[Seaside] Some questions about Seaside architecture

Avi Bryant avi.bryant at gmail.com
Mon Dec 12 23:30:38 CET 2005


Hi Oleg,

> * How essential are continuations to the design of Seaside?
>     * How is "blocking component call" implemented? My interpretation
>       of section 8.4 of the article would be that when child component
>       is called, a continuation is taken, and essentially the  
> follwoing
>       code is executed:
>         childComponent.addOnAnswerEventHandler(continuation)
>         decorator.replaceMe(childComponent)
>       To be more precise, the continuation should be partial,
>       with respect to the start of event handler.

Yes, that's about right.  We don't actually use partial  
continuations, but it would be a useful optimization to do so.
>
>     * If instead of "blocking calls", one would have primitive:
>         callAsync(component, onCompleteEventHandler)
>       how much the design of Seaside framework would change?
>       Would it still use continuations? Or would it suffice
>       to have event handlers (that never block) implemented
>       using closures?

You certainly could do that, and thus get away without having first- 
class continuations in the language.  This amounts to doing a CPS  
(continuation passing style) transformation on your code.  That's a  
common thing to do as part of compilation, but the results of the  
transformation are usually not very pleasant to work with directly,  
for any complex logic.  Consider a sequence like this:

x = call(component1);

if(x)
   y = call(component2);
else
   y = call(component3);

if(y)
   call(component4);
else
   call(component5);

call(component6);

Now write that out with event handlers...
>
> * Is it possible to "block" for some events other than "answer".
>   Would it be possible to write something like:
>
>     buttonYes = new Button()
>     buttonNo = new Button()
>
>     eventYes = buttonYes.getOnClickEvent()
>     eventNo = buttonNo.getOnClickEvent()
>
>     event = eventOr (eventYes, eventNo)
>
>     waitEvent(event)
>
>     if (eventYes.hasOccured)
>         message "You pressed Yes!"
>     else
>         message "You pressed No!"

No, it's not possible (or not easy, anyway) to do that right now - at  
the widget level (individual buttons/links/inputs) Seaside only uses  
async event handlers.  In the long run, I'm definitely interested in  
shaking things up a bit and allowing something more like what you  
describe, but that would be a substantially different design.

> * Back-button suport:
>     * Are continuations essential to back-button support?
>       Or are they orthogonal?

Well, let me put it this way: using threads rather than continuations  
for call/answer would make the back button (nearly) impossible to  
support.

>     * Is 'registerObjectForBacktracking' essentially equivalent of  
> Java
>       serialization with exception that some objects are omitted?
>       Does it make a shallow or deep copy of registered objects?
>       Does it give substantially better memory footprint in useful  
> configurations?
>       ... as compared to copying whole application tree on each  
> request.

I'm not even sure what "the whole application tree" would mean: you  
have to draw the line somewhere, unless you want to fork the entire  
process every time (which is almost certainly not what you want).   
registerObjectForBacktracking does a shallow copy by default, but you  
can override the behavior to do whatever you like for specific  
classes.  It shares copies across snapshots if there haven't been  
changes, so it has a much better footprint than some simpler  
approaches might.

>     * How does 'registerObjectForBacktracking' work with garbage  
> collection?
>       Weak refereces?

Yes.

>     * Can one backtrack mutable variables within the closures that
>       are not referenced from components?

The standard approach is to use a "StateHolder" object - a  
backtracked box - for mutable variables.

>     * Are Seaside sessions serializable? Are closures serializable  
> in Smalltalk?

Yes, provided you serialize enough context with them.  The simplest  
(and often most useful) example is to simply persist the entire  
object memory of the running process by doing an image snapshot.

>     * Would it be feasible to implement copy-on-change saving of  
> snapshots
>       for backtracking?

As I said above, that's effectively what Seaside already does.
>
> * What is Your opinion, whether it would be feasible to implement Java
>   version of Seaside using:
>     http://jakarta.apache.org/commons/sandbox/javaflow/
>   (note that this is weaker than real continuations & call/cc) and  
> not using
>   Java threads to imitate continuations like LakeShore does:
>     http://lakeshore.sourceforge.net/usersguide.shtml
>   Or is there some other important language feature missing?

Can you say a bit more about how javaflow is weaker?
As for the broader question: from my point of view Java's biggest  
limitation here is its syntax for event handlers (anon inner  
classes).  It's simply too verbose to be practical to use it as  
extensively as Seaside does blocks... if you're tied to the JVM  
(why?), then something like JRuby would seem a much better bet.

Cheers,
Avi


More information about the Seaside mailing list