(But it's possible that even less people ever wrote Eiffel than D, so, who knows)
It's very confusing name for this feature. It suggest that some sort of borrowing takes place and that it's just an optional check, which isn't the case. It should be named something like "enforced static usage analysis" instead.
In my programming language I have similar mechanism. But it isn't just checking, since it affects code generation by tracking which variables are still in use and which can be destroyed.
out (; balance == balance + amount) // checked after method returns
How exactly does it work? Is this a typo?The correct way to go about this would be to return the new balance and capture the return value in the first part of the out postcondition like:
```D double deposit(double amount) in (amount > 0, "Deposit amount must be positive") out (result; result == balance) { balance += amount; return balance; } ```
My mistake!
> LLMs will make it easier to prototype new concepts,
So where are these prototypes?
Refinement types can be used as compile time checks for preconditions and postconditions, while this contract programming is inserting runtime checks.
Here's a good post on the type state pattern in Rust (we don't actually have refinement types in something like Rust but the type state pattern is somewhere closer to refinement types on this spectrum): https://cliffle.com/blog/rust-typestate/
In advanced cases, you'd need dependent types, but the only place where that almost shows up is in the "amount <= balance" assertions. That's also silly because if you typed "amount" and "balance" correctly, then "balance -= amount" has to produce a runtime error because the resulting balance would be negative and not a valid value for the type. So, it's a very natural place anyway to force the programmer to properly handle errors anyways.
"Contracts" has been around a long time and has not caught on. That's usually a good sign that better approaches are prevailing.
In other words: refinement types are a better solution.
Contracts are an attempt to include formal specification languages into the implementation languages. You can enforce valid and invalid state changes, enforce relationships across the program state, or even enforce some level of correctness in behaviour.
> around a long time and has not caught on. That's usually a good sign that better approaches are prevailing.
That is completely not true. Plenty of dumb things prevail for faar too long for no other reason than momentum. Plenty of great things remain academic forever. It has decades to get algebraic types or basic functional programming to get somewhat accepted.
Design by contract is in theory a good idea but suffers from being a pain to use effectively. (making actually useful invariants that help the program more than an assert already would have)
I'd love to see a language whose pitch is that they have very next level stdlibs builtin. Effect for example is basically a mini stdlibs unto itself. It would be amazing to see such a principled deliberate craft applied to a language. Scope, layers etc etc etc etc: make visible, make first-class the actual pieces of computing, make them part of the language, explicitly modelled.
I'm also super excited for Zena, which just got announced yesterday! A typescript alike that compiles to wasm, and which really leans in to modern wasm, such as gc, wasi. A language that sits well at the cross-roads, that is excellent glue, that runs anywhere, that bridges other languages, is very compelling.