Continuations in Scala?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Continuations in Scala?

Stefan Matthias Aust
I wonder whether there's a way to express web continuations in Scala
similar to how it works in PLT-Scheme.  This is the code I'd image:

  abstract class Servlet {
    def start(req: Request): Response
    def sendAndSuspend(f: String => Response): Request = {
      ...
    }
    ...
  }
  case class Response(xml: xml.Elem)
  case class Request { def parameter(name: String): String = ... }

Using this mini framework, I can do:

  /** No continuations here; this demonstrates the servlet abstraction */
  class OnePage extends Servlet {
    def start(req: Request): Response = {
      Response(<html>...<h1>Hello</h1>...</html>)
    }
  }

  /** sendAndSuspend contains the continuation, sending the first
   * response to the browser after including an URL that will be
   * recognised on the next request and the control flow will resume */
  class TwoPages extends Servlet {
    def start(req: Request): Response = {
      val req = sendAndSuspend(kUrl =>
        Response(<html>...
          <a href="{kUrl + "?link=1"}">Link 1</a>
          <a href="{kUrl + "?link=2"}">Link 2</a>
          ...</html>))
      Response(<html>...
        <p>You chose Link {req.parameter("link")}</p>
        ...</html>)
    }
  }

And the classical "let's add two numbers for the most complex and
unnaturla way just to show the power of continuations"  example:

  class AddEx extends Servlet {
    def start(req: Request): Response = {
      webPrint("Ergebnis", webRead("Eins") + webRead("Zwei"))
    }

    private def webRead(prompt: String): Int = {
      val req = sendAndSuspend(kUrl =>
        Response(<html>...<form action="{kUrl}"><input name="v">...))
      req.parameter("v").toInt
    }

    private def webPrint(prompt: String, value: Int) = {
      Response(<html>...<h1>{prompt}</h1><p>{value}</p>...</html>)
    }
  }

I think, it's impossible to have "true" continuations in Scala because
neither Java nor the JVM can express them but I thought: Better ask the
experts :)

I've the vague feeling that continuations and monads have something in
common and perhaps one can at least simulate them using exceptions (but
escape continuations are not enough for web apps) and/or closures or
whatever...

--
Stefan Matthias Aust

Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Jamie Webb-3
On Fri, Apr 21, 2006 at 11:43:59AM +0200, Stefan Matthias Aust wrote:
> I think, it's impossible to have "true" continuations in Scala because
> neither Java nor the JVM can express them but I thought: Better ask the
> experts :)
>
> I've the vague feeling that continuations and monads have something in
> common and perhaps one can at least simulate them using exceptions (but
> escape continuations are not enough for web apps) and/or closures or
> whatever...

Your 'sendAndSuspend' primitive is not possible in Scala, because as
you say, there is no way in Java to do a call/cc. But you are right
about monads. Essentially the monad bind operator gives you a way to
store your entire computation in a data structure (just treat it like
the cons operator on lists), and then execute it piece by piece.

We are working on a web framework which incorporates a similar concept
called arrows (http://www.haskell.org/arrows/). With luck we should
have something ready for release in the summer.

-- Jamie Webb
Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Burak Emir
Hello Stefan, Jamie

Jamie Webb wrote:

>On Fri, Apr 21, 2006 at 11:43:59AM +0200, Stefan Matthias Aust wrote:
>  
>
>>I think, it's impossible to have "true" continuations in Scala because
>>neither Java nor the JVM can express them but I thought: Better ask the
>>experts :)
>>
>>    
>>
Who needs "true" continuations when one can have fake ones? : )

you might want to check out the new Scala2 standard library class
"scala.Continuation" :-)

And also, a quite old writeup (I should mention that this is also based
on previous work by Michel Schinz).
http://lamp.epfl.ch/~emir/bqbase/2005/01/20/monad.html
Here a proof that continuations satisfy the "monad laws"
http://lamp.epfl.ch/~emir/bqbase/2005/01/27/continuation_monad.html

>>I've the vague feeling that continuations and monads have something in
>>common and perhaps one can at least simulate them using exceptions (but
>>escape continuations are not enough for web apps) and/or closures or
>>whatever...
>>    
>>
>
>Your 'sendAndSuspend' primitive is not possible in Scala, because as
>you say, there is no way in Java to do a call/cc. But you are right
>  
>
Not so. You can have a sort of fake continuation using monads, and it
looks as if it were a real one because of for-comprehension syntax.

