From: Mariano Montone
Subject: Continuations and dynamic variables
Date: 
Message-ID: <058b5f51-e09c-4dd9-aff4-6152c96c2d8a@h5g2000yqh.googlegroups.com>
Hello,
          I'd like to know how dynamic variables are supposed to
behave when using continuations. The way to implement continuations in
CL is by code transformation where the lambdas generated represent the
rest of the computation. The problem I see with this is that dynamic
variable bindings are not preserved.

For example, using the cl-cont package that works like that:

(require :cl-cont)

(use-package :cl-cont)

(defvar *my-dyn-var*)

(defvar *cont*)

(with-call/cc
  (let
      ((*my-dyn-var* "hello!!"))
    (call/cc (lambda (cont)
	       (setf *cont* cont)))
    (print *my-dyn-var*)))

(funcall *cont*)

That prints nil instead of hello!! (the dynamic variable binding is
lost).

So, which is the correct semantic??

If our language were interpreted and we had access to the stack-
frames, we could get rid of the code transformation and implement
continuations copying stack-frames instead. This way, dynamic variable
bindings are preserved, which is interesting for programming some web
applications. AFAIK, this is how Seaside implement them, so I guess
they don't have that problem.

Thoughts?

Thanks!

Mariano

From: Mariano Montone
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <0d3c31af-139d-4d67-809d-0377e53530ce@e38g2000yqa.googlegroups.com>
Talking to myself, but anyway...

What I meant was the whole dynamic binding structures are lost, of
course.

Using conditions for example:

(require :cl-cont)

(use-package :cl-cont)

(define-condition unhandled-condition (error)
  ())

(defvar *cont*)

