0

I've been thin lately about async/await lately and its case is similar to references. In javascript there're no pointers, derefecence operators etc. that exist in low-level languages which makes javascript look simpler because it pretends that a variable stores a value for an object while in truth it stores reference to an object and magically resolves it to the object when it notices you actually want to get the data. So it looks as if the variable stored the object itself.

Pretty same situation can be observed with promises: when you have a promise stored in some variable, you actually don't care about the promise itself - you care about its value.

AFAIK there are no pointers in javascript because they were confusing and could be abstracted away so they were. Same goes for promises.

Instead of doing

const data = await fetch("endpoint");

you could be doing

const data = fetch("endpoint");

because javascript would figure out that what you want is the data returned by the fetch. Promises and async/await actually might become language's internal implementation detail.

  1. Will it be possible (meaning can it be implemented in javascript)?
  2. Is there a language that already does this?
  3. Would you want this to land in javasrcipt?
marzelin
  • 10,790
  • 2
  • 30
  • 49
  • @JaromandaX if this is confusing to you, take a look at Go. "await" is implicit everywhere, and if you want to 'opt out' of waiting, you call the function with the 'go' prefix. This is a much saner model than javascript's. – Evert Sep 04 '18 at 09:59
  • @JaromandaX same goes for references and pointers but they are not present in javascript you can do without them – marzelin Sep 04 '18 at 09:59
  • `what you want is the data returned by the fetch` - this is not always true. You may want to store a reference to `promise`, for example in order to understand weither your request is the last one for example, and you want to discard results of previous requests. – Egor Stambakio Sep 04 '18 at 09:59
  • @JaromandaX, what I'm responding to is "why would you want to take that choice away". My point is that there's other languages that explicitly await and still have that choice. – Evert Sep 04 '18 at 10:02
  • @JaromandaX I'm saying that there are no pointers in javascript because, i think, they were confusing to people and could be abstracted away so they were. Same goes for promises. – marzelin Sep 04 '18 at 10:04
  • @JaromandaX well what is happening now is this road to make javascript to look synchronous while keeping it async behind the scenes. First promises then async/await. I think there might be another step, no? – marzelin Sep 04 '18 at 10:17
  • @JaromandaX yes javascript never had pointers, what I meant is programming languages had pointers (and low-level still have) but high level does not. – marzelin Sep 04 '18 at 10:19
  • @JaromandaX so why promise and async/await was added? We can do everything with callbacks. – marzelin Sep 04 '18 at 10:22
  • @JaromandaX yes, you still have to understand how async works is js to write quality code, but same goes for references. Not understanding references is a common cause of bugs in newbe code. – marzelin Sep 04 '18 at 10:29
  • @JaromandaX I'm not advocating for making asyn/await transparent. That's just an open question. I know it is virtually impossible now to implement this in javascript because js must be backward compatible (living standard). I want is it possible from the implementation perspective. Can it be implemented in js? – marzelin Sep 04 '18 at 10:34
  • 3: Absolutely not. [It's a horrible idea](https://stackoverflow.com/a/25447289/1048572). – Bergi Sep 04 '18 at 12:30
  • How would you allow doing things concurrently if everything is automatically awaited? – Bergi Sep 04 '18 at 12:32
  • @Bergi Good point. Well, maybe introduce a keyword `go` that will run the code concurrently ;) The golang looks more and more compelling to me. `go` seems like inverted `await`. I wonder if it is better that way. – marzelin Sep 04 '18 at 12:52

1 Answers1

1

It's extremely unlikely that javascript would support this pattern. It's current approach to async code is so deep, that having 'explicit await' everywhere would really make javascript no longer javascript. I do think it might be possible to come up with a language that compiles down to javascript.

If you're looking for a language that does do this, take a look at Go. It's a much saner model for asynchronous programming because it was considered from the start. In javascript, promises and async/await were tacked on much later.

9 times out of 10 you will want to 'await' a asynchronous function, so in go every function is 'awaited'. If you don't want to 'await' a function, you call the function like this:

go foo()

So comparing Go and Javascript, the go and await keywords are very similar, but used for opposite cases.

In go, the async keyword in front of functions is also not needed.

Evert
  • 93,428
  • 18
  • 118
  • 189
  • @Bergi you're right, but I think that's somewhat unrelated to the question. – Evert Sep 04 '18 at 14:33
  • I'd just like to challenge "*It's a much saner model for asynchronous programming*" :-) JS has run-to-completion semantics and was designed thread-safe from the start. Doing something asynchronously must be explicit, as it allows for concurrency. – Bergi Sep 04 '18 at 14:40
  • Makes sense @Bergi. Maybe it would be better phrased as: 'The Go style of dealing with async/await functions may have been a better fit for javascript'. – Evert Sep 04 '18 at 14:43
  • Maybe, but really I think that its concurrency model is a cornerstone of the popularity and success of JavaScript. – Bergi Sep 04 '18 at 14:50
  • The concurrency model (to me) feels like an afterthought. This is pretty subjective ofc. I definitely think that the javascript concurrency model + "await by default" is definitely a feasible language, it (AFAIK) just doesn't exist yet. – Evert Sep 04 '18 at 14:52
  • The problem with that language would be that it implicitly becomes thread-unsafe: you call a function, and you never know whether it waits and allows for arbitrary other code to run. You either would have to invent a way of "trusting" functions, or you could drop the run-to-completion concurrency model altogether. – Bergi Sep 04 '18 at 15:04
  • This is becoming pretty hypothetical, but really all I'm suggesting to treat instances of `foo()` as `await foo()`, and `go foo() `as `foo()`. It would be just as predictable. – Evert Sep 04 '18 at 15:10
  • Ah, ok, but that would mean that I also had to write `go foo()` for every single invocation of a *synchronous* function (that I don't want to `await`). And while your estimate of 90% of asynchronous functions to be called with `await` sounds reasonable, so does that 90% of all function calls are synchronous. – Bergi Sep 04 '18 at 15:16
  • You're right, I would want the await `await synchronous()` to be optimized away. Does something like `await 5;` stop execution of the event loop? – Evert Sep 04 '18 at 15:28
  • Ah interesting. Maybe this would be more than a simpler transpiler then – Evert Sep 04 '18 at 15:35
  • But the real problem isn't that this optimisation isn't possible - it's the countless threadsafety bugs that would happen when you expect an (optimised) synchronous call but get a (waiting) asynchronous call, and just because of an easily forgotten `go`. – Bergi Sep 04 '18 at 15:55