Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

91–100 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#91

Callbacks are basically COME FROM, epecially on a platform like a cell phone where you at least in theory have limited processing resources ($40 android phones need apps, too!). They are the devil.

> Callbacks are basically COME FROM No, they aren't even similar to COME FROM. COME FROM is "upon reaching label X, jump to this point". Callbacks have less in common with COME FROM than with GOTO, and less in common with GOTO than with normal procedure/function invocation. > epecially on a platform like a cell phone where you at least in theory have limited processing resources Platform is completely orthogonal to t…

I see your point, but they read a lot like come from when looking at code.

And platform is not orthogonal: sometimes I need to know exactly what is using how many cpu cycles, and callbacks make it hard.

Admittedly I mostly do embedded dev, but there's a reason why I have the only remote control / video app out there that still works on a HT G1 :)

Re: Callbacks as our Generation's Goto Statement

#92
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?

  ci := make(chan int)
  go func(ci)
  

Re: Callbacks as our Generation's Goto Statement

#93
Why do people insist on analysing things using analogies? Analogies are useful for explaining a concept that might not be obvious. Saying callbacks are like gotos, gotos are bad, therefore callbacks are bad is ridiculous.

And he gives some sample code where the 'problem' is nothing to do with callbacks, its just nested lambdas. In fact I find that code quite easy to read, and would be very interested in seeing the same functionality implemented some other way, bearing in mind it is quite a difficult problem to synchronize multiple async operations and usually requires horrible code using multiple mutex.

Re: Callbacks as our Generation's Goto Statement

#94
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?

I think that WaitGroups or possibly just reading from a semaphore channel might do the trick for you in go.

Re: Callbacks as our Generation's Goto Statement

#95
post #48

Earlier quoted context omitted.

Let's not forget that "if", "for", "while", "switch", and friends, fundamentally, aren't anything more than syntactic sugar for "goto" either. ;)

Very true. :) The genius about them, however, is that with all those, we discovered that you could get rid of "goto" afterwards. Which was kind of amazing. "Await", on the other hand, doesn't remove the need for callbacks -- it just makes it much easier to use them in a lot of common use cases, in a much clearer way. But there are still plenty of valid/necessary uses for callbacks that can't be handled by "await".

On the contrary, there are still perfectly good uses for goto. The two I can name right off the top of my head are stack-like error unwinding in C (which comes with an endorsement from CERT recommending its use) and computed goto dispatch tables in threaded interpreters.

Still, you're right that structured control flow statements have obsoleted goto for all but the tiniest edge cases, and so too do I look forward to callbacks suffering a similar fate at the hands of things like await.

Re: Callbacks as our Generation's Goto Statement

#96
post #67

Earlier quoted context omitted.

Maybe like this? players.forEach(function() { 'use strict'; var player = this; var name = Ask("What's your name?, function(name) { if (isValidName(name) { player.name = name; } }); });

Same problem like with the sibling post: this will ask two players simultaneously. My example waits for each player to provide a valid name in turn.

If you're doing everything sequentially anyway, why bother with the awaiting part? As far as I can see your example would be functionally unchanged if you wrote the same code except without the await keyword.

Re: Callbacks as our Generation's Goto Statement

#97
post #64

Earlier quoted context omitted.

for player in players get_name_for = (player) -> ask "what's your name?", (response) -> if is_valid_name response player.name = response else get_name_for player get_name_for player

This looks like it does the wrong thing. If "ask" gets to access the scheduler's task list as a queue, then entering an invalid name in the first response and only valid names thereafter will cause the first valid name to be given to the second player, the second valid name to the third player, and so on. If "ask" gets to access the scheduler's task list as a stack, then a sequence of only valid input names will caus…

Hmm, I wrote it so that the function closes over the player, so that shouldn't happen. The real issue is, as pointed out, that this will ask for all the names at once, rather than sequentially. Wether this is bad or not depends on how the `ask` function gets its input.

Re: Callbacks as our Generation's Goto Statement

#98

I noticed that most of the methods awaited on had an Async suffix in their name. Is that some sort of modern hungarian notation, and is it even necessary? It also looks like you can't pass timeouts to await.

The Async suffix is here to differentiate with the synchronous version of an existing method returning T, the asynchronous return a Task. With a Task you can do :

  int timeout = 1000;
  var task = SomeOperationAsync();
  if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
      // task completed within timeout
  } else { 
      // timeout logic
  }

Re: Callbacks as our Generation's Goto Statement

#99

This is what continuations are for.

Given that your handle has "racket" in it, I'll assume that you're a call/cc kinda guy.

Even if you're not, others may enjoy this argument against call/cc by Oleg:

http://okmij.org/ftp/continuations/against-callcc.html

Delimited continuations are a huge improvement over undelimited ones, but still, by themselves, any kind of continuations feel like (to me) the GOTOs of functional programming.

More recently, people are doing work with "effect handlers". See Eff & it's research papers, for example:

http://math.andrej.com/eff/

This model is safer, faster, easier, and more composable than general purpose undelimited continuations.

Re: Callbacks as our Generation's Goto Statement

#100
post #7

"I have just delegated the bookkeeping to the compiler." That's not obviously a good thing. Debugging the compiler (or just figuring out why it did something, even if correct) is far more difficult than debugging application code. Given the choice between implementing behavior with application code (or a library function) or adding semantics to the language, I prefer the former because it's much easier to reason abou…

While that can be true, I feel like the author inadvertently overstated the amount of work that the compiler is doing here. This is really more of a case of syntactic sugar and not heavy-duty code reordering.
Post reply on HN