Rich,
I'm responding to an old thread, as I've just discovered Clojure, and
I've just been thinking about how to start using it. I also work with
Weblocks (and like it a lot).
Your comments are spot-on if applied to one particular approach to
continuation-based web development. That approach is popular with
Schemers, as Scheme supports first-class continuations as part of the
language. There have been many presentations and demos by schemers where
each HTTP request basically calls a continuation with the entire
application state. This is not what Weblocks does.
Weblocks does something quite different. The continuations we're talking
about are delimited and do not serve the purpose of freezing the
application logic. Also, the sequential/imperative flow you mention
isn't their main purpose. The main goal is to support actions, e.g. code
like this:
(defmethod render-widget-body :before ((w news-story) &rest args)
[...]
(when (display-mode-toggling-enabled w)
(ecase (display-mode-of w)
(:short (link "[+]" (toggle-display-mode w)))
(:full (link "[-]" (toggle-display-mode w)))))
The link macro actually renders a HTML link pointing to the captured
continuation -- an action, which in this case just toggles how the
widget is displayed.
Notice we aren't actually freezing anything and this is not a full
first-class continuation, it doesn't capture the state of our entire
application. It just lets us conveniently execute an action in the
context of a particular user's session. Another area where
continuation-based actions are useful are multi-step flows, which are
present in every web application (think checkout process for example, or
login/signup).
So, these actions make developing web applications much easier and bring
it much closer to desktop GUI development -- where in any decent
language you would use (lambda) instead of (link) to achieve a similar
effect.
I'm not "following trends" here, I simply haven't seen anything nicer or
more convincing for component-based web development. Getting back to the
original topic, I've also been wondering if a library like cl-cont is
possible in Clojure. Notice I'm not talking about full first-class
continuations here.
And I'm all for thinking outside the box, as long as there is something
*better* outside the box (after all, I *am* looking at Clojure in spite
of a heavy investment in CL!).
--J.
PS: incidentally, would it be possible to allow posting for non-members?
Or otherwise enable posting via news.gmane.org? GMANE is a lifesaver for
those of us whose interests require participating in many groups...
Won't (delimited) continuations require support from the JVM itself (unless we resort to using threads and monitors for "simulating" them)?
--
pinocchio
the hard part about implementing continuations in a language that doesn't already support them is that you're trying to capture it from within.
with a delimited continuation, you're capturing it from the outside, so you don't have that problem.
I did manage to figure out that cl-cont works by transforming the
delimited continuation into Continuation Passing Style (CPS). This is
a general transform that can be done in (almost?) any language, and
certainly can be done in Clojure.
cl-cont defines a subset of Common Lisp in CPS so that the macro
system could translate most code into CPS, and from there delimited
continuations follow.
The complication with Clojure is the possibility of stack overflow due
to the lack of TCO. With the new trampoline functionality this could
probably be avoided, but I don't understand continuations well enough
to really say if that could work.
It also may be that for the use cases Jan is talking about, it is very
unlikely to blow the stack and so maybe you could just deal with that
as a limitation.
/mike.