(with-call/cc
  (handler-case
      (progn
	(call/cc (lambda (cont)
		   (setf *cont* cont)))
	(error 'unhandled-condition))
    (unhandled-condition () (print "Condition handled!"))))

(funcall *cont*)

That signals a condition that doesn't get caught. I know that's
because when we do (funcall *cont*) we are in a different dynamic
environment.

Just wonder which is the correct semantic, and whether it is possible
to implement something that executes the continuation in the dynamic
environment it was generated somehow.

Btw, the continuation library seems to be buggy, so my experiments may
mean nothing:

This doesn't handle the condition, although I think it should:

(with-call/cc
  (handler-case
      (error 'unhandled-condition)
    (unhandled-condition () (print "Condition handled!"))))

Mariano

On 20 mar, 17:23, Mariano Montone <··············@gmail.com> wrote:
> Hello,
>           I'd like to know how dynamic variables are supposed to
> behave when using continuations. The way to implement continuations in
> CL is by code transformation where the lambdas generated represent the
> rest of the computation. The problem I see with this is that dynamic
> variable bindings are not preserved.
>
> For example, using the cl-cont package that works like that:
>
> (require :cl-cont)
>
> (use-package :cl-cont)
>
> (defvar *my-dyn-var*)
>
> (defvar *cont*)
>
> (with-call/cc
>   (let
>       ((*my-dyn-var* "hello!!"))
>     (call/cc (lambda (cont)
>                (setf *cont* cont)))
>     (print *my-dyn-var*)))
>
> (funcall *cont*)
>
> That prints nil instead of hello!! (the dynamic variable binding is
> lost).
>
> So, which is the correct semantic??
>
> If our language were interpreted and we had access to the stack-
> frames, we could get rid of the code transformation and implement
> continuations copying stack-frames instead. This way, dynamic variable
> bindings are preserved, which is interesting for programming some web
> applications. AFAIK, this is how Seaside implement them, so I guess
> they don't have that problem.
>
> Thoughts?
>
> Thanks!
>
> Mariano
From: Vend
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <4fd865ff-7f29-45d9-acbd-0c819c880deb@w9g2000yqa.googlegroups.com>
On 20 Mar, 21:23, Mariano Montone <··············@gmail.com> wrote:
> Hello,
>           I'd like to know how dynamic variables are supposed to
> behave when using continuations. The way to implement continuations in
> CL is by code transformation where the lambdas generated represent the
> rest of the computation. The problem I see with this is that dynamic
> variable bindings are not preserved.

Maybe you should pass a dynamic binding table along with the
continuation closure.

<snip>
From: Pascal Costanza
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <72k2u2Fqau0sU1@mid.individual.net>
Vend wrote:
> On 20 Mar, 21:23, Mariano Montone <··············@gmail.com> wrote:
>> Hello,
>>           I'd like to know how dynamic variables are supposed to
>> behave when using continuations. The way to implement continuations in
>> CL is by code transformation where the lambdas generated represent the
>> rest of the computation. The problem I see with this is that dynamic
>> variable bindings are not preserved.
> 
> Maybe you should pass a dynamic binding table along with the
> continuation closure.

Tables are not good enough.

Assume you want to build up a list of entries using a special variable:

(defvar *entries* '())

You may want to build it up by rebinding it:

(let ((*entries* (list* 'a 'b 'c *entries*)))
   ...)

If you want to capture the dynamic environment, you may actually want to 
capture the action, not the result. Consider:

(setq env (let ((*entries* (list* 'a 'b 'c *entries*)))
             (capture-dynamic-environment)))

(let ((*entries* '(d e f)))
   (with-dynamic-environment (env)
     (print *entries*)))

=> (A B C D E F)

This is especially interesting for removals:

(setq env (let ((*entries* (remove 'b *entries*)))
             (capture-dynamic-environment)))

(let ((*entries* '(a b c)))
   (with-dynamic-environment (env)
     (print *entries*)))

=> (A C)

Now the dynamic environment ensures that the resulting binding does not 
contain a certain element, no matter what it contained before.

Being able to capture actions is important. For example, you can then 
also capture exceptions handlers, etc.

The new version of ContextL supports all this, and it should be easy to 
combine this with existing continuation frameworks for Common Lisp! (At 
least, that's the goal, if it doesn't work, please let me know! Note 
that ContextL doesn't provide continuations itself.)


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: szergling
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <ba920f2b-ced0-41c4-905e-9563581064e0@r31g2000prh.googlegroups.com>
On Mar 21, 8:23 am, Mariano Montone <··············@gmail.com> wrote:
> Hello,
>           I'd like to know how dynamic variables are supposed to
> behave when using continuations. The way to

...

> (defvar *my-dyn-var*)
>
> (defvar *cont*)
>
> (with-call/cc
>   (let
>       ((*my-dyn-var* "hello!!"))
>     (call/cc (lambda (cont)
>                (setf *cont* cont)))
>     (print *my-dyn-var*)))
>
> (funcall *cont*)
>
> That prints nil instead of hello!! (the dynamic variable binding is
> lost).
>
> So, which is the correct semantic??

I can't think of anything wrong with having (print *my-dyn-var*) show
"hello!!", instead of anything else. For example, I don't expect it to
be the binding at the time the continuation is invoked, as in,
not this (arnesi style):

(let ((*my-dyn-var* "NOT THIS"))
  (kall *cont*))
==> I still expect "hello!!"

This behaviour is what arnesi does (almost, it's buggy at the moment!)

CL-USER> (arnesi:with-call/cc
           (let ((*my-dyn-var* "hello!!"))
             (declare (special *my-dyn-var*))
             (arnesi:let/cc cont
               (setf *cont* cont))
             (print *my-dyn-var*)))
(IT.BESE.ARNESI::K-FOR-EVALUATE-PROGN/CC
 (#<IT.BESE.ARNESI:FREE-APPLICATION-FORM # {E1BADE9}>) NIL
 ((:LET *MY-DYN-VAR* . "hello!!")) (IT.BESE.ARNESI::TOPLEVEL-K))
CL-USER> (arnesi:with-call/cc (arnesi:kall *cont*))

"hello!!" "hello!!"

Unfortunately, you need that declaration so that the variable is
walked as a free (dynamic) variable. It's not too clear to me at the
moment if that's also the case for tracking of dynamic
environments. The declaration is a "TODO fix" as shown in the test
suite,
t/call-cc.lisp, at least in my copy.

Additionally,

CL-USER> (arnesi:with-call/cc
           (let ((*my-dyn-var* "NOT ME"))
             (arnesi:kall *cont*)))

"hello!!" "hello!!"
CL-USER> (let ((*my-dyn-var* "NOT ME"))
           (arnesi:with-call/cc
             (arnesi:kall *cont*)))

"hello!!" "hello!!"
CL-USER>

Arnesi's code walker does capture it's surrounding outer lexical
environment. But, it doesn't seem to capture its surrounding/outer
dynamic environment. The inner environments seem to be captured fine
(if a little bit buggy).

By inner/outer (am I using the right word?), I was referring to:

(let (...outer...)
  (with-call/cc
     (let (...inner...)
       ...)))

Incidentally, the arnesi components seem to have been spun off into
cl-walker and cl-delico, by Attila Lendvai.
From: Mariano Montone
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <c405d4ef-1fd9-4a81-92f7-53711aa9754e@z1g2000yqn.googlegroups.com>
On 21 mar, 08:23, szergling <···············@gmail.com> wrote:
> Arnesi's code walker does capture it's surrounding outer lexical
> environment. But, it doesn't seem to capture its surrounding/outer
> dynamic environment. The inner environments seem to be captured fine
> (if a little bit buggy).

That must be because continuation implementations in CL are delimited.

Mariano
From: Pascal Costanza
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <72k2hpFq42s8U1@mid.individual.net>
Mariano Montone wrote:
> On 21 mar, 08:23, szergling <···············@gmail.com> wrote:
>> Arnesi's code walker does capture it's surrounding outer lexical
>> environment. But, it doesn't seem to capture its surrounding/outer
>> dynamic environment. The inner environments seem to be captured fine
>> (if a little bit buggy).
> 
> That must be because continuation implementations in CL are delimited.

Yep.

I can only highly recommend to read 
http://okmij.org/ftp/papers/DDBinding.pdf - especially Sections 4.2.1 - 
4.2.3!!!


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mariano Montone
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <7a08bf2c-adbb-4077-8edf-e82922f56a73@c11g2000yqj.googlegroups.com>
On 21 mar, 08:49, Pascal Costanza <····@p-cos.net> wrote:
> Mariano Montone wrote:
> > On 21 mar, 08:23, szergling <···············@gmail.com> wrote:
> >> Arnesi's code walker does capture it's surrounding outer lexical
> >> environment. But, it doesn't seem to capture its surrounding/outer
> >> dynamic environment. The inner environments seem to be captured fine
> >> (if a little bit buggy).
>
> > That must be because continuation implementations in CL are delimited.
>
> Yep.
>
> I can only highly recommend to readhttp://okmij.org/ftp/papers/DDBinding.pdf- especially Sections 4.2.1 -
> 4.2.3!!!

The paper is quite revealing for me! Specially 4.2.x that explain the
use of continuations in several contexts (mobile code, web
applications and databases), and concludes that you need control over
which parts of the dynamic context you want to capture. Your approach
to capturing the dynamic context seems to fit very well; I'll be doing
some experiments, though.

What I feel unconfortable with sometimes is that whenever I see some
CL limitation, then that limitation has a reason, and a better
solution comes because of that limitation (for example, delimited
continuations and control over the dynamic context, instead of full
continuations). Although I haven't totally made up my mind about this
yet.

Mariano
From: Pascal Costanza
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <72kfsnFqvb7oU2@mid.individual.net>
Mariano Montone wrote:
> On 21 mar, 08:49, Pascal Costanza <····@p-cos.net> wrote:
>> Mariano Montone wrote:
>>> On 21 mar, 08:23, szergling <···············@gmail.com> wrote:
>>>> Arnesi's code walker does capture it's surrounding outer lexical
>>>> environment. But, it doesn't seem to capture its surrounding/outer
>>>> dynamic environment. The inner environments seem to be captured fine
>>>> (if a little bit buggy).
>>> That must be because continuation implementations in CL are delimited.
>> Yep.
>>
>> I can only highly recommend to readhttp://okmij.org/ftp/papers/DDBinding.pdf- especially Sections 4.2.1 -
>> 4.2.3!!!
> 
> The paper is quite revealing for me! Specially 4.2.x that explain the
> use of continuations in several contexts (mobile code, web
> applications and databases), and concludes that you need control over
> which parts of the dynamic context you want to capture. Your approach
> to capturing the dynamic context seems to fit very well; I'll be doing
> some experiments, though.

Please make sure to let me know what your findings are. This is a very 
new feature in ContextL, so any kind of feedback that helps improving it 
is very welcome!


Best,
Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: szergling
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <9e764b40-07b4-4110-8d04-df3a30adf23c@c18g2000prh.googlegroups.com>
On Mar 21, 11:49 pm, Pascal Costanza <····@p-cos.net> wrote:
> Mariano Montone wrote:
> > On 21 mar, 08:23, szergling <···············@gmail.com> wrote:
> >> Arnesi's code walker does capture it's surrounding outer lexical
> >> environment. But, it doesn't seem to capture its surrounding/outer
> >> dynamic environment. The inner environments seem to be captured fine
> >> (if a little bit buggy).
>
> > That must be because continuation implementations in CL are delimited.
>
> Yep.
>
> I can only highly recommend to readhttp://okmij.org/ftp/papers/DDBinding.pdf- especially Sections 4.2.1 -
> 4.2.3!!!

Ok, I take back what I said earlier. Specifically, I quote the paper:

"A migrated piece of mobile code should look to its new host for OS
services such as gethostname (see Section 4.2.1)."

"On the other hand, the mobile code may bind and use dynamic variables
internally as well, ..."

It's not about whether the dynamic environment should be "captured" or
not, but how much of the dynamic environment to "capture", and how
much to not "capture" (to be left to be "looked up" in a new kaller's
environment).

It's another 10 years back to the temple for me, while I figure out
all the notations/squiggles and OCAML code in that paper.
From: Pascal Costanza
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <72j63mFollaiU4@mid.individual.net>
Mariano Montone wrote:
> Hello,
>           I'd like to know how dynamic variables are supposed to
> behave when using continuations. 

See http://groups.google.com/group/comp.lang.lisp/msg/e429bbf73ecd784d 
and http://common-lisp.net/pipermail/closer-devel/2009-February/000550.html


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Mariano Montone
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <2b222e42-17ed-45e5-83d9-5302ea01622c@a39g2000yqc.googlegroups.com>
On 21 mar, 00:43, Pascal Costanza <····@p-cos.net> wrote:
> Mariano Montone wrote:
> > Hello,
> >           I'd like to know how dynamic variables are supposed to
> > behave when using continuations.
>
> Seehttp://groups.google.com/group/comp.lang.lisp/msg/e429bbf73ecd784d
> andhttp://common-lisp.net/pipermail/closer-devel/2009-February/000550.html

Oh!  Thanks for the links. Interesting.

Mariano
From: Thomas F. Burdick
Subject: Re: Continuations and dynamic variables
Date: 
Message-ID: <e5f5595f-3171-43b0-a8c6-df90fe9f0356@e38g2000yqa.googlegroups.com>
On 20 mar, 21:23, Mariano Montone <··············@gmail.com> wrote:
> So, which is the correct semantic??

Pascal gave you good links, and hopefully those solve your immediate
question. I stand by what I asserted in the cited thread: dynamic
bindings in the face of continuations are easy. However, in order to
make continuations useful, you need to think about reentry and
unwinding and if your goal is to make a general purpose language or
language facility, you end out in the hell that is dynamic-wind and
friends.

You seem to be aware of Seaside. If you're messing with continuations
with a specific functional goal in mine, look there. Scheme is a mess.
Seaside does not provide a perfect solution for all eventualities, but
they get it right for the case they're trying to solve. In case you
haven't read it, §6 of "Seaside – A Multiple Control Flow Web
Application Framework" might be helpful:
http://www.iam.unibe.ch/~scg/Archive/Papers/Duca04eSeaside.pdf