on script-shipping and "send/suspend/callback" using staged code instead of first-class continuations?

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

on script-shipping and "send/suspend/callback" using staged code instead of first-class continuations?

Burak Emir
Hi there,

mzscheme's "send/suspend/callback" emerged on the wishlist for scala web app
development.

Let me try to summarize. Some languages tweak control-flow in a similar manner
to Scala's webcont

* Scheme is the language where all the continuation business started
* Seaside is the SmallTalk version of the continuation dance

But they use first-class continuations and don't live in the statically strongly
typed Scala world. The Scala webcont library/framework lives in this world, and
its main goal was to make *straight line programs* fit for web apps. It's in its
early stages but already has a proof of concept that it works.

Now here's Stefans code again to see what is missing (all very close to what is
on the agenda for Links)

(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)))))))

Points to remember:
* there is *staged code* in the markup, which is to be executed when the user
clicks.
* such code can only ever appear in <a href=" "> -- this has its problems, which
I want to discuss later.
* the sequence of actions could be described as follows:
1) when running "show-page", the server has to build continuations for
"edit-page" and "delete-page" and store them somewhere.
2) when the user clicks the link, it has to retrieve the continuation from that
somewhere and resume it.

Fortunately, Scala is able to handle staged code, and it's XML literals have at
some point been tweaked with the ability to add arbitrary objects.

I can thus imagine some markup like this

<a href={ editPage(): Code[unit] }>edit this page</a>

(staged code means it is left symbolic) and refine the server actions to the
following

1a) the server invokes show-page and obtains the markup with the *staged* code.
1b) for each staged code bit it encounters, it constructs the appropriate
continuation, stores it somewhere and fills in the href-string.

This looks very promising. There are some rough edges:

* It relies on some interpreter or compiler facility to do something with the
staged code. Since scheme is interpreted anyway there is no big difference
between the first class continuations and the program source, but in Scala we
have to do something extra.

This extra bit might be quite different from walking the entire "stage and
interpret" path I described above, but it needs to produce the same effect. If
the staged code is an expression, it might be compiled ahead of time, for
instance.

* the big probem I see is with the "old style". I want my web applications to
rely on client-side scripting for validation etc. so it might happen that the
stuff in the href is some JavaScript code, which after doing a lot of messy
things finally gets itself together to call back the server. What now? How to
export e.g. some JavaScript variable back to my Scala server program?

My personal conclusion is that all of the above is worth trying and doing, and
that at the same time the ideal solution seems to require a far more substantial
change to language semantics than what you get even with an interpreted language
and first-class continuations.

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

Re: on script-shipping and "send/suspend/callback" using staged code instead of first-class continuations?

Jamie Webb-3
On Sun, May 07, 2006 at 02:45:41PM +0200, [hidden email] wrote:

> I can thus imagine some markup like this
>
> <a href={ editPage(): Code[unit] }>edit this page</a>
>
> (staged code means it is left symbolic) and refine the server actions to the
> following
>
> 1a) the server invokes show-page and obtains the markup with the *staged* code.
> 1b) for each staged code bit it encounters, it constructs the appropriate
> continuation, stores it somewhere and fills in the href-string.

Why go to all that trouble? Given a function:

def store(f : Request => Node) : String = {
        // Save f for later and return a unique URL for it
}

We can write:

<a href={ store(r => editPage(id, r)) }>edit</a>

Job done.

Having said that, I don't think this design is a good idea, or rather
that the marginal programming elegance it affords comes at a high
price which is very rarely worth paying. It introduces a lot of
unnecessary server-side state which clobbers application scalability,
subjects the user to annoying timeouts, makes URLs non-memorable,
non-bookmarkable and unfriendly to Google, and causes redeployment
headaches.

It seems to me that the vast majority of web applications can and
should be written to be largely stateless, and that cookies and/or
sessions are quite adequate for much of the state that is required.

There are of course cases where pages do run in sequence with state
being passed between them, obvious examples being signup and checkout
processes, and these are exactly the cases favoured by the monadic
continuations Florian describes.

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

Re: on script-shipping and "send/suspend/callback" using staged code instead of first-class continuations?

Lex Spoon
Jamie Webb <[hidden email]> writes:

> > 1b) for each staged code bit it encounters, it constructs the appropriate
> > continuation, stores it somewhere and fills in the href-string.
>
> Why go to all that trouble? Given a function:
>
> def store(f : Request => Node) : String = {
> // Save f for later and return a unique URL for it
> }
>
> We can write:
>
> <a href={ store(r => editPage(id, r)) }>edit</a>

Yes, this store() function for registering a callback sounds like a
simple place to start along the way to trying more exotic things.
Then you can use the facility however much seems appropriate for your
application.


Incidentally, I do not understand the emphasis on staged code.
Seaside does not use it in the examples I have read, and the `(...)
format of Scheme is actually desugared at compile time.  For example,
this:

    '(p ,(wikify id))

desugars into this:

    (list 'p (wikify id))

The Scala equivalent would be  <p> {wikify(id)} </p> .  It
does not even use higher-order functions, much less a run-time
representation of code.

Not to say staged code does not have uses for web frameworks -- I look
forward to seeing what Burak is hinting at in this area!  I
just want to point out that dynamic languages do not use staged code
as much as you might expect.  Even when you have nukes available,
sometimes a hammer is enough.

Lex

Reply | Threaded
Open this post in threaded view
|

Re: on script-shipping and "send/suspend/callback" using staged code instead of first-class continuations?

Burak Emir
In reply to this post by Jamie Webb-3
Jamie Webb wrote:

>On Sun, May 07, 2006 at 02:45:41PM +0200, [hidden email] wrote:
>  
>
>>I can thus imagine some markup like this
>>
>><a href={ editPage(): Code[unit] }>edit this page</a>
>>
>>(staged code means it is left symbolic) and refine the server actions to the
>>following
>>
>>1a) the server invokes show-page and obtains the markup with the *staged* code.
>>1b) for each staged code bit it encounters, it constructs the appropriate
>>continuation, stores it somewhere and fills in the href-string.
>>    
>>
>
>Why go to all that trouble? Given a function:
>
>def store(f : Request => Node) : String = {
> // Save f for later and return a unique URL for it
>}
>
>We can write:
>
><a href={ store(r => editPage(id, r)) }>edit</a>
>
>Job done.
>  
>
You are right, actually, I meant something else. "Continuation" as rest
of the program as source and *not* as code.

If I have a dictionary index with say 1000 entries, I sure enough don't
want to create 1000 continuations in the form of closures stored somewhere.

But my pie-in-the-sky staging framework would not need to do that. It
what just send those embedded code bits.

1b) for each staged *source* code bit it encounters, it stores it in the
page/cookie/somewhere. The href is then filled with some javascript that
fills in the "loading" code plus some input data from a form if
necessary, and ships the whole thing back so it gets executed.

>Having said that, I don't think this design is a good idea, or rather
>that the marginal programming elegance it affords comes at a high
>price which is very rarely worth paying. It introduces a lot of
>unnecessary server-side state which clobbers application scalability,
>  
>
^this one would be avoided

>subjects the user to annoying timeouts, makes URLs non-memorable,
>  
>
^timeouts avoided, ^URLs might be non-memorable but pages could be
("store this page" button which makes sure all info is written).

>non-bookmarkable and unfriendly to Google, and causes redeployment
>  
>
Google should index data, and I agree that for data this doesn't seem
all to interesting. But for "application" links (update-forms) it might
make things easier.

>headaches.
>  
>


>It seems to me that the vast majority of web applications can and
>should be written to be largely stateless, and that cookies and/or
>sessions are quite adequate for much of the state that is required.
>
>  
>
I'd agree mostly
...but I'd think that there must be more ways to change the state of the
client then following a link. The whole AJAX thing and all.

cheers,
Burak

--
Burak Emir

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

Reply | Threaded
Open this post in threaded view
|

Re: on script-shipping and "send/suspend/callback" using staged code instead of first-class continuations?

Burak Emir
In reply to this post by Lex Spoon
Lex Spoon wrote:

>Jamie Webb <[hidden email]> writes:
>  
>
>>>1b) for each staged code bit it encounters, it constructs the appropriate
>>>continuation, stores it somewhere and fills in the href-string.
>>>      
>>>
>>Why go to all that trouble? Given a function:
>>
>>def store(f : Request => Node) : String = {
>> // Save f for later and return a unique URL for it
>>}
>>
>>We can write:
>>
>><a href={ store(r => editPage(id, r)) }>edit</a>
>>    
>>
>
>Yes, this store() function for registering a callback sounds like a
>simple place to start along the way to trying more exotic things.
>Then you can use the facility however much seems appropriate for your
>application.
>
>  
>
see my mail before.

>Incidentally, I do not understand the emphasis on staged code.
>Seaside does not use it in the examples I have read, and the `(...)
>format of Scheme is actually desugared at compile time.  For example,
>this:
>
>    '(p ,(wikify id))
>
>desugars into this:
>
>    (list 'p (wikify id))
>
>The Scala equivalent would be  <p> {wikify(id)} </p> .  It
>  
>
No, this is precisely not what I want for some code that is "in" a link.
I want it to be left symbolic so I can worry about it later.

>does not even use higher-order functions, much less a run-time
>representation of code.
>
>Not to say staged code does not have uses for web frameworks -- I look
>forward to seeing what Burak is hinting at in this area!  I
>just want to point out that dynamic languages do not use staged code
>as much as you might expect.  Even when you have nukes available,
>sometimes a hammer is enough.
>  
>
I (half-knowingly) confused the continuation bit -- the code in the <a
href="..."> -- because it's easy to get continuations with staged code.
Remember we don't have first-class continuation, and we will probably
never have them on the VM. But not only do we already have our "fake"
continuations that are implemented by closures, we also have a
reasonable chance of getting staged code. You don't get hammers in a
weapon shop :-)

