[ANN] Async/await is coming to ReScript!

I just finished the implementation of Async/await syntax here: https://github.com/rescript-lang/syntax/pull/600

let greetUser = async (userId) => {
  let name = await getUserName(userId)  
  "Hello " ++ name ++ "!"
}

The future is here.

21 Likes

Or rather the promise is awaiting

10 Likes

It’s times like this when I wish discourse had emoji reactions :joy:

Looking forward to trying this out! It’s a massive pain point for developers coming from modern browser development where promises are so common.

1 Like

Absolutely fantastic job @cristianoc and @Maxim :clap:t4::clap:t4::clap:t4::clap:t4: – can’t wait to try it out!

2 Likes

Wonderful! :clap: Thank you for your work @zth and @cristianoc :bowing_man:

1 Like

I cant wait! this is the only reason i didnt dive face first into rescript

2 Likes

Exciting announcement and thank you for your work!
Can’t wait to try it.

2 Likes

Update: both syntax and compiler support has been merged. Won’t make it into V10, which is just around the corner, but into the release after V10.

17 Likes

That will be V10.1 which is a big-ish step w.r.t. 10.0 in terms of functionality, but a relatively small step in terms of risk as features are already relatively well tested in there, so the 10.1 release could follow e.g. 2 or 3 months after 10.0 if no surprising issues are discovered.

13 Likes

The split between 10.0 an 10.1 is mostly about risk management, where the former contains mostly the fixes and the latter mostly the novelties, in the past year or so.

17 Likes

breathing heavy I’m so excited

1 Like

Is there any pre-release where I can start using it right now?

Yes, it has been merged into main branch. You can download and compile or get packages from github actions.

The github actions is the easiest way to go. Pick your commit, download the npm_packages.zip, unzip, and then you can install ReScript by using the path to the package.

npm install \path\to\package\rescript-10.1.0-whatever.tgz

:exclamation:I think the maintainers would be sad if I didn’t warn you that you are treading on potentially dangerous territory. So, keep in mind that this has not been approved for production.

Let me know if you have issues :slightly_smiling_face:

8 Likes

Thank you - it’s working great. So much nicer to have async/await than having to deal with endless nested and/or chained promises.

5 Likes

Dropping in to express my absolute disapproval of async/await because of the many footguns it arms the user with, these are well documented so I won’t go into them.

However, if we are to have async/await, I can get behind this form - one that completely matches JS and ReScript.

How does this interact with blocks? Does the following code work as expected?

let fetchUserName = async (id) => {
  let user = await {
    let res = await fetch(`/users/${id}`)
    res->json()
  }

  user["name"]
}

How about something like this, where the block itself isn’t being awaited but exists in an async context

let foo = async () => {
  let p = {
    let x = await asyncInt()
    x + 1
  }

  await p
}

The semantics with blocks do not seem clear to me with async/await.

6 Likes

Ok, so now I’ve been suing async/await with ReScript for a while.

I don’t enjoy async/await nearly as much as I do in JS. It just doesn’t quite sit right with me. I think it’s all the implicit Promise.t wrapping that becomes very exposed and apparent, as opposed to JS where it just goes unnoticed. I think this works mostly fine in JS, but I understand it’s not appropriate for ReScript. I find myself switching back and forth between explicitly using Promise.t’s and async/await.

Async/await is probably necessary for marketing
In our codebase, we plan to continue using rescript-future. Async/await does not interest us.

But, there is one place where it will really help us a lot: writing tests (in rescript) with @testing-library/react and the use of waitFor. The addition of async/await will be great for this part.

3 Likes

Totally agree. I’m not going to use async/await myself, but seeing how the feature is requested by newcomers, it might noticeably increase ReScript adoption. It’s bad that there are multiple ways of doing the same thing, but at least it’s possible to control with eslint.

It’s easier in JS because a lot of things are easier in JS, the under-the-hood conversions supporting a range of return types for async functions papers over a lot of weird code patterns.

I believe the goal of this syntax is to improve the current situation where we need to use Promise.t manually, not make it as easy to use as JS. I’m fully supportive of it (even if I wish it were possible to use it for types other than Promise).

2 Likes

How does rescript-future compare to @ryyppy’s promises? Why would one pick one or the other?