upvote
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 :)
reply
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.

reply
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.

reply