Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

11–20 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#11
post #5

I agree, although I think callbacks are more like COME FROM than goto. You see a function being passed somewhere as a callback, and you know the block is going to execute at some point, but most of the time you have no idea what the codepath that calls you back looks like. There's nothing more frustrating than trying to debug why a callback isn't being called. Who calls it? How do I set a breakpoint somewhere to see…

Have you looked at the Erlang model? Each Erlang process (green thread) only gets the arguments initially passed in and whatever else it asks for from other running processes. The only shared state is long-running processes created for the purpose of explicitly sharing state.

Yep. The Actor model that Erlang uses is exactly what I was referring to being missing from green thread libraries for other languages (C#, python with greenlet or generators, js with generators)

Re: Callbacks as our Generation's Goto Statement

#12
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…

This is a nonsensical comment, and I voted it down. The same point can be made about any time languages got a level higher. This kind of rejection of powerful in favor of complex-but-familiar is precisely what Bret Vector warns against in the Future of Programming talk[1].

If anything, `await` makes debugging easier because you don't have to untangle callbacks and jump back and forth. You're not supposed to “debug the compiler” because, well, you know, there are test suites and everything.

Yes, this is something that takes getting used to. Just like `for` loops, functions, classes, futures, first class functions, actors and many other useful concepts and their implementations.

As for your edit, I still can't agree with you.

You're saying:

>I prefer the former because it's much easier to reason about code written in a simple language than to memorize the semantics of a complex language.

The point of `async` is making the semantics more obvious. Is it much easier to reason about Assembler than C? I say it's not. Would it be for somebody with years of experience in ASM and none in C? Yes it would.

I think it just comes down to that. Callbacks seem simpler to you not because they are simpler (try explaining them to someone just learning the language, and you'll see what I mean), but because you got used to them. Even so, error handling and explicit thread synchronization make maintaining callback-ridden code painful. I think setting `Busy` to `false` in `finally` block is a great example (in the blog post). You just can't do that with nested callbacks—they are not that expressive.

Async allows you to think in structure (`for`, `if`, `while`, etc) about time, that's why it's powerful.

[1]: http://vimeo.com/71278954

Re: Callbacks as our Generation's Goto Statement

#14
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 leg up on task based C# F# style async/await. We can do both Rx style event stream processing and async task coordination under the same conceptual framework.

Re: Callbacks as our Generation's Goto Statement

#16
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…

This is a nonsensical comment, and I voted it down. The same point can be made about any time languages got a level higher. This kind of rejection of powerful in favor of complex-but-familiar is precisely what Bret Vector warns against in the Future of Programming talk[1]. If anything, `await` makes debugging easier because you don't have to untangle callbacks and jump back and forth. You're not supposed to “debug th…

The sarcasm in my post was unnecessary, so I've replaced it with a better explanation.

Re: Callbacks as our Generation's Goto Statement

#17
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 callbacks to goto is a tad unfair. They don't merely solve async issues, but also event handling and dynamic systems to name two common uses. I don't see a better solution on the table. Using callbacks to write deeply async code is the real problem. And while async/await may help with this problem, it still won't tell you why step 3 never finishes, because it's still waiting for a come from.

Re: Callbacks as our Generation's Goto Statement

#19

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 the relation between callbacks and other programming constructs.

Re: Callbacks as our Generation's Goto Statement

#20
post #5

I agree, although I think callbacks are more like COME FROM than goto. You see a function being passed somewhere as a callback, and you know the block is going to execute at some point, but most of the time you have no idea what the codepath that calls you back looks like. There's nothing more frustrating than trying to debug why a callback isn't being called. Who calls it? How do I set a breakpoint somewhere to see…

PLEASE. There's nothing wrong with COMEFROM.
Post reply on HN