I am very bullish on constraints based programming like this.
The main problem is code organization and syntax. Tacking stuff like this onto fuction declarations is too basic.
Ideally, I think we need better constructs, e.g. dettached constraints like to the function declaration. You can define constraints separately, in the same namespace or w/e, add notes, comments, etc. and the function declaration can be used with intellisense to jump to the constraint. You could even tag the defintions.
In modern AI-based workflows, the agent can pull up an explanation on the function, and point directly to the constraints, with strong confidence esp. if it's got explicit metadata.
Take a look at Racket (or Rhombus if allergic to parens). Support for contracts there is stellar and provides everything you mentioned. You can use `define/contract` for inline contracts, or you can attach contracts when exporting names from a module using `contract-out` declaration. Contracts are first-class, can be defined separately and attached wherever you want (importantly, this includes values (structs, classes) as well as functions). There are higher-order contracts that generate new contracts from existing ones. There's support for both static and dynamic metadata for almost all kinds of entities in code (ie. both the syntax and the semantic entity it produces can be annotated with anything). I wouldn't recommend using Racket/Rhombus in production, but it's a great preview of what might become commonplace in a decade or two :)
I've spent years avoiding lisp, I am not about to break that streak now.
All jokes aside, I genuinely think that non-algol syntax is a non-starter. We're too far along now, that it's easier for these features to come to java/rust/typescript/cpp than it is to switch completely to academic langs that have terrible tooling support.
The tooling around S-expression syntaxes is almost necessarily better than others because it's so straightforward, eg, structure-based editing operations. The "problem" with IDE integration for such languages is generally the (lack of) availability of static information, especially due to Racket's expressive arbitrarily-many-phased macro system, but that's a separate axis of language design.
That said, the parent comment explicitly pointed out Rhombus as an alternative to an S-expression syntax within that same community, so maybe you could look into that suggestion instead of being pithy about topics in which you are less well informed.
I suspect the GP might not like Rhombus because it uses indentation (like Python) for code blocks instead of braces (which isn't actually Algol-like; IIRC, Algol mostly used parentheses). In that case, even Pyret wouldn't work for them.
Personally, I'm still (25 years into programming) undecided: does syntax not matter at all, matter only a bit, or is one of a language's most important characteristics? It's incredibly hard to say, at least for me.
The main problem is code organization and syntax. Tacking stuff like this onto fuction declarations is too basic.
Ideally, I think we need better constructs, e.g. dettached constraints like to the function declaration. You can define constraints separately, in the same namespace or w/e, add notes, comments, etc. and the function declaration can be used with intellisense to jump to the constraint. You could even tag the defintions.
In modern AI-based workflows, the agent can pull up an explanation on the function, and point directly to the constraints, with strong confidence esp. if it's got explicit metadata.