Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

111–120 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#111
I always liked event based systems the most. I find them to be clean and flexible. Sometimes you want to run some more code after you run an async operation, or you want to run multiple operations at once and deal with them out of order. Await seems pretty linear.

Re: Callbacks as our Generation's Goto Statement

#112

I don't understand what the big deal is. Callbacks are OK. They're less cumbersome if the language you're using has smaller function definitions. Callbacks 'get crazy' when you've got more than one I think, and thankfully someone smart has made a library you can use to manage them! https://github.com/caolan/async Saying that, I don't mind the way things look with the whole await/async stuff in C# and etc. However I d…

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…

[deleted]

Re: Callbacks as our Generation's Goto Statement

#113

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

You're missing the point of `await`. Await does change how your program is structured, unless we're talking about most trivial cases. You can use `await` inside a `for` loop—can you do the same with callbacks without significantly re-structuring your code? What is the “callback analog” of placing something in a `finally` block that executes no matter which callback in a nested chain fails? You'd have to repeat that c…

There are other means of accomplishing what you are referring to, for example, the async module for node.js is really nice in terms of having loop workers, as well as flattening out callback structures.

I find that async.waterfall + SomeFunction.bind(...) are insanely useful with node.js ... I don't seem to have near the friction in node that I find when working in C# projects.

Re: Callbacks as our Generation's Goto Statement

#114
I'm not buying the c# async/await kool-aid.

Async, sure, I'm down with that, but I've used the c# async stuff now, and while it makes it the app somewhat faster, it has three major downsides (that I encountered):

- Infects everything; suddenly your whole application has to be async.

- Debugging becomes a massive headache, because you end up in weird situations where the request has completed before some async operation completes, the debugger gets scared and stops working.

- It's really hard to test properly.

The only good reason for using it is that because of the infection-property back fitting async to your application is a major headache; if you might use it, you have to use it from the beginning or you get a huge backlog of refactoring and test fixes to do.

-___- 'I might use this for some performance bottleneck I don't yet know about, so better start using it now...' yeah, that's a thing: premature optimization.

Re: Callbacks as our Generation's Goto Statement

#115
The problem is simply that those languages are not Lisp.

Once good patterns of use of GOTO were found, it was natural to critisize random uses, and to wrap good uses in a lisp macro. Or in a new while or for "instruction".

But then the next construct is discovered, and its bad uses considered harmful, and its good uses need to be wrapped. In lisp, mere programmers will just write the next macro to abstract away this new construct. Other programming languages need to evolve or have new language invented with new "instructions".

So now it's the callbacks. Yes, in lisp we'd just use closures, but this is only a building block for higher level constructs. If those "callbacks" are needed to represent futures, then we'd implement those futures, as a mere lisp macro.

Yes, in the other languages you're still powerless, and need to wait for the language designers to feel the pressure and implement a new "future" instruction or whatever.

Any language construct can be considered harmful eventually. Concretely, a repeative use is a hint of that: the construct becomes meaningless because it's used all the time, or apparently randomly (just like those GOTOs). But it's not that the construct is bad, it's that its usage is not abstracted away in higher level constructs. And the only way to do that is lisp macros.

So unless you're programming in lisp (a homoiconic programming language that let you write easily macros in the language itself), you will always reach a point where some construct will be able to be considered harmful for lack of a way to abstract its uses away.

Re: Callbacks as our Generation's Goto Statement

#116
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.

It's not clear if you know or not, but it's the common name of http://en.wikipedia.org/wiki/List_of_cognitive_biases#Freque...

Re: Callbacks as our Generation's Goto Statement

#117

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

HN discussion of that article: https://news.ycombinator.com/item?id=4732924

FRP is an interesting topic (I thought so anyway, I wrote a paper on it for my MS). It doesn't seem to have caught on widely as a paradigm, with a few exceptions I'm aware of (Elm, Meteor).

Re: Callbacks as our Generation's Goto Statement

#118
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.

It's a reference to the Baader-Meinhof phenomenon, a.k.a. "frequency illusion".

Re: Callbacks as our Generation's Goto Statement

#119
post #57

You get a similar interface in Python's Twisted using the @inlineCallbacks decorator: @inlineCallbacks def example(): try: obtain_some_lock() ui_status("Fetching file...") result = yield fetch_file_from_server(args) ui_status("Uploading file...") yield post_file_to_other_server(result) ui_status("Done.") except SomeError as e: ui_status("Error: %s" % e.msg) finally: release_some_lock() I must say that this style of w…

Tornado has a similar interface:

    class GenAsyncHandler(RequestHandler):
        @gen.coroutine
        def get(self):
            http_client = AsyncHTTPClient()
            response = yield http_client.fetch("http://example.com")
            do_something_with_response(response)
            self.render("template.html")
(via http://www.tornadoweb.org/en/stable/gen.html ..)

Re: Callbacks as our Generation's Goto Statement

#120
post #57

You get a similar interface in Python's Twisted using the @inlineCallbacks decorator: @inlineCallbacks def example(): try: obtain_some_lock() ui_status("Fetching file...") result = yield fetch_file_from_server(args) ui_status("Uploading file...") yield post_file_to_other_server(result) ui_status("Done.") except SomeError as e: ui_status("Error: %s" % e.msg) finally: release_some_lock() I must say that this style of w…

Obligatory mention of gevent[1].

It handles all the plumbing for you with monkey-patching I/O calls. No annotations necessary, you just write linear code.

[1] http://www.gevent.org

Post reply on HN