>about monads. Essentially the monad bind operator gives you a way to
>store your entire computation in a data structure (just treat it like
>the cons operator on lists), and then execute it piece by piece.
>
>  
>
...and you can even write it in a style that is reminiscent of call/cc
trickery.

An extract of Florian Hof's master thesis:===
Thanks to this project, one could write this web application in Scala in
a pleasant way:
for (
val firstname <- printAndWait ("Give your first name");
val lastname <- printAndWait ("Give your last name");
val _ <- printAndStop ("Hello "+firstname+" "+lastname+"!")
) {null}
===
You should write to him and ask whether he wants to give out his report.

When the project finished (recently), Martin discovered that there is
slightly more elegant way to get these fake continuations and wrote what
is now in the library. We used that new formulation successfully to get
fake coroutines.

My highest-priority task right now should be to get this rewritten in
order to use the new library class scala.Continuation, update our
repository to incorporate Florian's changes to smotor (our homegrown
servlet container), then package everything up and have it released. The
nice thing is that the WebCont framework seems to be independent of
smotor, so it should be possible to use the whole thing with Tomcat.

>We are working on a web framework which incorporates a similar concept
>called arrows (http://www.haskell.org/arrows/). With luck we should
>have something ready for release in the summer.
>
>  
>
Arrows should go a level beyond the monad interface, but with the
drawback that you won't be using Scala's for-comprehension syntax.
Looking forward to it, that also looks like it could get some fresh
inspirations for the way UI programming is handled, isn't it?

cheers,
Burak

--
Burak Emir

http://lamp.epfl.ch/~emir

Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Stefan Matthias Aust
Burak Emir schrieb:

> Who needs "true" continuations when one can have fake ones? : )

I hoped for such a response :)

> you might want to check out the new Scala2 standard library class
> "scala.Continuation" :-)

Would love to, but where do I find it?

> Thanks to this project, one could write this web application in Scala in
> a pleasant way:
> for (
> val firstname <- printAndWait ("Give your first name");
> val lastname <- printAndWait ("Give your last name");
> val _ <- printAndStop ("Hello "+firstname+" "+lastname+"!")
> ) {null}

Well, personally, I don't find for comprehension that pleasant to read
because it always looks like misuse, but it's better than nothing.

> My highest-priority task right now should be to get this rewritten in
> order to use the new library class scala.Continuation, update our
> repository to incorporate Florian's changes to smotor (our homegrown
> servlet container), then package everything up and have it released. The
> nice thing is that the WebCont framework seems to be independent of
> smotor, so it should be possible to use the whole thing with Tomcat.

Sound good...

--
Stefan Matthias Aust

Reply | Threaded
Open this post in threaded view
|

scala.Responder, was Re: Continuations in Scala?

Burak Emir
Hi there,

Stefan Matthias Aust wrote:

>> you might want to check out the new Scala2 standard library class
>> "scala.Continuation" :-)
>
>
> Would love to, but where do I find it?
>
Excuse me, after looking for it for a while and deciding that I should
rewrite it, I remembered that the class is called "Responder".

http://scalasvn.epfl.ch/cgi-bin/viewvc.cgi/scala/trunk/src/library/scala/Responder.scala?view=markup

I am hacking the doc for Responder into the wiki right now, you can
already have a look http://scala.sygneca.com//libs/responder it has your
"add two numbers" example.

[for-comprehensions example]

>
> Well, personally, I don't find for comprehension that pleasant to read
> because it always looks like misuse, but it's better than nothing.
>
It's slightly better with Responders, see above

>> My highest-priority task right now should be to get this rewritten in
>> order to use the new library class scala.Continuation, update our
>> repository to incorporate Florian's changes to smotor (our homegrown
>> servlet container), then package everything up and have it released.
>> The nice thing is that the WebCont framework seems to be independent
>> of smotor, so it should be possible to use the whole thing with Tomcat.
>
>
> Sound good...
>
: ) you ain't seen nothing yet, that's only the beginning

cheers,
Burak

--
Burak Emir

http://lamp.epfl.ch/~emir

Reply | Threaded
Open this post in threaded view
|

webcont package shared Re: scala.Responder, was Re: Continuations in Scala?

