On Thursday, March 21, 2013 11:35:19 AM Noah Lavine wrote: > (lambda () > (let ((x 5)) > (set! x (compute-1 x)) > (set! x (compute-2 x)) > x)) > > becomes > > (lambda () > (let ((k1 (lambda (x) (k2 (compute-2 x)))) > (k2 (lambda (x) x))) > (k1 (compute-1 x)))) > > However, this rewriting idea runs into trouble when you try to figure > out what happens to mutable variables that have been captured by > closures (as Mark said). I don't know what the right solution is > here.
The semantic is that cpatured variables in lambdas will be restored to the value when the continuation left the guard. And this is something you want many times e.g. consider, (let ((a 0) (f (case-lambda (() a) ((b) (set! a b))))) (with-special (a) (for-each (lambda (x) (if (blah x) (k x f) (abort-to-prompt 'tag a))) a-list) (f))) Assume that you would like to be able to go back to the tag abort many times in a redo/undo sequence, then it is natural for the a referenced in f to be restored as well. But as you know sometimes this is not what we want. As I said, using dynwinds and fluids it's really possible to get this behavior today but it's really a bloated solution. Anyhow the good news with this semantic is as with the current behavior of assigned variables it's easy to reason with the code although one risk some severe bugs. A good question though is what we should use as default for e.g. a python implementation where prompts is not included per se, but which we might want to add as a special scheme flavour of python using an import e.g. what is the natural thing to expect for the variables that are assigned. Also in the previous email I had a suggestion to for each with variable, a, add two slots in the stack e.g. a1 val1 s2 val2 ... But there is a good reason to asign a kind to this as well e.g. a1 val kind a2 val2 kand2 ... then we could use a predicates when we rewind a continuation e.g. at rewind: (when (pred1 kind1) (set! a1 (ref-val val1))) ... and and at wind (when (pred2 kind1) (set-val val1 a1)) ... A simple version of this with a complex implementation is what I actually use in guile-log. BTW after this deep realizations of the guile variable behavior I'm ready to implement a much improved version of these special variables in guile-log that is both efficient and featureful. Cool! Have fun /Stefan