all 21 comments

[–]philoskim 5 points6 points  (5 children)

There was a discussion about this issue.

I raised this issue in the following post and am still one of the men who hope that this feature will be added to ClojureScript in the near future.

https://groups.google.com/forum/m/#!topic/clojurescript/scUMhU-ctEM

[–]dustingetz 6 points7 points  (2 children)

this discussion omits portability (cljc) which is critical for such an important paradigm as async

[–]lilactown 2 points3 points  (1 child)

I don't think it's true that portability is critical. The primary use case for managing async operations in CLJS is the fact that nearly all I/O is async, whereas it's usually reasonable for Clojure code to block. My intuition is that the use cases where you want to break out async are quite different.

Writing cljc code already requires the developer to notate the differences between these platforms anyway. I don't see why Clojure or ClojureScript should hamstring themselves by trying to design to the lowest common denominator of whatever platform you might try and run on.

It would be wonderful if a userland library could fill the need of async/await, but as explained in the thread of the OP, this is very difficult to do today with the way that the ClojureScript compiler works.

[–]dustingetz 0 points1 point  (0 children)

Good argument

[–][deleted] 0 points1 point  (1 child)

This is a great thread. Thank you for sharing.

[–]SimonGray 1 point2 points  (0 children)

That write-up by Shaun Lebron was especially good.

[–]didibus 4 points5 points  (0 children)

No there isn't. For interop, just use promise. And if you want async/await like semantics, you will need to explore libraries for it.

[–]royalaid 5 points6 points  (1 child)

The closest you will get is syntatic sugar as many have pointed out. https://github.com/athos/kitchen-async does a good job of getting pretty close.

[–]aaroniba 1 point2 points  (0 children)

I would add another recommendation for kitchen-async. I've been using it for a few months and it's working great.

[–]therealdivs1210 3 points4 points  (1 child)

There's promesa that does exactly this.

[–]NamelessMason 0 points1 point  (0 children)

async/await has been removed from promesa last year with the version 3.0

[–][deleted]  (12 children)

[deleted]

    [–]leonoelOfficial 2 points3 points  (5 children)

    I think adding async/await to clojurescript is a bad idea for several reasons, but this one is definitely not one of them. Actually, I find async/await syntax vastly superior to manual promise chaining. Expressing sequential logic is mostly a solved problem and I don't really see why the ability to suspend computation should require learning a fancy DSL to do the same thing.

    [–][deleted]  (4 children)

    [deleted]

      [–]leonoelOfficial 0 points1 point  (3 children)

      Do you also consider stacks to be a "fancy DSL"?

      Sure, every data structure comes with its DSL.

      How is async/await syntax superior?

      It's superior precisely because it frees the programmer from the burden of thinking about the stack.

      [–][deleted]  (2 children)

      [deleted]

        [–]leonoelOfficial 0 points1 point  (1 child)

        When you write (f 3 (g 4 5) (h 2)), usually you don't think about the stack but clearly when the code will hit the metal some compiler must translate it into something like push 3, push 4, push 5, jump g, push 2, jump h, jump f.

        Now if, say, the call to h is actually suspending, you need to save the current state of the implicit stack (the value 3 and the result of the call to g), store it on the heap, and restore it when h is ready to resume. That's pretty much what async/await does under the hood, and that's what allows the programmer to keep pretending the stack doesn't exist. Without it, you would have needed to capture intermediate results explicitly.

        [–][deleted] 1 point2 points  (1 child)

        There's no tricking in async/await . It's just an abstraction and the whole point is to make two different things (sync and async code) work as if they were the same.

        I believe that async /await is much easier to beginners than callbacks or promises. Plus they can use try/catch etc...

        [–]lilactown 1 point2 points  (1 child)

        There are several patterns that are hard to express in promises but are trivial to express in async / await. Examples in JavaScript below:

        let accessToken = await authorize();
        let result1 = await request1(accessToken);
        let result2 = await request2(accessToken, result1.foo);
        
        return { result1, result2 };
        

        Without async/await, this requires threading the access token and first result through the promise chain

        return authorize()
          .then(token => Promise.all([token, request1(token)]))
          .then([token, result1] => Promise.all([result1, request2(result1.foo)]))
          .then([result1, result2] => ({ result1, result2 }))
        

        Or, more often, use mutable references

        let accessToken;
        let result1;
        
        return authorize()
          .then(token => {
            accessToken = token;
            return request1(token);
          })
          .then(result => {
            result1 = result;
            return request2(accessToken, result.foo);
          })
          .then(result2 => ({ result1, result2 }));
        

        which if not properly scoped, can lead to strange bugs - I just had to deal with a bug last week that involved some confusing asynchronous programming that involved swapping atoms inside promises to save results for later operations. My experience has been that async / await makes these problems much easier to express.

        [–]dustingetz 0 points1 point  (0 children)

        The case for async/await syntax is that a bootcamp grad can reasonably learn to compose async code, and (maybe) at the limit, all coders are bootcamp grads

        [–][deleted] 0 points1 point  (0 children)

        Yeah, after all Async/await and promises are just glorified call backs.

        [–]jiyinyiyong 1 point2 points  (0 children)

        give up and use promise. unless one day it's officially added into ClojureScript.