Burak Emir
[talk about continuations web etc]
Burak Emir wrote:

>>> My highest-priority task right now should be to get this rewritten
>>> in order to use the new library class scala.Continuation, update our
>>> repository to incorporate Florian's changes to smotor (our homegrown
>>> servlet container), then package everything up and have it released.
>>> The nice thing is that the WebCont framework seems to be independent
>>> of smotor, so it should be possible to use the whole thing with Tomcat.
>>
>>
In the end, I will do the rewriting later, as there is some discrepancy
between the plain continuation monad and what is going on in webcont.
Anyway, the stuff is installable via sbaz and the sources accessible via
subversion. Enjoy!

cheers,
Burak
Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Florian Hof
In reply to this post by Burak Emir
Hello Stefan,

As Burak has said, I have made my master project on Continuations in
Scala, aims to make web applications easier to write. The goal was to
show that it was possible. The implementation prove it, even if it is
not ready for a productive use.

As you have guessed, I have used closures instead of real
continuations, but it's sufficient and is actually exactly what we
need. The idea of my framework is similar to your small example.

To get rid of lots of nested closures, the for comprehension has been
used. It's more pleasant to read, but perhaps confusing. See it as a
loop over all the web user's request (even if it has nothing to do with
a loop!).

The implementation uses smotor as a servlet engine. It is modular so as
to be usable with other servlet engine, like tomcat. Just add the
mapping between tomcat and web application that uses my framework. The
types are also abstract, so has to respond a text or an XML (or a more
complex HTTP response, if you want to).

The report of my master thesis is available here:
     http://lamppc1s1.epfl.ch/~hof/report.pdf
And its associated framework, including some examples and smotor:
     http://lamppc1s1.epfl.ch/~hof/webcont.tgz

Florian

Le 21 avr. 06, à 17:26, Burak Emir a écrit :

