Discussion:
Dynamic environment capture
szergling
2009-03-22 00:51:56 UTC
Permalink
Hi Pascal,

I have a quick question, or perhaps a bug report on the new dynamic
environments and their capture. Is 'nested' capture supported?

(defdynamic x nil)
X

(defparameter *y*
(dlet ((x 1))
(capture-dynamic-environment)))
*Y*

(with-dynamic-environment (*y*)
(dynamic x))
1

(defparameter *x*
(with-dynamic-environment (*y*)
(capture-dynamic-environment)))
*X*

(with-dynamic-environment (*x*)
(dynamic x))
NIL

Inspecting *x* shows that its dynamic-winds slot is nil.


I would guess that nested capture is the intended behaviour, from
reading the source. Capture would go through *dynamic-wind-stack*
collecting environments. However, call-with-dynamic-environment
doesn't seem to re-establish *dynamic-wind-stack*. How do I capture
all of *y* in *x* as well? This way, there's a chain of environments
to fallback on.

Thanks in advance for your help.

Theam Yong Chew



Aside:
Should defdynamic be required before we can use dlet?

(dlet ((x 1)) (...))

Should be pretty obvious that x is dynamic. Especially when we access
it via (dynamic x).
Pascal Costanza
2009-03-22 12:04:19 UTC
Permalink
Dear Theam Yong Chew,

You're absolutely right, this is a bug. Nice catch. I will fix it as
soon as possible.

It shouldn't be necessary to perform a defdynamic for purely local
dynamic bindings, but I have to double-check this, it may be that I
forgot to get the details right here. Will do this as well.

You shouldn't, however, use computed symbols for dlet. If you want
those, you should rather use one of the progv/repgrogv variants.


Pascal
Post by szergling
Hi Pascal,
I have a quick question, or perhaps a bug report on the new dynamic
environments and their capture. Is 'nested' capture supported?
(defdynamic x nil)
X
(defparameter *y*
(dlet ((x 1))
(capture-dynamic-environment)))
*Y*
(with-dynamic-environment (*y*)
(dynamic x))
1
(defparameter *x*
(with-dynamic-environment (*y*)
(capture-dynamic-environment)))
*X*
(with-dynamic-environment (*x*)
(dynamic x))
NIL
Inspecting *x* shows that its dynamic-winds slot is nil.
I would guess that nested capture is the intended behaviour, from
reading the source. Capture would go through *dynamic-wind-stack*
collecting environments. However, call-with-dynamic-environment
doesn't seem to re-establish *dynamic-wind-stack*. How do I capture
all of *y* in *x* as well? This way, there's a chain of environments
to fallback on.
Thanks in advance for your help.
Theam Yong Chew
Should defdynamic be required before we can use dlet?
(dlet ((x 1)) (...))
Should be pretty obvious that x is dynamic. Especially when we access
it via (dynamic x).
_______________________________________________
closer-devel mailing list
http://common-lisp.net/cgi-bin/mailman/listinfo/closer-devel
--
ELS'09: http://www.european-lisp-symposium.org/

Pascal Costanza, mailto:***@p-cos.net, http://p-cos.net
Vrije Universiteit Brussel
Programming Technology Lab
Artificial Intelligence Lab
Pleinlaan 2, B-1050 Brussel, Belgium
Pascal Costanza
2009-03-23 15:39:42 UTC
Permalink
Dear Theam Yong Chew,

I have fixed both issues: The dynamic wind stack is now also updated
when with-dynamic-environment is invoked, and dynamic-let and friends
should now also work without a prior defdynamic (local special
declarations were missing to ensure this).

I have added your test case to the test suite, to ensure that this
will work in the future. You can find the changes in the repository.

Thanks again a lot for the bug report! This is very useful!


Best,
Pascal
Post by szergling
Hi Pascal,
I have a quick question, or perhaps a bug report on the new dynamic
environments and their capture. Is 'nested' capture supported?
(defdynamic x nil)
X
(defparameter *y*
(dlet ((x 1))
(capture-dynamic-environment)))
*Y*
(with-dynamic-environment (*y*)
(dynamic x))
1
(defparameter *x*
(with-dynamic-environment (*y*)
(capture-dynamic-environment)))
*X*
(with-dynamic-environment (*x*)
(dynamic x))
NIL
Inspecting *x* shows that its dynamic-winds slot is nil.
I would guess that nested capture is the intended behaviour, from
reading the source. Capture would go through *dynamic-wind-stack*
collecting environments. However, call-with-dynamic-environment
doesn't seem to re-establish *dynamic-wind-stack*. How do I capture
all of *y* in *x* as well? This way, there's a chain of environments
to fallback on.
Thanks in advance for your help.
Theam Yong Chew
Should defdynamic be required before we can use dlet?
(dlet ((x 1)) (...))
Should be pretty obvious that x is dynamic. Especially when we access
it via (dynamic x).
_______________________________________________
closer-devel mailing list
http://common-lisp.net/cgi-bin/mailman/listinfo/closer-devel
--
ELS'09: http://www.european-lisp-symposium.org/

Pascal Costanza, mailto:***@p-cos.net, http://p-cos.net
Vrije Universiteit Brussel
Programming Technology Lab
Artificial Intelligence Lab
Pleinlaan 2, B-1050 Brussel, Belgium
szergling
2009-03-23 20:31:36 UTC
Permalink
Post by Pascal Costanza
Dear Theam Yong Chew,
I have fixed both issues: The dynamic wind stack is now also updated when
with-dynamic-environment is invoked, and dynamic-let and friends should now
also work without a prior defdynamic (local special declarations were
missing to ensure this).
Great, thanks.
Post by Pascal Costanza
I have added your test case to the test suite, to ensure that this will work
in the future. You can find the changes in the repository.
Good idea. I'll check it out soon. Incidentally, this all started from a thread
on comp.lang.lisp about continuations & dynamic scope. I'll be able to keep
exploring with this fix. I'll see how I go from here.

Yong.

Loading...