
I wonder whether this can be done in Haskell (see muleherd's comment): http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web... Cristiano

I haven't looked at the details, but I think this is what a library like
Reactive from Conal Elliott could do, but as far as I understand it, it is
still work in progress.
On Wed, Feb 11, 2009 at 2:22 PM, Cristiano Paris
I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
Cristiano _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Wed, Feb 11, 2009 at 2:30 PM, Peter Verswyvelen
I haven't looked at the details, but I think this is what a library like Reactive from Conal Elliott could do, but as far as I understand it, it is still work in progress.
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation. Cristiano

On Wed, Feb 11, 2009 at 1:41 PM, Cristiano Paris
On Wed, Feb 11, 2009 at 2:30 PM, Peter Verswyvelen
wrote: I haven't looked at the details, but I think this is what a library like Reactive from Conal Elliott could do, but as far as I understand it, it is still work in progress.
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation.
I think that would be difficult. You could probably store the continuation in a server-side cache if you aren't doing CGI but have a persistent server process, but eventually you'll need to discard unused continuations to avoid running out of memory. You may be able to use a WASH style continuation model in conjunction with this. So you store the session logs on disk, and if the continuation does not exist in memory you'd fetch the session log from disk, replay the whole session from that, and reproduce the continuation that way. That way most sessions would just work directly off of the cache and never touch disk, but if someone waits too long (or, say, bookmarks a page in the middle of the session!) there's still a fallback stored on disk. -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862

On Wed, Feb 11, 2009 at 2:53 PM, Sebastian Sylvan
I think that would be difficult. You could probably store the continuation in a server-side cache if you aren't doing CGI but have a persistent server process, but eventually you'll need to discard unused continuations to avoid running out of memory. You may be able to use a WASH style continuation model in conjunction with this. So you store the session logs on disk, and if the continuation does not exist in memory you'd fetch the session log from disk, replay the whole session from that, and reproduce the continuation that way. That way most sessions would just work directly off of the cache and never touch disk, but if someone waits too long (or, say, bookmarks a page in the middle of the session!) there's still a fallback stored on disk.
I thought about something like that. In this regards, I narrowed the problem to a computation's internal binding to symbol names. With this respect, a point-free approach, like the one found in the factor language, would be simpler to handle as you'd have to serialize the state of stacks and those of any other monads used. Cristiano

Cristiano Paris ha scritto:
On Wed, Feb 11, 2009 at 2:30 PM, Peter Verswyvelen
wrote: I haven't looked at the details, but I think this is what a library like Reactive from Conal Elliott could do, but as far as I understand it, it is still work in progress.
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation.
Not sure this is a good thing in a web application. Manlio

On Wed, Feb 11, 2009 at 4:08 PM, Manlio Perillo
Cristiano Paris ha scritto:
On Wed, Feb 11, 2009 at 2:30 PM, Peter Verswyvelen
wrote: I haven't looked at the details, but I think this is what a library like Reactive from Conal Elliott could do, but as far as I understand it, it is still work in progress.
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation.
Not sure this is a good thing in a web application.
I'm thinking of complex workflows and inversion of control. A computation may stop, return a response, wait for a new request to be passed by the HTTP server and return back a new response, stopping again. This goes on forever. All this can be achieved in Haskell but the serialization path, which is crucial for swapping out idle sessions (containing the stopped computation) or to get back to life after server stopped (for maintenance for instance). I guess this should be doable in Clean, which has mechanisms to do dynamic binding and serialization of closures. I once did something close to this using Stackless Python, which sports serializable iterators. I did funny things like moving all the sessions to a different server transparently. Nevertheless, the use of yield, specially in sub-computation, is tricky to handle. Notice that this is not a main concern in my daily work but the possibility fascinates me and it turns out to be not a simple problem to solve. During my explorations, I considered continuations, delimited continuations and zippers, and I learned a lot even if I can't still catch delimited continuations. Recently, I stumbled upon Factor and realized that most of the complications are simply cut out in that language as it is purely concatenative (no symbol bindings to mess around). Cristiano

Cristiano Paris wrote:
Manlio Perillo wrote:
Cristiano Paris ha scritto:
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation.
Not sure this is a good thing in a web application.
I'm thinking of complex workflows and inversion of control.
A computation may stop, return a response, wait for a new request to be passed by the HTTP server and return back a new response, stopping again. This goes on forever. All this can be achieved in Haskell but the serialization path, which is crucial for swapping out idle sessions (containing the stopped computation) or to get back to life after server stopped (for maintenance for instance). I guess this should be doable in Clean, which has mechanisms to do dynamic binding and serialization of closures.
It's ugly, but one option is to just reify your continuations as an ADT, where there are constructors for each function and fields for each variable that needs closing over. Serializing that ADT should be simple (unless some of those functions are higher-order in which case you run into the same problem of how to serialize the function arguments). In GHC's STG machine this representation shouldn't have much overhead, though it does require the developer to do the compiler's job. -- Live well, ~wren

On 2009 Feb 12, at 1:04, wren ng thornton wrote:
It's ugly, but one option is to just reify your continuations as an ADT, where there are constructors for each function and fields for each variable that needs closing over. Serializing that ADT should be simple (unless some of those functions are higher-order in which case you run into the same problem of how to serialize the function arguments). In GHC's STG machine this representation shouldn't have much overhead, though it does require the developer to do the compiler's job.
Hmmm... Template Haskell useful here? Feed it the continuation, extract the AST and rewrite as an ADT? -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

wren ng thornton
It's ugly, but one option is to just reify your continuations as an ADT, where there are constructors for each function and fields for each variable that needs closing over. Serializing that ADT should be simple (unless some of those functions are higher-order in which case you run into the same problem of how to serialize the function arguments). In GHC's STG machine this representation shouldn't have much overhead, though it does require the developer to do the compiler's job.
FWIW, this idea is called defunctionalization (due to Reynolds), and it works for higher-order functions as well (because you can defunctionalize those function arguments in the same way). People in many fields put a lot of effort into turning their programs into state machines... -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig "Attending a mathematics lecture is like walking through a thunderstorm at night. Most of the time you are lost, wet and miserable but at rare intervals there is a flash of lightening and the whole countryside is lit up." - Tom Koerner

On Thu, 2009-02-12 at 19:55 -0500, Chung-chieh Shan wrote:
wren ng thornton
wrote in article <4993BBEE.9070603@freegeek.org> in gmane.comp.lang.haskell.cafe: It's ugly, but one option is to just reify your continuations as an ADT, where there are constructors for each function and fields for each variable that needs closing over. Serializing that ADT should be simple (unless some of those functions are higher-order in which case you run into the same problem of how to serialize the function arguments). In GHC's STG machine this representation shouldn't have much overhead, though it does require the developer to do the compiler's job.
FWIW, this idea is called defunctionalization (due to Reynolds), and it works for higher-order functions as well (because you can defunctionalize those function arguments in the same way).
People in many fields put a lot of effort into turning their programs into state machines...
This paper by Ezra Cooper and Phil Wadler is an interesting recent development in the theory of defunctionalization and very relevant to this particular topic as well: http://homepages.inf.ed.ac.uk/wadler/topics/links.html#located-lambda

Chung-chieh Shan wrote:
wren ng thornton wrote:
It's ugly, but one option is to just reify your continuations as an ADT, where there are constructors for each function and fields for each variable that needs closing over. Serializing that ADT should be simple (unless some of those functions are higher-order in which case you run into the same problem of how to serialize the function arguments). In GHC's STG machine this representation shouldn't have much overhead, though it does require the developer to do the compiler's job.
FWIW, this idea is called defunctionalization (due to Reynolds), and it works for higher-order functions as well (because you can defunctionalize those function arguments in the same way).
Oh certainly. Depending on how the HOFs are used, however, that can lead to a very large grammar. The basic ADT approach works best when there are a small selection of actions to take or pass around (aka few states in the state machine). For a more general solution you'll want to use something like HOAS or Template Haskell's AST, with explicit representations for general function application, let binding, and case expressions. That way the building blocks are small enough to keep the evaluator simple to maintain. -- Live well, ~wren

On Thu, Feb 12, 2009 at 12:41 AM, Cristiano Paris
On Wed, Feb 11, 2009 at 2:30 PM, Peter Verswyvelen
wrote: I haven't looked at the details, but I think this is what a library like Reactive from Conal Elliott could do, but as far as I understand it, it is still work in progress.
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation.
I've been looking into something similar... currently, my best option is looking like deliberately causing a core dump and editing the core file to run as a binary (or even more hackishly, just using gdb.) If there's a less filthy way to do it, I'd love to hear about it. (I know about Data.Binary, but it seems inelegant to have to write out instances for something that exists already in memory - you should be able to just blat it back in.) Mark

2009/2/11 Cristiano Paris
I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
WASH did/does something similar. You can certainly write applications in a similar, workflow-ish style (rather than like a state machine). Alistair

On Wed, Feb 11, 2009 at 9:34 PM, Alistair Bayley
2009/2/11 Cristiano Paris
: I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
WASH did/does something similar. You can certainly write applications in a similar, workflow-ish style (rather than like a state machine).
To hijack the subject, what happened to WASH? The paper seemed like it was full of interesting ideas, but the implementation seems to have failed to capture many hearts. Now it seems like a stagnant project. What were the fatal flaws? [ paris ]
I'm interested in the possibility of stopping/pickling/unpickling/resuming a computation.
From what I recall, WASH stores the continuation in the URL, at least if you turn on that setting...

On Wed, Feb 11, 2009 at 09:43:34PM +0800, Evan Laforge wrote:
On Wed, Feb 11, 2009 at 9:34 PM, Alistair Bayley
wrote: 2009/2/11 Cristiano Paris
: I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
WASH did/does something similar. You can certainly write applications in a similar, workflow-ish style (rather than like a state machine).
To hijack the subject, what happened to WASH? The paper seemed like it was full of interesting ideas, but the implementation seems to have failed to capture many hearts. Now it seems like a stagnant project. What were the fatal flaws?
I actually used it in production for some time, and abandoned it in favor of a FastCGI-based app about 6 months ago. There were several issues. The biggest was maintainability. CPS was difficult to work with, especially when different paths through a web app branch and may later reunite. There was not enough control over how things worked, and the HTML and JavaScript generated did not always fit our needs. Field names were essentially random, and IIRC, so were page names, making integration with other web sites difficult. You can't just link from an external static HTML to a particular page or to the submission of a particular form. There were also issues with people using the back button. It reminded me a fair bit of the issues I ran into when using Python's Twisted framework, actually. -- John

John Goerzen ha scritto:
[...] There were also issues with people using the back button.
It reminded me a fair bit of the issues I ran into when using Python's Twisted framework, actually.
Same experience, with Twisted Web + Nevow. All solved after switching to WSGI and a simple WSGI framework (wrote by myself). Configuration and behaviour (middlewares) are all composable. The only thing I miss is a "little" higher level of abstraction. Right now I operate on "request bodies" (in a text format, usually text/html) but I would like to operate on generic "response entities", where an entity is a generic object/data that can be serialized to a request body. This will allow an even greater degree of composability, where each web "view" returns a generic entity, that can be later transformed to another object/data (filtered) or serialized (to JSON or HTML). I think that Haskell is one of the most suitable languages for this idea, but there is the need for the equivalent of WSGI.
-- John
Manlio

Evan Laforge
On Wed, Feb 11, 2009 at 9:34 PM, Alistair Bayley
wrote: 2009/2/11 Cristiano Paris
: I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
WASH did/does something similar. You can certainly write applications in a similar, workflow-ish style (rather than like a state machine).
To hijack the subject, what happened to WASH? The paper seemed like it was full of interesting ideas, but the implementation seems to have failed to capture many hearts. Now it seems like a stagnant project. What were the fatal flaws?
I got curious and made two pages point to each other, resulting in as many stale continuations as your left mouse button would permit. While the model certainly is cool, I'm not aware of any implementation that even comes close to having production-safe (that is, non-abusable) semantics. Continuations might also be overkill: For things like server-side checked[1] POST hurdle races, specifying a list of form/predicate/action triples seems to be the nicer way to go. Generalising, fgl should be able to take care of any control flow imaginable. [1] Am I the only one who can't stand those buggy js-forms, especially if the client side has a different notion of valid input than the server? -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

On Wed, Feb 11, 2009 at 5:41 PM, Achim Schneider
Evan Laforge
wrote: On Wed, Feb 11, 2009 at 9:34 PM, Alistair Bayley
wrote: 2009/2/11 Cristiano Paris
: I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
WASH did/does something similar. You can certainly write applications in a similar, workflow-ish style (rather than like a state machine).
To hijack the subject, what happened to WASH? The paper seemed like it was full of interesting ideas, but the implementation seems to have failed to capture many hearts. Now it seems like a stagnant project. What were the fatal flaws?
I got curious and made two pages point to each other, resulting in as many stale continuations as your left mouse button would permit. While the model certainly is cool, I'm not aware of any implementation that even comes close to having production-safe (that is, non-abusable) semantics.
Shouldn't the following WASH function help? once :: (Read a, Show a) => CGI a -> CGI a -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862

Sebastian Sylvan
On Wed, Feb 11, 2009 at 5:41 PM, Achim Schneider
wrote: I got curious and made two pages point to each other, resulting in as many stale continuations as your left mouse button would permit. While the model certainly is cool, I'm not aware of any implementation that even comes close to having production-safe (that is, non-abusable) semantics.
Shouldn't the following WASH function help?
once :: (Read a, Show a) => CGI a -> CGI a
Possibly, I don't know. It was in my early days of Haskell, and I quickly gave up on using anything and prototyped my own web server instead. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited.

On Wed, Feb 11, 2009 at 6:41 PM, Achim Schneider
... I got curious and made two pages point to each other, resulting in as many stale continuations as your left mouse button would permit. While the model certainly is cool, I'm not aware of any implementation that even comes close to having production-safe (that is, non-abusable) semantics.
Stale continuations are an issue (think of anonymous accesses), even if my personal feeling is that it may be mitigated using continuations wisely (i.e. only when they're actually relevant). Cristiano

I was poking around once trying to find something like that and stumbled
across this: http://wiki.cs.pdx.edu/forge/riviera.html
Cheers,
Tim
On Wed, Feb 11, 2009 at 8:22 AM, Cristiano Paris
I wonder whether this can be done in Haskell (see muleherd's comment):
http://www.reddit.com/r/programming/comments/7wi7s/how_continuationbased_web...
Cristiano _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (15)
-
Achim Schneider
-
Alistair Bayley
-
Brandon S. Allbery KF8NH
-
Chung-chieh Shan
-
Cristiano Paris
-
Cristiano Paris
-
Derek Elkins
-
Evan Laforge
-
John Goerzen
-
Manlio Perillo
-
Mark Wotton
-
Peter Verswyvelen
-
Sebastian Sylvan
-
Tim Wawrzynczak
-
wren ng thornton