Interested in ReScript until I read async/await docs

This feels like deal breaker to me. Is there any work being done to address this?

The usual recommendation is to just try it out and see how it works in practice. Usually it works really well especially because of ReScript’s excellent type inference and fast compilation. My half-joke recommendation: alias the Promise.resolve and Promise#then functions to get ‘poor man’s async/await’:

let async = Js.Promise.resolve
let await = (p, f) => Js.Promise.then_(f, p)

prom->await(res => {
  Js.log(res)
  async(res)
})
3 Likes

I dont agree.
What is it about async await that you need?

So I have never used ReScript before, but am a long time Javascript developer. ReScript looks great as I’m reading the docs, then I stumble on this page.

so what I’m getting here, again as a newbie is

" There is currently no support for async and await keywords in ReScript"

so I’m thinking “no syntactic sugar for this, like in JS, so it’s promise chaining, or callback hell”, This page doesn’t give any examples, it just links to https://github.com/ryyppy/rescript-promise#usage which lets be honest looks super ugly, So again, as someone just interested, I’m still not understanding how ReScript makes async code easier or cleaner compared to js/typescript async/await

please explain.

1 Like

What you see is what you get, the standard way to deal with promises in ReScript is with the provided functions. Yes, it doesn’t look as nice as async/await syntax sugar–but it gets the job done, and syntax sugars have their downsides as well. ReScript focus is on providing a fast compiler with a strong static type system and good-looking JS output. People who use it are primarily interested in that.

Unless we have let binds of sorts, I still get nested promises. That or I extract each promise handler into a named function so at least the promise chain becomes easier to read.

3 Likes

It doesn’t IMO, not always. For example when you want to call await in a loop it gets very tricky. And exceptions handling is much easier to work with with async/await sometimes:

try {
  for (...) {
    await something()
  }
} catch (e) {
  ...
}

BTW, generator functions support would get us most of the way there too probably. And in some cases would be even better than async/await because it can work with other monads.

@chadams

I just use RxJs (even in JS). I just don’t like promises, and I advice to use a real library for asynchronous workflow. And since that library is more than 13 years old (an old man in web world), and still actively use and develop, I can only advocate for it :slightly_smiling_face:

It also seemed critical for me, but it happened that I don’t have any problems with using promises.
What I really miss is generators support.

Just to be clear, I’m not being critical of ReScript, but rather of the documentation for that page. As someone coming from TypeScript, It really made me question if I wanted to invest time learning this.

Good point. The async/await syntax sugar does take care of managing the stack when you’re looping.

1 Like

I love Rescript, but I,too, have to admit my interest has gone “on hold” until async/await is implemented.

2 Likes

Not sure async wait is a huge blocker. The other aspects of the language are too good to skip. I am biased to rescript.

The following stack has proved to work already in 4 projects now

  1. Rescript
  2. React query
  3. React table

I had to write the bindings for react query and react table but having compiler next to you telling where you make a mistake is just too good dev experience to forgo. Again I am biased towards Rescript.

Perhaps your usecase it too heavy api driven with deep nested promises.

2 Likes

I’m not going to persuade you or anything, but a sugar syntax doesn’t really sound like a blocker. I wish rescript team will spend time on something more useful than async/await.

2 Likes

There’s another wrinkle with async code in ReScript, when using Js.Promise, you have to return a promise from .then() which makes using promises in ReScript more complicated than in JavaScript. The reason for this is that ReScript uses OCaml’s type checker under the hood and it doesn’t support conditional types.

I use thenResolve from https://github.com/ryyppy/rescript-promise

2 Likes

I come from Typescript and Flow, and with daily use of ReScript by my team today, we don’t feel a real lack of async/await.

With the rescript-future library, we have some useful methods like Future.all and Future.flatMap. With this everything is working for us!

(we also use GraphQL a lot which makes us forget this lack)

I’m not going to persuade you or anything, but a sugar syntax doesn’t really sound like a blocker. I wish rescript team will spend time on something more useful than async/await.

Totally agree with @DZakh

7 Likes

I like the idea of some sort of syntactic sugar for async operations, but in the meantime want to give another vote for the aforementioned rescript-future.

  let search = React.useCallback1(query => {
    Photo.search(query)
    ->Future.tapOk(photos => setState(_ => Loaded(photos))
    ->Future.tapError(error => setState(_ => Failed(error))
    ->ignore
  }, [setState])

I just have lots of helper functions that I can pipeline requests / responses through to transform them into either a success with a properly parsed response, or some sort of parsed failure. The trickiest part for me has been wrapping my head around the types when mapping/flat mapping multiple promises together.

5 Likes

My conclusion is that there are great options the community has come up with to make async workflows easier. We just need to share more examples on the docs page, instead of having 1 trivial example with the native Fetch module.

For those coming from async/await, the use of pipes and promises probably don’t feel as natural anymore.

2 Likes

If youre arguing to familiarity how will a new language ever work for you?

1 Like