Robby,
Section 5 of your paper notes the function (continuation-marks cont)
provides the continuation marks of an arbitrary continuation at time of
reification.
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))
(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))
(printf
"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 <lzgal...@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 <lzgal...@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
____________________
Racket Users list:
http://lists.racket-lang.org/users