> Hello Stefan, Jamie
>
> Jamie Webb wrote:
>
>> On Fri, Apr 21, 2006 at 11:43:59AM +0200, Stefan Matthias Aust wrote:
>>
>>> I think, it's impossible to have "true" continuations in Scala
>>> because neither Java nor the JVM can express them but I thought:
>>> Better ask the experts :)
>>>
>>>
> Who needs "true" continuations when one can have fake ones? : )
>
> you might want to check out the new Scala2 standard library class
> "scala.Continuation" :-)
>
> And also, a quite old writeup (I should mention that this is also
> based on previous work by Michel Schinz).
> http://lamp.epfl.ch/~emir/bqbase/2005/01/20/monad.html
> Here a proof that continuations satisfy the "monad laws"
> http://lamp.epfl.ch/~emir/bqbase/2005/01/27/continuation_monad.html
>
>>> I've the vague feeling that continuations and monads have something
>>> in common and perhaps one can at least simulate them using
>>> exceptions (but escape continuations are not enough for web apps)
>>> and/or closures or whatever...
>>>
>>
>> Your 'sendAndSuspend' primitive is not possible in Scala, because as
>> you say, there is no way in Java to do a call/cc. But you are right
>>
> Not so. You can have a sort of fake continuation using monads, and it
> looks as if it were a real one because of for-comprehension syntax.
>
>> about monads. Essentially the monad bind operator gives you a way to
>> store your entire computation in a data structure (just treat it like
>> the cons operator on lists), and then execute it piece by piece.
>>
>>
> ...and you can even write it in a style that is reminiscent of call/cc
> trickery.
>
> An extract of Florian Hof's master thesis:===
> Thanks to this project, one could write this web application in Scala
> in a pleasant way:
> for (
> val firstname <- printAndWait ("Give your first name");
> val lastname <- printAndWait ("Give your last name");
> val _ <- printAndStop ("Hello "+firstname+" "+lastname+"!")
> ) {null}
> ===
> You should write to him and ask whether he wants to give out his
> report.
>
> When the project finished (recently), Martin discovered that there is
> slightly more elegant way to get these fake continuations and wrote
> what is now in the library. We used that new formulation successfully
> to get fake coroutines.
>
> My highest-priority task right now should be to get this rewritten in
> order to use the new library class scala.Continuation, update our
> repository to incorporate Florian's changes to smotor (our homegrown
> servlet container), then package everything up and have it released.
> The nice thing is that the WebCont framework seems to be independent
> of smotor, so it should be possible to use the whole thing with
> Tomcat.
>
>> We are working on a web framework which incorporates a similar concept
>> called arrows (http://www.haskell.org/arrows/). With luck we should
>> have something ready for release in the summer.
>>
>>
> Arrows should go a level beyond the monad interface, but with the
> drawback that you won't be using Scala's for-comprehension syntax.
> Looking forward to it, that also looks like it could get some fresh
> inspirations for the way UI programming is handled, isn't it?
>
> cheers,
> Burak
>
> --
> Burak Emir
>
> http://lamp.epfl.ch/~emir
>

Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Stefan Matthias Aust
Florian,

Florian Hof schrieb:

> As you have guessed, I have used closures instead of real continuations,
> but it's sufficient and is actually exactly what we need. The idea of my
> framework is similar to your small example.

Thanks for sharing this. Being somewhat ill, I finally had the time to
read your thesis. Quite interesting and well written (understandable
even with mild flu ;) but also quite tricky.

Perhaps too tricky. I'm not sure.

You wrote that it would be very interesting to measure performance data
which was out of scope for your work. You probably meant runtime
performance data (speed, memory) but I think, even more interesting
would be to measure "developer performance". Does this approach has
measurable advantages over the "traditional" approach?

I've no good idea how to measure this, though.

For quite some time, I'm trying to come up with some interesting pet
project or some class of problems where continuations might really save
time and effort - compared to let's say a decent agile web framework
like Rails. My fear is that the "sum of all problems" is more or less
constant - but I'd love to be proven wrong.

While complex interactions are easier to express with continuation style
- simple control flow is not. The question is, which kind of interaction
is the major type of interaction...

Just think of a typical blogging application where you probably find no
complex interaction but would want to have nice, easily bookmarkable
pages. Even the admin stuff consists only of simple "choose function
from menu, fill out form, save data, goto menu" control flows.

And then there's "session" and memory management. How and when to remove
stored continuations?  In the "Continue-Server" paper, the authors wrote
that they never invalidated any continuation and because the server had
to run only for a short period of time - a few weeks IIRC - and had only
a few users (I assume a dozen or so) it grow only to 150MB which is no
problem on today's computers. I wouldn't want to let such an application
into the cruel widths of the internet, though.

The Seaside-guy also wrote about the problem that you have to be very
careful not to serialize your complete application every time.  In
Smalltalk, every class reference will link back to Object class and this
will link to all other classes, all other methods and there's a high
chance that some class or method will finally refer to Smalltalk, the
dictionary for all globals and if you try to serialise this, you've got
the whole image...

Perhaps something like a web based strategy game could take more
advantage of continuations.  I'm not really good at inventing games (I
wish I would) but for starters, something like this very old startrek
game (http://www.cactus.org/~nystrom/startrek.html) might be something
worth to test...


I've one question regarding your framework.

What would be the implementation of printAndWait and printAndStop for
WebLogic?  These functions seem to be not part of the general framework
but are only available for the console simulation.  These are however
the primitives, I'm interested in most.

You probably need also something like send/suspend/dispatch in
PLT-Scheme (or Seaside which always automatically dispatches registered
callbacks), which is an extension of send/suspend a.k.a printAndWait. I
assume that you can simulate it with a switch function.

Regards,

--
Stefan Matthias Aust

Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Florian Hof
Le 2 mai 06, à 11:38, Stefan Matthias Aust a écrit :

> Florian,
>
> Florian Hof schrieb:
>
>> As you have guessed, I have used closures instead of real
>> continuations, but it's sufficient and is actually exactly what we
>> need. The idea of my framework is similar to your small example.
>
> Thanks for sharing this. Being somewhat ill, I finally had the time to
> read your thesis. Quite interesting and well written (understandable
> even with mild flu ;) but also quite tricky.
>
> Perhaps too tricky. I'm not sure.
>
> You wrote that it would be very interesting to measure performance
> data which was out of scope for your work. You probably meant runtime
> performance data (speed, memory) but I think, even more interesting
> would be to measure "developer performance". Does this approach has
> measurable advantages over the "traditional" approach?

I meant runtime performance data. It would be a constraint for an
effective use.
I have not spoken about "developer performance", but I see it related
to convenience (for web developers). The project is focused on
developers.

Developer performance is difficult to measure. An easier measure,
although not perfect, could be the length of sources. I expect sources
to be smaller, whereas the "complexity of each line" (for programers)
does not increase, so the whole complexity would be smaller, thus
quicker to develop. Just an idea, not a formal proof ...

For code length, I'm happy with my example of a (really basic) wiki
dictionary which is less than 400 lines, including a lots of comments.
See my sources for details (link given in my previous post).

>
> I've no good idea how to measure this, though.
>
> For quite some time, I'm trying to come up with some interesting pet
> project or some class of problems where continuations might really
> save time and effort - compared to let's say a decent agile web
> framework like Rails. My fear is that the "sum of all problems" is
> more or less constant - but I'd love to be proven wrong.
>
> While complex interactions are easier to express with continuation
> style - simple control flow is not. The question is, which kind of
> interaction is the major type of interaction...
>
> Just think of a typical blogging application where you probably find
> no complex interaction but would want to have nice, easily
> bookmarkable pages. Even the admin stuff consists only of simple
> "choose function from menu, fill out form, save data, goto menu"
> control flows.

When the state does not mind, as reading a blog, then continuations are
not necessary and an overhead for the server. For the admin stuff,
continuations are useful, at least for the step "fill out form, save
data". Printing the menu does not requires continuations, because no
data are passed (or perhaps the login is remembered, in this case
continuations can still helps).

An idea would be to combine continuations with other traditional helps
for web applications (such as session, etc), depending on the need of
each step of an application. But it could result in a complicated
framework, not convenient for developers.

> And then there's "session" and memory management. How and when to
> remove stored continuations?  In the "Continue-Server" paper, the
> authors wrote that they never invalidated any continuation and because
> the server had to run only for a short period of time - a few weeks
> IIRC - and had only a few users (I assume a dozen or so) it grow only
> to 150MB which is no problem on today's computers. I wouldn't want to
> let such an application into the cruel widths of the internet, though.

Neither would I, too.

> The Seaside-guy also wrote about the problem that you have to be very
> careful not to serialize your complete application every time.  In
> Smalltalk, every class reference will link back to Object class and
> this will link to all other classes, all other methods and there's a
> high chance that some class or method will finally refer to Smalltalk,
> the dictionary for all globals and if you try to serialise this,
> you've got the whole image...

Serializing everything is almost what happens in my implementation. It
is difficult to serialize only the relevant things, and also make
something convenient for developers.

> Perhaps something like a web based strategy game could take more
> advantage of continuations.  I'm not really good at inventing games (I
> wish I would) but for starters, something like this very old startrek
> game (http://www.cactus.org/~nystrom/startrek.html) might be something
> worth to test...
>
>
> I've one question regarding your framework.
>
> What would be the implementation of printAndWait and printAndStop for
> WebLogic?  These functions seem to be not part of the general
> framework but are only available for the console simulation.  These
> are however the primitives, I'm interested in most.

Actually, printAndWait and printAndStop are only used for console
simulation. WebLogic only uses print, which can see as a printAndWait.
The reason is that, in web applications, the user decides to go on or
not with a new request, whereas in console applications, the
application decides to ask something to the user or not. In web
applications, the replacement of printAndStop is also print, but no
links nor forms permit to go on with a continuation, and I set the
closure to null. I agree this is not very clear ...


> You probably need also something like send/suspend/dispatch in
> PLT-Scheme (or Seaside which always automatically dispatches
> registered callbacks), which is an extension of send/suspend a.k.a
> printAndWait. I assume that you can simulate it with a switch
> function.

I'm not sure to understand correctly, but a dispatch can be made with a
switch (several if-then-else or pattern matching). I use it in the wiki
dictionary example: when a request occurs, I first check if the user
requests a general feature (login, logout, go home), then I go on with
the normal flow of the application. The implementation is done easily
inside the example, there is no support from the framework (apart from
the 'call' method).

Florian

Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Stefan Matthias Aust
Florian Hof schrieb:

> I have not spoken about "developer performance", but I see it related to
> convenience (for web developers). The project is focused on developers.

Yes, I know that you didn't take about "developer performance". I wanted
to mention that I consider this the more important factor.  Faster
machine are usually quite affordable.  And if there are no faster
machine, just add more. Web applications typically scale very well.

However, you can't "scale" developers by just adding more :)

> Developer performance is difficult to measure.

Indeed.

> An easier measure, although not perfect, could be the length of sources.

Well yes.  Once you have code, the application is the easier to
understand the less you have to read.  Unfortunately, for initial
writing, this mostly measures "typing speed".

A better metric would be the time you need from the problem to your
first solution, that is the time required to express you ideas with
code.  This is incredibly hard to measure and very dependent on the
individual developer.

Still, I think, the language and its paradigm can affect this time.

> For code length, I'm happy with my example of a (really basic) wiki
> dictionary which is less than 400 lines, including a lots of comments.
> See my sources for details (link given in my previous post).

Well, used to "old school" web application, I find that application very
difficult to understand.  You basically dispatch commands in the
for-loop of start(), just as you'd do without continuations. There's
preprocess() which seems to deal with authentication but then, it also
lists the word - why isn't the main loop in start() dealing with that
command? All these nested ifs in logIn are also difficult to grasp. It
is not clear to me why you need to call preprocess() from inside the
logIn() function.  Don't get me wrong, you code isn't bad, it's just,
that I don't find it obvious.

I started to look into MzScheme recently. Using continuations I'd
probably setup the program structure for a Wiki like this:

  - a view-page function displays the given page and has links bound
    to other functions for edit-page and delete-page. This is done by
    MzScheme's send/suspend/callback function which does a nice implicit
    dispatch:

  (define (show-page id request)
    (send/suspend/callback
      `(html
       (head (title "View " ,id))
        (body (h1 ,id)
              (p ,(wikify id))
              (p
               (a ((href ,(λ (r) (edit-page id r)))) edit)
               (a ((href ,(λ (r) (delete-page id r)))) delete)))))))

  - the wikify function gets the text and replaces wiki words with links.
    I don't know enough Scheme to implement the replacement, but it
    should look like this:

  (define (wikify id)
    `(p ,@(for-each-word (λ (w) (if (wiki-word? w) (as-link w) w))
                         (hash-table-get *pages* id)))

  (define (as-link w)
    `(a ((href ,(λ (r) (view-page w r)))) ,w))

    If "λ" looks strange, please note it's a lambda your client cannot
    display correctly. I don't know whether my ad-hoc-currying can be
    improved. I googled a bit and it seems, one can write

     (cut edit-page w <>)

    instead of

     (λ (r) (edit-page w r))

  - the edit-page function displays a textarea form, send/suspends it
    and stores the updated page and calls view-page again. The function
    send/suspend/return is my invention - it extracts the given parameter
    from the request and helps to keep this short. I omitted the HTML:

  (define (edit-page id request)
    (hash-table-put! *pages* id (send/suspend/return 'name ...))
    (show-page id)))

  - the delete-page function, which shall ask for for confirmation (just
    to demonstrate a "modal" call), could look like this:

  (define (delete-page id request)
    (if (confirm `(p "Delete " id "?"))
      (begin
       (hash-table-remove! *pages* id)
       (show-page "Home"))
      (show-page id)))

    the following function will display the prompt and a form with two
    buttons named ok and cancel and will return #t if ok was pressed.

  (define (confirm prompt)
    (not (string=? "" (send-suspend/return 'ok ...))))

(Oops, that digression became longer than expected ;)

I never needed to use explicit dispatch. I circumvented login because
I've no clever idea how to put this into the framework but still having
all flexibility.  For my last (old-school) application I used an aspect
oriented approach which worked quite nicely.


> When the state does not mind, as reading a blog, then continuations are
> not necessary and an overhead for the server. For the admin stuff,
> continuations are useful, at least for the step "fill out form, save
> data".

Sure, but is it worth the effort?  From my wiki example above, I'd begin
to say "yes", because that wiki also really doesn't require continutions
to become easier to implement and understand, but at least, it wasn't
more difficult either.  And the delete confirmation is something, I'd
have otherwise omitted - too much work if you need to keep track of the
continuation yourself.

> An idea would be to combine continuations with other traditional helps
> for web applications (such as session, etc), depending on the need of
> each step of an application. But it could result in a complicated
> framework, not convenient for developers.

Have you looked at Seaside?  It tries to mix continuation and a
traditional component based framework and is quite successful.

>> What would be the implementation of printAndWait and printAndStop for
>> WebLogic?  These functions seem to be not part of the general
>> framework but are only available for the console simulation.  These
>> are however the primitives, I'm interested in most.
>
> Actually, printAndWait and printAndStop are only used for console
> simulation. WebLogic only uses print, which can see as a printAndWait.

Oh, I see.  Does this mean, that I always need two lines to first print
(and wait) a form and then extract lets say an integer from that form?
Something like this:

  for (
   val form1 <- print(read("number 1"))
   val    i1 <- Integer.parseInt(form1("n"))
   val form2 <- print(read("number 2"))
   val    i2 <- Integer.parseInt(form2("n"))
  ) result(i1 + i2)

(read and result being two functions generating the HTML)

I think, I cannot use

  val i1 <- readInt("number1")

directly because that breaks the emulated closure. ReadInt might look like:

  def readInt(prompt: String) =
    Integer.parseInt(print(read(prompt))("n"))

Knowing, that for applies map, I might be able to use that call in the
readInt method, but that leads to unreadable code, IMHO.

>> You probably need also something like send/suspend/dispatch in
>> PLT-Scheme (or Seaside which always automatically dispatches
>> registered callbacks), which is an extension of send/suspend a.k.a
>> printAndWait. I assume that you can simulate it with a switch function.
>
> I'm not sure to understand correctly, but a dispatch can be made with a
> switch (several if-then-else or pattern matching).

Yes, but that's an explicit map.  Scheme uses an implicit dispatch. All
you have to do it embedding function object into the HTML template and
the framework does the rest.

Besides being shorter and easier to read, it also removes the
requirement to use strings as command identifiers.

Regards,

--
Stefan Matthias Aust

Reply | Threaded
Open this post in threaded view
|

Re: Continuations in Scala?

Florian Hof
> Still, I think, the language and its paradigm can affect this time.

Of course, otherwise let's write web applications in Fortran.

>> For code length, I'm happy with my example of a (really basic) wiki
>> dictionary which is less than 400 lines, including a lots of
>> comments. See my sources for details (link given in my previous
>> post).
>
> Well, used to "old school" web application, I find that application
> very difficult to understand.  You basically dispatch commands in the
> for-loop of start(), just as you'd do without continuations. There's
> preprocess() which seems to deal with authentication but then, it also
> lists the word - why isn't the main loop in start() dealing with that
> command? All these nested ifs in logIn are also difficult to grasp. It
> is not clear to me why you need to call preprocess() from inside the
> logIn() function.  Don't get me wrong, you code isn't bad, it's just,
> that I don't find it obvious.

Effectively, the idea is that there is one continuation for each HTML
page (because there is only one execution state at the page's
creation).  The drawback is that you have to handle all possible links,
including "global" ones likes "home" and "login". The last idea (see
below) would offer a better approach. But it moves away from the
concept of continuation.

> Have you looked at Seaside?  It tries to mix continuation and a
> traditional component based framework and is quite successful.

I have only looked what it is for, not how to develop with it.

> Oh, I see.  Does this mean, that I always need two lines to first
> print (and wait) a form and then extract lets say an integer from that
> form? Something like this:
>
>  for (
>   val form1 <- print(read("number 1"))
>   val    i1 <- Integer.parseInt(form1("n"))
>   val form2 <- print(read("number 2"))
>   val    i2 <- Integer.parseInt(form2("n"))
>  ) result(i1 + i2)
>
> (read and result being two functions generating the HTML)

Effectively, this is what I suggest.

> I think, I cannot use
>
>  val i1 <- readInt("number1")
>
> directly because that breaks the emulated closure. ReadInt might look
> like:
>
>  def readInt(prompt: String) =
>    Integer.parseInt(print(read(prompt))("n"))

I have not thought about this, because I rely on one type for (web)
request and one for (html) response. You can write a MyLogic class with
type Int as request and HTML as response. This should be easy. Another
possibility would be to implement readInt in the same way as print (why
not with a type parameter), including the type conversion. I think it
would be a bad design, unless the readInt function is really general
(that is, not only related to Int). And what to do if the user does not
enter an integer?

> Yes, but that's an explicit map.  Scheme uses an implicit dispatch.
> All you have to do it embedding function object into the HTML template
> and the framework does the rest.

Perhaps it would be possible in Scala, because you can include
statements in XML, and defining a high-order function that takes a
closure, remembers it, and generates an XML link to access it.

Interesting idea for the Scala team ... because I'm no more on this
project.

Regards,
Florian