4 ms·
Didn't expect to say this, but the article is completely right! This is obviously the right way to write concurrent programs. Kudos for writing this. One quest
by cousin_it 9y ago
Didn't expect to say this, but the article is completely right! This is obviously the right way to write concurrent programs. Kudos for writing this.
One question though. The first part of the article says that "onclick" handlers should be replaced with nurseries as well. But I don't see how. Can someone explain?
- jerf 9y agoI suspect that if you were to try to do this in real code, something like an onclick handler would have to be run in a nursery scoped at the page level, by the code running the page. An onclick handler on its own accord can't run itself in the correct nursery. It's like the network handling case there, where the nursery's lifetime is either unbounded, or tied to the lifetime of the OS process, depending on how you want to look at it. Functions don't always return within a program, or at least, don't always return excepting maybe a last cleanup as the program terminates.
- marshray 9y agoMaybe a subtle difference here is that a page doesn't get to block on anything before it gets closed. So how is creating a nursery that matches the lifetime and visibility of the page different from not using a nursery at all?
- jerf 9y ago"Maybe a subtle difference here is that a page doesn't get to block on anything before it gets closed." In real browsers, the UI act of closing a tab and the completion of cleaning up all of its resources are already clearly separated. I can see that when I terminate a browser with a lot of tabs and the main window has entirely closed while the browser runs at 100% CPU for quite a few more seconds. Plus a browser can probably hard-kill running Javascript code with some reasonable effectiveness. (Not sure. Asynchronous exceptions are very, very hard.) So I don't think that's a disqualifier. "So how is creating a nursery that matches the lifetime and visibility of the page different from not using a nursery at all?" Well, as I've said in one of the reddit conversations, bear in mind the entire purpose here is not to enable something that was previously impossible, but to constrain us from using primitives in their most powerful form. The big thing is that if you had a nursery-based system, and the page had a nursery associated with it, and the page's render routine returned, you'd know that all the page threads must necessarily be terminated. You can't know that with the same confidence now, because the programming style does not permit that level of confidence by construction. Browsers are a bit of a pathological case on a lot of levels, though, and probably not a great mental example, because you can assume a high degree of competence, concern, and skill in the people programming the browser, and they do things like use static analysis all the time and even in the "worst" cases, develop entire new programming languages to write browsers in. So you are probably justified in saying "But jerf, I'm pretty confident the browsers are already cleaning up their stuff without this stuff." The real question is, how does this look for Joe Programmer and his ability to work in the domain of multithreaded programming, which is well known and widely acknowledged to be very difficult, by constraining what mistakes he can make? One of the other angles you can look at this with is, if I have two pieces of correct code and I compose them together, are they still correct? The nursery system says that with my nursery, I can call other code that uses them, and the composition attained over that function call is also correct and does not leak resources. We do not get that guarantee with some other primitives. We do with others. There's a lot of experimentation still going on in this field. I'm not saying this approach is guaranteed to be correct, but it's one of the more plausible claims to being a primitive as basic as "if" is relative to "goto". Compare with Software Transactional Memory, which as nice as it may be, is wildly more complicated than "if" no matter how you slice it.
- wilun 9y agoThat's an interesting tool, but merely among other. Not the next big things to structure thread usage. There are loads of problems if we wanted to generalize that solution as fundamental, and a quick review of the state of the art (of which we can have a quick preview by taking a look at these very comment threads on HN) show a wide spectrum of alternatives, sometimes for similar and sometimes for somewhat different use cases. I see fundamental issues with it: in some cases the checking model proposed by Rust is better; also - and this is related -, your don't always fix things reliably by mindlessly extending lifetimes or delaying things until termination of others, in the same way that mindlessly switching a resource usage to a shared_ptr in C++ if you had a lifetime issue can't be done in the general case, because you could very well only be trading a bug for another. Checking capabilities are more useful and general than constructive limitations, especially when we have load of counter examples on use cases. So without hesitation: yes, this is more structured than having no structure on the point considered, but that is not at all a sufficient criteria to make that the kind of panacea the author seems to think it is. I would have been way more positive in seeing that presented as a comparison with the other existing solutions, similar or not, and without that little escape hatch story that makes me thing the author has found a hammer and now everything looks like a nail to them.
- mannykannot 9y agoAs callback have their uses as event handlers in single-threaded event-driven programs, I would guess that he is referring specifically to mechanisms that use callbacks in a concurrent setting - perhaps the code calling the handler is supposed to set up the nursery?