Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

271–280 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#271

"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…

There's nothing inherently harmful about goto either, and people who think that just having it around is death, seriously don't understand the machines they're programming, and how we implement these magical control structures they love so much. (hint: we use goto) I don't feel any respect for the article because it's written on the premise that goto is bad, and that it is anything like a callback. Callbacks have bee…

I don't think the article is written on the premise that Goto is inherently bad, I think it's written on the premise that it can lead to unmaintainable code if misused.

I've had some of the exact situations described in the article come up many times at work — especially with blocks in Objective-C (nested error handling, recursive blocks, and so on). The `await` keyword seems like a very nice tool for a lot of common use cases that can be problematic with blocks/callbacks.

Re: Callbacks as our Generation's Goto Statement

#272

Earlier quoted context omitted.

That sounds like state to me.

Do you have any other method of updating the UI without calling corresponding methods? I'm lost on your argument.

Well if the goal is to have a "spinning wheel UI element" to reflect to the user that the app is in a "busy" state, and the UI element requires calls to modify its animation state, then no I don't have a way to do it without calls to the UI element.

Re: Callbacks as our Generation's Goto Statement

#273
post #234

This is all simply sugar to hide behind-the-scenes threading behind very narrow interfaces. Which isn't necessarily bad, but it's fun to see it suddenly in favour again and presented as something new. E.g. Simula67 had Call and Detach for the basic case, and Activate(object representing async behaviour) and Wait(queue) that would both depending on need often be used for the same purpose (as well as a number of other…

That was my thought. I always get lost in these discussions because I have to translate the bizarre lingo into basic threading primitives I can understand. Once I've done that I don't understand what all the fuss is about.

I think the issue is that most programmers actually never touch threading, or if they do, they get complicated threading models shoved in their faces and run away in horror (which is a reasonable reaction). But these constructs looks sort-of like they're just wrappers around callbacks.

Never mind that the only reason callbacks are all that interesting in JS is because they allow the engine to sneak in threading behind your back - most people have a very woolly idea about how JS execution happens and the fact the javascript execution itself isn't threaded.

Re: Callbacks as our Generation's Goto Statement

#274
post #189
post #182

Earlier quoted context omitted.

Not terribly plausible in kernel code.

Not all kernels are UNIX.

I didn't know UNIX won't allow kernel exception handling. Source?

Of course exceptions are suboptimal; bad performance compared to "goto" can have unintended side effects depending upon the OS (scheduling work may be triggered off of the additional interrupt).

Re: Callbacks as our Generation's Goto Statement

#275
post #95

Earlier quoted context omitted.

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…

An alternative that can work, unless you need nested loops, would be to just wrap everything in a do {...} while(false), and then call break.

Re: Callbacks as our Generation's Goto Statement

#276
post #274
post #189

Earlier quoted context omitted.

Not all kernels are UNIX.

I didn't know UNIX won't allow kernel exception handling. Source? Of course exceptions are suboptimal; bad performance compared to "goto" can have unintended side effects depending upon the OS (scheduling work may be triggered off of the additional interrupt).

> I didn't know UNIX won't allow kernel exception handling. Source?

My statement was based on ideology as I doubt typical UNIX kernel coders would ever allow for exceptions, given that C does not support them and is against the UNIX way.

> Of course exceptions are suboptimal; bad performance compared to "goto" can have unintended side effects depending upon the OS (scheduling work may be triggered off of the additional interrupt).

Exceptions at the kernel level are possible, Windows does it for certain classes of errors, for example.

Some other commercial or research kernels might do it as well.

Re: Callbacks as our Generation's Goto Statement

#277

Earlier quoted context omitted.

Well in addition to not having a problem with callback hell I also haven't used a debugger in more than three years, so I guess I'm just weird. As I said I like to write unit tests with my named callbacks. This allows me to test the callbacks as well as the root level functions that make use of these callbacks to ensure that everything is working perfectly. When I follow this model it is extremely rare that I ever en…

When someone gives you a sufficiently large codebase written by other people and asks why when they click A they get B, you have two options: 1. Read the code and try to reason about it. 2. Fire up the debugger and replicate user actions. Guess what? Callbacks in JS make option #1 significantly harder, since they are, essentially, runtime weakly typed mechanism for code composition.

This is a common issue.

I guess people that state they are fine with it, never worked on the typical enterprise codebases, done by several consulting firms along the years.

When one works on their own code, or startup elite programmer style, everything is easy.

Re: Callbacks as our Generation's Goto Statement

#278

Earlier quoted context omitted.

C# operates entirely differently, I understand. The IDE work is massive and necessary. Having said that, a lot of this stuff is "catching up" or implementing stuff from the 70s. To be clear, it's not like type inference or closures were invented with Haskell, F#, or C#. Stuff like that is pretty well-known PL stuff, isn't it? People would be upset if C# didn't have for loops; why aren't they upset the type inference…

Probably because they don't know it's useless. I use and like C#. The type inference seems useful to me. Avoiding generic parameters on almost every linq extension method is a huge savings in comprehensibility. var x = new SuperDuperLongClassName(); is a nice savings in redundancy. Where can I see an example of useful type inference?

Off the top of my head, C# can't type infer: Fields, properties, parameters, return types, lambdas, generic type declarations, type constraints.

I did a pretty fair line-by-line translation of a C# app to F#, and the F# version needed 1/20th the number of type annotations.

Re: Callbacks as our Generation's Goto Statement

#279
post #133

I have a basic technical question. I work in C for embedded systems, so I'm a bit "behind the times." How is "await" any different from a regular blocking system call? A regular system call does exactly what is being described: The system call happens, and then when it is finished, execution resumes where it left off. (Yes, this makes the thread block... which is why you have multiple threads. I think the answer will…

If you remember the (gnu, ossp) pth library or any of the various cooperative multitasking equivalents for C, this is all the people raised on javascript, who started writing callback APIs for C#/ObjC discovering the same idea.

await is equivalent to "yield" or "wait" in most of those systems. The idea is to pause execution and jump back to the cooperative scheduler, which will eventually execute the function call in question. Once that call ends up with a result, the scheduler will then (eventually) resume your function with the result at the point you yielded. In the midst of all that, various other threads of control will be scheduled briefly -- for instance, the ones servicing sockets and whatnot. It's all single threaded and cooperative -- typically with an event system embedded.

Part of the callback "mess" is the result of the short memory of our industry. I was working with these kinds of systems in C code years and years ago. It didn't take long for most people to realize that you wanted to abstract the callbacks to the scheduler so you were writing your code instead fucking with the state machine mechanism used to implement the cooperative framework in question. No references to abstract CSP (or CPS :-)) ideas needed, really -- it's basic practical knowledge that seems to have been ignored over time.

Re: Callbacks as our Generation's Goto Statement

#280

As someone who only recently switched to Node.js from PHP I personally haven't had any difficulty switching over to the callback frame of mind, and I haven't experienced the "callback hell" so many people complain about. At first I was hesitant to start with Node because I saw blog posts by people bemoaning the spaghetti callback code that they ended up with. But I haven't experienced any of that, although I am a rel…

I'm tired to the utmost degree of all these posts about people (supposedly) coming from PHP/C#/Ruby/Python background and seeing "absolutely no problems" with JS syntax, object model and programming paradigms. There are problems. They are objectively there. If you don't see them, you have to check your critical thinking skills, rather than imply that everyone outside of elite JS circles are simply too ignorant to und…

IMO, this is more of a problem of indirections than its a problem of callbacks.

If you use anonymous function as the callback there is no indirection and you know perfctly well where to set the break point.

At the same time, you can also have the sort of debugging problem you mentioned in regular code whenever you call a method in some polymorphic object. (the "listener" pattern is just one example of this)

Post reply on HN