Is there an async/await, bs-let, let_ppx official solution?

Are you asking why we were undecided on the general idea of monadic-let transformations?

If so, I will just dump my (of course highly subjective) perspective on this whole thing.

So my personal nitpick on the latest “stage-0” proposal (the one where Bob essentially proposed a somewhat specialized version of bs-let) was the fact that it felt like a bolted-on solution for a very visible, and very high-impact addition to the language that was just asking to be abused. The proposal document itself was already hard to understand, and from a design perspective, the feature was not specifically locked to promises even though it was only supposed to be used with promises (and node callbacks). For a few folks (espcially those churn resistent OCaml users) it was a “good enough” solution, but from a language ecosystem perspective it was a risky addition.

My fear was also backed by some anecdotical data: The new editor support was forked from the original RLS codebase, which was full of monadic let usages for all kinds of data structures. This particular syntax turned out to be a pretty big source for swallowed errors, causing a lot of annoying hard to find bugs that directly translated into unhappy IDE users (I hope we all agree that the old vscode extension aged badly over time). The stability of the code improved greatly as soon as Cheng / Christiano got rid of all the hard to understand let%xyz to make uncovered error cases more explicit and hard crashes less likely. This particular scenario seriously scared me; just thinking about how many ppl could have used that feature without noticing critical bugs, and how much impact that would have on the general quality of the ecosystem.

Of course this is only one data point, and I can’t wait to hear all the counter arguments on “how we did things wrong”, “how it’s not that bad” or “how I don’t understand the topic / let% syntax”. If experienced users have such a hard time making it behave correctly (including the creator of RLS / bs-let himself), then that’s an indicator that there is something wrong with the design. From a product management perspective, I’d rather postpone and re-evaluate the async / await situation in a later point in time instead of adding a somewhat working feature that needs to be maintained forever.

Previously I thought Bob / Cheng had some ideas regarding a coroutine like runtime library, and proper syntactic support along with it, but unfortunately this was apparently a misunderstanding and was never supposed to happen. This kinda took me by surprise as well, so all I can say is let’s wait it out and see what will happen in the future.

The async / await syntax is also not the only feature we had to put on hold for later. We once had a great proposal for a cleaner external syntax, which Maxim put a ton of time into (it was an incredibly well specified proposal + implementation). Even though it was solid, It didn’t make it because there was no proper consent. I am fine with it though, because I know that there is thought and discussion put into changes to the language, and we can still pick it up later when there is time to improve it.

As a last remark I also wanted to say that in my professional time, I am a ReScript user myself, so all this decisions being made impact me as much as anyone else here. I’d hate to see the language being bloated with things that seem like a good idea today, but then bite us years later (we had enough of those features in the past, and now we are struggling getting rid of them).

9 Likes

My only 2 cents on that is rescript has already achieved such a level of maturity, efficiency and feature completeness (including for DX) that the lack of support for async await is quite visible as being the last thing lacking, I can’t see any feature more important than this now for the ecosystem, so I really hope that this failed try (and that’s OK, we also want robust and elegant solutions and those are unlikely to be found at first) won’t focus the team away from this issue.

9 Likes

Yes, that’s the type of clarification I was after, thanks.

So, the basic idea is that it can “swallow” errors in a less obvious way than for example manually using a catch all with an ignore in a switch, and that’s dangerous enough in itself that you don’t want to support it. Have I understood it correctly?

Has there been talk of adding algebraic effects to the language to support async/await?

I’m sure there are many technical challenges to actually doing it, but does it fit within the design goals of the language?

I’ve spun this out into a separate topic: Algebraic effects

2 Likes

Apropos: Beware of Async/Await | Brandon's Website :

the easiest and clearest way to write something with async/await is, more often than not, wrong. And wrong in a subtle way that may never be noticed, because it only affects performance, not correctness.

2 Likes

optional syntax sugar is more welcome

currently the Optional.map is the most code snippet occur in my codebase and it’s biggest issue for promotion rescript to my team