Live data from Hacker News

Callbacks as our Generation's Goto Statement

tirania.org

181–190 of 287 posts

Re: Callbacks as our Generation's Goto Statement

#181

Earlier quoted context omitted.

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

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…

People would be upset if C# didn't have for loops; why aren't they upset the type inference is nearly useless?

Can you honestly not comprehend the answer to this? There are plenty of languages without type inference and shit gets done fine. People don't rely on it. People do rely on for loops.

Re: Callbacks as our Generation's Goto Statement

#182
post #178
post #141

(C/OS developer spiel) I'm sick of these app developers assuming that using "goto" is bad practice. The fact is that "goto" is used plenty in great production code you're probably running right now.[1] I'd like to know a cleaner way to abort a function into its cleanup phase when a function call returns an error. And "goto" statements are extremely simple to handle for even the most naive of compilers. [1] https://ww…

Exceptions

Not terribly plausible in kernel code.

Re: Callbacks as our Generation's Goto Statement

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

The aforementioned CERT guideline:

https://www.securecoding.cert.org/confluence/display/seccode...

Skeptics should note that the real-world example on that page is from the Linux kernel, where this style of goto is used heavily for error handling.

Re: Callbacks as our Generation's Goto Statement

#184

Earlier quoted context omitted.

(for whatever's worth, I'm Brazilian)

Aren't you still American? ;) As an Indian I am confused why only people of the US are called Amerians while two entire continents are called America. And also, why we Indians are not considered Asians by the said Americans.

Because "America" is part of the nation's actual name, and the only part that isn't a modifier. What else could you call Americans? Unionized Statists?

Re: Callbacks as our Generation's Goto Statement

#185
post #28

Can someone explain to me the difference between this and futures (specifically, futures in c++11)?

std::async uses threads (if used with std::launch::async) whereas C# await uses coroutines. You can use Boost.Coroutine to implement something similar in C++ as that project has done: https://github.com/vmilea/CppAwait

Re: Callbacks as our Generation's Goto Statement

#186

There is some creative use of C# async/await in this blogpost: http://praeclarum.org/post/45277337108/await-in-the-land-of-... Basically, the author implements a “first time walkthrough” kind of interface a-la iWork very declaratively by using async: async Task ShowTheUserHowToSearch () { await Tutorial.EnterText (searchField, minLength: 3); await Tutorial.Tap (searchButton); await Tutorial.Congratulate ("Now you kno…

What if you have two buttons, search and 'be lucky'? I guess you will have to await for a controller object that wakes up that if either one of the buttons is triggered, and then test what button was pressed. Now what if you have add a search option dialog that can be invoked at any moment? I guess when the 'apply' button of the option dialog got pressed then this is still going to be a callback that sets global vari…

In event driven programs there are often events that can arrive at any moment; for example in networking the connection might have been closed by the peer, or in a GUI the user might chose to alter parameters by means of option dialog.

So with await you may need to write a wrapper around await, the wrapper function will check for common events that can arrive at any moment.

Re: Callbacks as our Generation's Goto Statement

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

> Yes! I really hope this use of yield will bubble up to the language spec and become pervasive in Python.

And the time machine spaketh: http://www.python.org/dev/peps/pep-3156/#coroutines-and-the-...

(it has no reason to "bubble up to the language spec", the language provides all the right primitives — especially with Python 3's `yield from`, it's up to the libraries to use them. That is a Good Thing.)

Re: Callbacks as our Generation's Goto Statement

#188
post #164

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

But doing things by hand with callbacks is going to have all of those same issues isnt it? If you dont want to infect everything then you basically need to just write synchronous code instead...

Correct. Same with introducing futures/deferred.

Re: Callbacks as our Generation's Goto Statement

#190

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…

I would do it in Node.js like the following:

  async.eachSeries(players, askName, function (err) {});

  // this is someplace it should go
  function askName(player, callback) {
    Ask("What's your name", function (err, name) {
      if (err) { return callback(err); }
  
      if (IsValidName(name)) {
        player.name = name;
        callback(null);
      } else {
        askName(player, callback);
      }
    });
  }
This follows Node's err convention. Note I use a bit of old fashion recursion to handle the asking for a valid name. This will not stack overflow due to the fact Ask is async. You could inline askName, but then you wouldn't have a nice little unit testable function.
Post reply on HN