[racket] Engineering Tradeoffs of ANF transforms and the Stateless Server

From: Galler (lzgaller at optonline.net)
Date: Sat Dec 31 22:15:24 EST 2011


Section 5 of your paper notes the function (continuation-marks cont)

provides the continuation marks of an arbitrary continuation at time of 

Illustrative code snippet below

That certainly takes care of a lot of the problems associated with 
implementing a solution to chain exit and entry actions.

Thanks very much for sharing the paper.

I had no idea!

#lang web-server

(define *s2-k* #f)

(define (nextproc)
   (list ;have to have an intermediate function, or it will replace 
prior mark (tail-calling
    (with-continuation-mark 'state '(S2 beforeproc afterproc) ((λ ()
(call/cc (λ (k) (set! *s2-k* k)) (default-continuation-prompt-tag))
"in S2 ~A\n" (continuation-mark-set->list
(current-continuation-marks) 'state)))))
    (with-continuation-mark 'state '(S3 beforeproc afterproc) ((λ ()
"in S3 ~A\n" (continuation-mark-set->list
(current-continuation-marks) 'state))
"in S3 s2's continuation marks are ~A\n" (continuation-mark-set->list
(continuation-marks *s2-k*) 'state)))))


(with-continuation-mark 'state '(S1 beforeproc afterproc) (nextproc))

On Sat, Dec 31, 2011 at 9:36 PM, Robby Findler wrote:

> FWIW, this is essentially re-implementing dynamic-wind (but it is not
> too difficult if you are familiar with continuations). One thing to
> watch out for: the lists of continuation marks will, in some cases,
> share a tail. In that case you'll want to avoid exiting and
> re-entering the same things. Also worth noting here, I think, you may
> need to use some kind of unique values in the marks to be able to tell
> if the shared tails _really_ are shared or if they simply have the
> same structure.
> You might find this paper useful to sort out some of the subtleties:
>    http://www.cs.utah.edu/plt/delim-cont/
> hth,
> Robby
> On Sat, Dec 31, 2011 at 8:18 PM, Galler <lzgaller at optonline.net> 
> wrote:
>> Robby,
>> Thanks
>> Not at all opaque. I was experimenting with that earlier this 
>> afternoon, as
>> below.
>> Actuallly, the way you phrased it helps clarify something I was 
>> struggle
>> with.
>> A very useful and valuable suggestion.  I think that may very well be 
>> plan
>> B.
>> R./
>> Zack
>> (define (nextproc)
>>  ;need an intermediate function, or it will replace prior mark 
>> (tail-calling
>>  (list
>>   (with-continuation-mark 'state '(S2 beforeproc afterproc) ((λ ()
>>  (printf "in
>> S2 ~A\n" (continuation-mark-set->list
>> (current-continuation-marks) 'state)))))
>>   (with-continuation-mark 'state '(S3 beforeproc afterproc) ((λ ()
>>  (printf "in
>> S3 ~A\n" (continuation-mark-set->list
>> (current-continuation-marks) 'state)))))))
>> (with-continuation-mark 'state '(S1 beforeproc afterproc) (nextproc))
>> On Sat, Dec 31, 2011 at 9:03 PM, Robby Findler wrote:
>>> I'm not sure if the web-server supports continuation marks or not, 
>>> but
>>> if it does, you could use continuation marks to note what the exit 
>>> and
>>> entry operations are, and then when you would do a continuation 
>>> jump,
>>> first grab the continuation marks from one side, do the jump, grab 
>>> the
>>> continuation marks from the other side, and then explicitly do the
>>> actions that the marks have recorded should be done. (Let me know if
>>> that is too opaque ...)
>>> Robby
>>> On Sat, Dec 31, 2011 at 7:56 PM, Galler <lzgaller at optonline.net> 
>>> wrote:
>>>> Sorry, should have included a brief example.
>>>> Here's an example of what I've implemented, which is just Harel's
>>>> hierarchical state machines
>>>> You can create a Hierarchical State Machine by defining individual 
>>>> nodes
>>>> in
>>>> a flat file, as below.
>>>> each node has 6 keyword parameters , state, parent, entry, init, 
>>>> exit,
>>>> and a
>>>> handler.
>>>> The machine is very much like a web-server. It receives a signal 
>>>> (akin to
>>>> a
>>>> request), processes the signal which may cause a change internal 
>>>> state,
>>>> and
>>>> returns a continuation to be invoked when the next signal is 
>>>> presented.
>>>> The new signal is the argument provided to this continuation at
>>>> invocation.
>>>> In the stateful server, the  HSM continuation is closed over by the 
>>>> PLT
>>>> Server's external continuation (reified by send/suspend)
>>>> In the stateless version, I would replace the HSM continuation with 
>>>> the
>>>> PLT
>>>> server's continuation (reified by send/suspend).
>>>> I can't do that right now because the continuation is in the scope 
>>>> of the
>>>> dynamic-wind function, which is an unsafe place to capture 
>>>> continuations
>>>> for
>>>> #lang web-server
>>>> The dynamic wind is used as follows:
>>>> At present, the nodes are brought into the correct tree-like 
>>>> dynamic
>>>> extent
>>>> by a recursive function which invokes dynamic-wind.
>>>> Note that the handler code supports jumping to another state 
>>>>  (trans 'S2
>>>> 'S3).
>>>> Trans invokes a continuation reified earlier associated with state 
>>>> S3. In
>>>> this case, the invocation of the continuation calls the exit 
>>>> actions of
>>>> state S2 and the entry actions of S3.
>>>> That's where the dynamic-wind comes in. Its necessary for 
>>>> transitions
>>>> between states and but used for anything else.
>>>> That's why I think an overridden call/cc-dynamic-wind and dynamic 
>>>> wind
>>>> would
>>>> be sufficient.
>>>> (defnode
>>>>  #:state 'S2
>>>>  #:parent 'Top
>>>>  #:entry  (λ () (I-TLL:entry-start-TLL))
>>>>  #:init (lambda () (trans 'S2 'S3))
>>>>  #:exit  (λ () (I-TLL:exit-secure-TLL))
>>>>  #:handler (λ (signal)
>>>>              (cond
>>>>                [(signal-eq? signal "main") (trans 'S2 'S3)]
>>>>                [(signal-eq? signal "info") (trans 'S2 'S4)]
>>>>                [(signal-eq? signal "about") (trans  'S2 'S5)]
>>>>                [(signal-eq? signal "item") (trans 'S2 'S6)]
>>>>                [(signal-eq? signal "field") (trans 'S2 'S7)]
>>>>                [(signal-eq? signal "dispatch") (trans  'S2 'S8-3)]
>>>>                [(signal-eq? signal "burden") (trans  'S2 'S8-2)]
>>>>                [(signal-eq? signal "planning") (trans 'S2 'S8-1)]
>>>>                [(signal-eq? signal "failentry") (trans 'S2 'S3)]
>>>>                [else #f])))
>>>> ____________________
>>>>  Racket Users list:
>>>>  http://lists.racket-lang.org/users

Posted on the users mailing list.