Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

101–110 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#101
post #74

Does Await convert those async calls back into synchronous calls, or what does it do? Because that would be kind of defeating the purpose of doing things asynchronously? And you don't have to nest all those callbacks and write them inline. Rearrange your code a bit.

No, it rewrites the method code into a state machine[1]. See Async/Await FAQ[2]. [1]: http://stackoverflow.com/a/4047607/458193 [2]: http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-awa...

I'll have to look at that in the morning, thanks!

Re: Callbacks as our Generation's Goto Statement

#102
post #27

The ease with which callbacks can be created leads people to create them carelessly and excessively. While I like what the article has to say, there are ways to write callback heavy code that do not get ugly so fast. Looking at the iOS nested block example from Marco Arment -- the first step is to not do everything inline. Then the code suddenly becomes clear and the argument becomes one of syntax sugar. Comparing ca…

First: code that performs simple sequential steps should look simple. With callbacks, it always ends up looking complicated. Second: refactorability in callback oriented code is a lot worse than linear code. Even refactoring code with a single callback can be annoying. Async code with callbacks that looks and feels like imperative synchronous code is an enormous gain.

First: you're hammering the async point, which I don't disagree with. I am just pointing out that you can write less horrible async code than the example cited with callbacks.

Second: wait until people write ludicrous numbers of async routines as if they were imperative because it's so easy. Calling one from another (and hooking them up to event handlers). You'll have the same damn problem one level removed.

Re: Callbacks as our Generation's Goto Statement

#103
post #63

Yes a thousand million times. This is the reason why people love golang and why there's a lot of excitement about core.async in the Clojure community, particularly for ClojureScript where we can target the last 11 years of client web browser sans callback hell: http://swannodette.github.io/2013/07/12/communicating-sequen... Having spent some time with ClojureScript core.async I believe the CSP model actually has a le…

Yeah, C# await/async is cool. But isn't Google Go's approach nicer? Keep standard lib calls blocking as is, and use the "go" statement when you want to run something async? It avoids all the extra DoWhateverAsync() API functions. See http://stackoverflow.com/a/7480033/68707 What's the Go equivalent of "await"? I.e., like the "go" statement but asynchronously wait for the function to return and get its value?

The difference is that Go has what looks like preemptive scheduling for goroutines (and will eventually be truly preemptive; see [1]) while await is more like cooperative multitasking. If you're writing in Go, you should use channels (or mutexes) to avoid race conditions: "share by communicating".

With a single-threaded language using await, it's safer to modify common data structures without locks, although you should be aware that calling a function via "await" gives others task the opportunity to modify your data. So "await" appearing in the code explicitly warns you that pseudo-multitasking is happening. In Go, preemption can (in theory) happen at any time, plus there are multiple threads.

[1] http://honnef.co/posts/2013/08/what_s_happening_in_go_tip__2...

Edit: Go isn't truly preemptive in 1.1.

Re: Callbacks as our Generation's Goto Statement

#104
Anonymous callbacks are very powerful and very important. They will make you feel bad for unnecessary nesting. They will force you to learn how to abstract better, especially state changes. They will show you how nice and reliable code can be if it doesn't have shared states across multiple functions and how easy it is to understand consistent code with explicit continuations and how to write one yourself. They will make you a better programmer.

And "await" can only make it harder to visually distinguish which piece of code is executed in parallel and which is executed sequentially. Nesting makes it explicit.

Re: Callbacks as our Generation's Goto Statement

#105

"Await" is fantastic, and having using it for JavaScript (via TameJS and then IcedCoffeeScript), it makes things a lot easier and clearer. That being said, I don't think the comparison between callbacks and goto is valid. "Goto" allows you to create horrible spaghetti-code programs, and getting rid of it forces you to structure your programs better. "Await", fundamentally, isn't really anything more than syntactic su…

What this suggests is that "await" isn't like all structured programming, it's like one control construct. The history of structured programming is the development of more constructs as people realised that they had a goto pattern that kept popping up in their code, so they named it and thereby got a cognitively-higher-level program. Long after Dijkstra's essay, we could still occasionally find new places where goto was really the best way to do it: for instance, if you wanted to "break" out of multiple loops at once. So someone invented named break (likewise continue), and removed yet another use of the unconstrained goto in favour of a more constrained, structured construct.

Taking the OP's premise at face value, then, if callbacks are like goto, then await takes away one place where they were needed and replaces them with something more structured and safer---and this doesn't at all negate the possibility that there are other constructs yet to be invented that would continue that process.

Re: Callbacks as our Generation's Goto Statement

#106
Meh.

Callbacks are a very limited way to do asynchronous programming. However they are a good way to create interfaces that let you call methods and insert your own functionality in the middle.

So yes. Better async is good. But don't take away callbacks. They have their uses.

Re: Callbacks as our Generation's Goto Statement

#107
post #3

Holy Baader-Meinhof, just today, in frustration, I wrote something like Haskell's sequence_ for ContT, in Javascript: https://gist.github.com/cscheid/6241817

Why do you as an American feel the need to invoke some dead german left-wing militants in a pseudo-religious phrase that's meaningless except maybe for shock value? This seems highly inapproriate for any website and even more so on HN.

Re: Callbacks as our Generation's Goto Statement

#108
post #90

Earlier quoted context omitted.

How do you do this with callbacks? foreach (var player in players) { while (true) { var name = await Ask("What's your name"); if (IsValidName(name)) { player.name = name; break; } } } Assuming `Ask` is an asynchronous operation and must not block the UI thread. Note that second player is only asked after the first player has given a valid name. (And the code structure reflects that :-) My point is of course it's doab…

Coroutines (or generators) are a really nice sugar for callbacks. This looks a lot like ES6's yield, just s/await/yield/. But to answer your question, since these can't be done in parallel, you'd have to keep track of which player you're asking: var playersAsked = 0; var askNextPlayerHisName = function(done){ if (playersAsked === players.length) done(); Ask("What's your name?", function(name){ if (IsValidName(name)){…

Just hope that the players won't enter too much invalid names : http://stackoverflow.com/a/7828803/260556

Re: Callbacks as our Generation's Goto Statement

#109
post #108
post #90

Earlier quoted context omitted.

Coroutines (or generators) are a really nice sugar for callbacks. This looks a lot like ES6's yield, just s/await/yield/. But to answer your question, since these can't be done in parallel, you'd have to keep track of which player you're asking: var playersAsked = 0; var askNextPlayerHisName = function(done){ if (playersAsked === players.length) done(); Ask("What's your name?", function(name){ if (IsValidName(name)){…

Just hope that the players won't enter too much invalid names : http://stackoverflow.com/a/7828803/260556

Not quite in this case. I'm making an assumption that the Ask function provided by the parent is actually asynchronous.

Re: Callbacks as our Generation's Goto Statement

#110
Evan Czaplicki (author of Elm lang) made the identical argument (sometime?/years ago), with the same reference to Dijkstra's quote, but with another suggested solution, Functional Reactive Programming, on which his language is oriented:

http://elm-lang.org/learn/Escape-from-Callback-Hell.elm

Post reply on HN