Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

71–80 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#71
post #42

I love when Node.js advocates try to convince you that promises are as good a concept as anyone would need to handle asynchronous programming

Promises were removed from node core a long time ago, and remained unpopular until very recently. They are making a comeback due to lobbying in standards committees, forward-compatibility with ES6 generators, and the jQuery effect.

Fair enough. I guess I'm confusing IRC with reality again.

Re: Callbacks as our Generation's Goto Statement

#72
post #43

Earlier quoted context omitted.

Yes, C# tends to copy F# features in the way of compiler-syntactic-sugar. I wonder if Type Providers will be next. Async/await have been around for a couple of years and I haven't heard of the next big C# feature, other than Roslyn.

They seem to be pretty busy with Roslyn, Anders recently admitted it's taking longer than originally expected. So perhaps we need to give 'em a break. The only thing I heard about C# 6 so far is it's maybe going to have more compact class declarations, a-la F# or TypeScript.

C# 2 added generics (courtesy of the same people that did F#) and closures (albeit with syntax as verbose as JS).

C# 3 added LINQ, which is a major breakthrough for end-users, although I'm not fond of the query language. So really, C# 3 just added in some basic features you expect from proper languages. I do understand this required a huge amount of work, esp. with the tooling required.

C# 4 added dynamic (F# provides ? operator you can provide your own implementation for, if you really feel that strings look ugly). Oh, and it finally backpedalled on the no optional parameters (although the optional parameters is the same broken C-style callsite implementation).

C# 5 added async (F# had a more flexible implementation 6 years before).

What else? C# seems to have stagnated, although I understand that's a feature for some of their users. C# still lacks type inference in most places, making it extra verbose. C# expression trees are still very limited. C# still can't easily do tuples. Not sure they deserve a break; this was MS's "flagship" language.

OTOH, The CLR itself doesn't seem to be getting any upgrades, either - IL stayed locked at v2. It's as if they realised they have done better than the JVM can ever do (generics via erasure just sucks) so why bother pushing it further?

Re: Callbacks as our Generation's Goto Statement

#73
post #30

Earlier quoted context omitted.

The C# designers outdid themselves this time. I'm surprised they managed to made this feature so simple and succinct, especially for an "enterprise" language. Those two little words (async/await) seem like something I would expect from a language like Python or Ruby. Had it been Java, it would be called AsynchronousBureaucraticProccessDispatcherFactoryFactoryFactory.

F# implemented this many years before (6 years ago), and as a library , just by providing the proper language feature, workflows, and a default async implementation. In comparison, C# adds special compiler keywords for one specific example, just like they did with LINQ. That seems rather ugly IMO. Providing building blocks and letting libraries fill things in is a lot nicer. This is more of a "C#'s finally catching u…

I don't think it's fair to characterize this as "catching up". Both F# and C# are developed by an overlapping group of people at Microsoft. And, until recently, the bulk of Haskell's GHC was done by SPJ in a closely collaborating group in Microsoft Research.

The correct characterization is to view this as a pipeline from a research language, to a specialists' language, to a common man's language.

Six years isn't really all that long to wait for a specialist feature to be 1) motivated 2) conceived 3) prototyped 4) validated 5) justified 6) implemented 7) tooled 8) released 9) marketed. Given that there are hundreds of ideas and only so much time, the "minus 100 points rule" [1] basically means that it's no easy feat for a feature like this to show up in a mainstream language. When you consider the quality bar, level of IDE integration, the magnitude of the education effort, and all the other odds and ends, it's something of a minor miracle.

[1]: http://blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx

Re: Callbacks as our Generation's Goto Statement

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

Re: Callbacks as our Generation's Goto Statement

#75
post #64

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…

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 cause the last player to have the first input name, the second-last player to have the second input name, and so on.

Edit: I was optimistically assuming that the consumer of the many "asks" that are created all at once would process them sequentially, dealing with one and invoking the callback before dealing with the next. If you do not assume this, my problem disappears and you get the simpler problem of spawning many prompts simultaneously.

Re: Callbacks as our Generation's Goto Statement

#76

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

If you like icedcoffeescript, take a look at this:

https://github.com/bjouhier/galaxy

Essentially await/async using Harmony Generators.

Re: Callbacks as our Generation's Goto Statement

#77

In the right places and for the right reasons they are fine. A lot of code today devolves into what I've come to call "callback spaghetti" and, well, good luck. The toughest thing sometimes is getting your mind around what is supposed to happen and, more importantly, what is not. I found that sometimes it helps to build a state machine to effectively run the show and try to limit callbacks to setting flags and/or nav…

That's a smooth point! As you probably know, async code is translated by C# compiler to a state machine[1].

[1]: http://stackoverflow.com/a/4047607/458193

Re: Callbacks as our Generation's Goto Statement

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

[deleted]

Re: Callbacks as our Generation's Goto Statement

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

Yes! I really hope this use of yield will bubble up to the language spec and become pervasive in Python. It really strikes me as the Pythonic approach to solving callback hell.

Re: Callbacks as our Generation's Goto Statement

#80

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…

  (function(players) {
    var cur_idx = 0;
    function cb(name, err) {
      // just kidding, not going to handle errors!
      if (IsValidName(name)) {
        players[cur_idx].name = name;
        cur_idx++;
      }
      if (cur_idx 
This is of course completely awful. just2n's reply is a nicer realization of the same concept. sprobertson's reply clearly will not work as written, and I don't expect it's even possible to condense this code into a single call to eachSeries.
Post reply on HN