Rust wiring in syntax for this (which is what ?-notation is, it’s special-case do-notation) is both a blessing and a curse: it’s extremely useful today and a breath of fresh air relative to C++ or Java or whatever but this scenario has been seen before: GHC had do-notation and return, which are dramatically more flexible than ?-notation, wired in pretty deep when people started realizing that you want Functor => Applicative => Monad with pure === return and ApplicativeDo. They’re still trying to get the migration done today and they started years and years ago.
Time will tell how Rust will age as it inevitably continues adding algebraic power, but superficially ?-notation seems doomed to end up a kind of dangling appendage that will be obsoleted by some more general notation for algebraic effects.
When you say "They’re still trying to get the migration done today... " you mean Rust's core developers, right? Is there anywhere I can read up on it?
I remember when I was working on `Haxl` at FB in like, 2015 or 2016, it needed `ApplicativeDo` and that was like, quite the novelty in industrial Haskell (I think it was already a no-brainer to the research/OSS/etc. crowd). So mainstreaming `Applicative` into the effects hierarchy has been going on for 6 or 7 years that I know about, and I bet a lot longer than that (the paper introducing `Applicative` is from 2008: https://www.staff.city.ac.uk/~ross/papers/Applicative.html).
There's an (admittedly oversimplified) sales deck for algebraic effects that I have found really effective at selling this stuff to open-minded non-FP hackers: https://philipnilsson.github.io/Badness10k/posts/2017-05-07-....
At the risk of inviting an old-fashioned HN brigade gang-tackle: I think it indirectly illustrates why Rust is going to end up going all-in and ditching the ?-notation. Please don't hurt me.
- exceptions don't appear in the signature of a function
- you don't have to handle exceptions explicitly, while you cannot access the value of a Result without explicit error handling
- Exceptions are implemented like Rust's panic. The error path in exception is more costly, while the nominal path is supposedly less so, due to less register and branch pressure than the result type that at least has a discriminant to check.
Exceptions are such a different way or handling errors from Result that my team finds itself reimplementing Result types in C++ again and again. Alas, it is neither standard nor ergonomic in C++