cheers,
Burak

--
Burak Emir

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

Reply | Threaded
Open this post in threaded view
|

New version of overview paper

Martin Odersky
In reply to this post by Jamie Webb-3
By an unfortunate slip, the paper

   An Overview of the Scala Programming Language

was not updated on the web site. Until now, the paper referred to the
old version of the language. So anyone trying to learn the second
version of the language from this paper must have had some surprises!

We have corrected this now. The new, updated version of the paper is
found at the same place at the old -- it is the first entry on

   http://scala.epfl.ch/docu/index.html

Cheers

  -- Martin
Reply | Threaded
Open this post in threaded view
|

Re: New version of overview paper

Stéphane Micheloud
Did you try to clear the cache of your web brower ?!


--Stephane

Martin Odersky wrote:

> By an unfortunate slip, the paper
>
>   An Overview of the Scala Programming Language
>
> was not updated on the web site. Until now, the paper referred to the
> old version of the language. So anyone trying to learn the second
> version of the language from this paper must have had some surprises!
>
> We have corrected this now. The new, updated version of the paper is
> found at the same place at the old -- it is the first entry on
>
>   http://scala.epfl.ch/docu/index.html
>
> Cheers
>
>  -- Martin

--

========================================================================
Stephane Micheloud                                  Tel: +41 21 693 7593
EPFL - I&C - LAMP                                   Fax: +41 21 693 6660
IN BC 346
Station 14                                http://lamp.epfl.ch/~michelou/
CH-1015 Lausanne, Switzerland         mailto: [hidden email]
========================================================================
Reply | Threaded
Open this post in threaded view
|

Re: New version of overview paper

Vadim Lebedev
In reply to this post by Martin Odersky
Martin Odersky wrote:

> By an unfortunate slip, the paper
>
>   An Overview of the Scala Programming Language
>
> was not updated on the web site. Until now, the paper referred to the
> old version of the language. So anyone trying to learn the second
> version of the language from this paper must have had some surprises!
>
> We have corrected this now. The new, updated version of the paper is
> found at the same place at the old -- it is the first entry on
>
>   http://scala.epfl.ch/docu/index.html
>
> Cheers
>
>  -- Martin
>

It seems i found a mistake in this document on Page 12:
======================
abstract class SyncIterator extends AbsIterator {
        abstract override def hasNext: boolean =
                synchronized(super.hasNext)
        abstract override def next: T =
                synchronized(super.next)
}


StringIterator(someString) with RichIterator
        with SyncIterator

==========================

on previous page it is said that only traits could be used as mixins
so why SyncIterator is not declared as trait?


Vadim