4 ms·
Ooh, this brings back memories. Continuation-based web frameworks were my original gateway drug to "exotic" programming techniques. Dabble DB was the poster chi
by cousin_it 11y ago
Ooh, this brings back memories. Continuation-based web frameworks were my original gateway drug to "exotic" programming techniques. Dabble DB was the poster child of Seaside, but didn't get much traction and was acqui-hired by Twitter, whereupon Avi Bryant moved on to other pastures. The other high profile examples of continuation-based web development were Paul Graham's Viaweb (which was acquired by Yahoo and rewritten with more traditional techniques) and Hacker News (which had usability problems due to continuations and mostly phased them out). The verdict of history is clear: continuation-based web development is a sexy but ultimately misguided idea.
- deleted 11y ago[deleted]
- dang 11y agoGreat comment, but I don't think I agree with your conclusion. HN still has closure-style handlers [1] all through the code—60 or so as of the latest commit. We phased out the ones that were being invoked millions of times, but I'd emphasize that our reason for doing this was implementation-driven, i.e. accidental rather than essential. (This, by the way, is true of many alleged "verdicts of history" in programming. Those who care about good ideas should treat such arguments as guilty until proven innocent, lest we all get sucked completely into popular practice.) Writing the code to phase out those handlers was a deep lesson for me, because the new code came out more verbose and harder to follow. One rarely gets to do an apples-to-apples comparison of programming techniques on a production system, and somewhat to my surprise the experience convinced me (I was agnostic to begin with) that the closure approach is superior. There are at least four reasons: (1) the closure has immediate access to all the state that existed when the request was previously processed; (2) the closure is nested inside the code that creates it, so everything you need to understand a full request cycle is in one place; (3) much boilerplate is eliminated, making the code easier to read and write—it can be explicitly at the problem level; (4) security is less of a worry when the client only has to pass back a token instead of all the original parameters to the request, the latter being safely packed away in the closure. That last advantage, i.e. reduced attack surface, was particularly surprising. Learning this the hard way, by dismantling those advantages and replacing them with manual code in selected cases, taught me something else about this design: it's more than just a clever device. It's really a triumph of two of the greatest programming ideas: first-class functions—more specifically, what used to be called upward funargs [2] back when people were arguing about whether they were a good idea—and lexical scoping. The combination of those two abstractions is what allows this model to shuffle off most of the gruntwork instead of making you, in pg's memorable phrase, a human compiler. The fact that the design eventually hit scalability problems at millions of users is also a vindication of it, in the sense that it enabled pg to write HN more quickly and safely in the first place. We could selectively deal with the scalability problems later, and have done so. That has worked fine as an engineering tradeoff, but IMO a better solution will come from new implementation ideas that allow another couple orders of magnitude of closures to be kept without slowing down the rest of the system. If we get there, I will take pleasure in rolling all that manual code back into the original design. 1. They're closures, not continuations, which for HN is fine. 2. Meaning the ability to return a function from a function, and thus keep it around indefinitely, as opposed to passing a function to another function as a parameter (downward funargs).
- cousin_it 11y agoYeah, all fair points. Client-side AJAX apps also allow you to keep state from one request to the next, instead of tossing it back and forth over the net. You can use closures on buttons and everything. In some ways it's even more natural than keeping state on the server, because the client knows exactly how long the page stays open. And it doesn't break when you have lots of users, because they keep the state instead of you. I guess that's part of the reason why AJAX got so popular :-) That said, if I were building a site like HN, I wouldn't use any of that stuff. I'd go with a bog standard request-response model. There's just not that much state to be preserved. Except maybe draft comments, but these should go in browser storage anyway.
- dang 11y agoRe Ajax, yes, but there's plenty of state that you can't send to the client. For HN, an example would be the list of known spam sites. > There's just not that much state to be preserved Are you sure? From my perspective there's enough to make the complexity difference in the two models significant.
- cousin_it 11y agoNo, I'm not sure. But from a quick look, it seems like most GET handlers on HN take at most two parameters, except for "flag" which takes three. The POST handlers take more, but that's stuff that needs to be sent to the user anyway, because the user is editing it. Out of the stuff that I did see, the "goto" parameter is the most obvious candidate for the closure treatment. It's also the most obvious candidate for the AJAX treatment, if you add in-place editing like on Reddit, which would be a better UI in my opinion. Sorry if that sounds arrogant! Of course there could be a lot of functionality that I've missed.
- cwp 11y agoNo, it wasn't misguided. It worked great, and made writing web applications so much better and easier than it had been. But Javascript has come a looong way in the last 15 years, and sophisticated web applications do a lot more client-side processing these days. That leads to different architectures, where continuations aren't as advantageous as they had been. Hacker News is notable in that it doesn't use much client-side code and sticks to an old-school links-and-forms UI. Closures still make a lot of sense for that architecture.