[Openmcl-devel] process-run-function and "dynamic vs lexical"
Taoufik Dachraoui
taoufik.dachraoui at wanadoo.fr
Thu Oct 22 13:04:22 PDT 2009
I would like to add the following:
SPECIAL as defined in the specs:
"Specifies that all of the vars named are dynamic"
So if a variable is defined in a let block it is a lexical binding and
cannot
> ccl
? (let ((h 1)) ; there is no defvar for h
(declare (special h))
(let ((h 2))
(+ h (locally (declare (special h)) h))))
3 ; here the programmer controls everything, decides what is special
and what is not
? (defvar x 1) ; x is special
X
? (let ((x 1)) ; without declaring x special it is special
because of defvar (lost control)
(let ((x 2)) ; so where in the specs that says (defvar name
init)
(+ x x))) ; must treat name as special everywhere even if
it is
4 ; used in a let block, where let is supposed to create
; a new lexical variable binding (not special unless
declared so)
Only because a symbol is implicitly declared special within a let block
when defvar'ed that we may be in trouble with our code as we saw in
many examples.
Again look at this example of a closure:
(let ((x 1)) (defun foo (y) (+ x y)))
It is obvious that if x is defvar'ed then the code will not behave as
the programmer
intention. This closure definition is legitimate, but the programmer
can use a symbol
name that is defvar'ed without him knowing.
Again, a symbol is special only when you declared so using defvar or
(declare (special ..))
and that when let is used it creates a NEW variable binding and it is
not special unless
declared so.
Taoufik
On Oct 22, 2009, at 9:27 PM, Taoufik Dachraoui wrote:
> Ok let me be more methodic
>
> 1. how do you recognize if a binding is lexical (dynamic)
>
> >ccl
> ?(let ((x 1))
> (flet ((foo () x))
> (let ((x 5)) (+ x (foo)))))
> 6
> ?
> ok the first x is lexical thus the x in foo was replaced by the value
> of x at the time of definition/eval/compile.
>
> ? (defvar x 2)
> X
> ? (let ((x 1))
> (flet ((foo () x))
> (let ((x 5)) (+ x (foo)))))
> 10
> ?
> Ok here the first x is dynamic (see below for comments about this)
> thus the x in
> foo was replaced by <get last value of x at runtime> and it is 5
> when foo is
> executed.
>
> So now I hope it is clear what is lexical and what is dynamic.
>
> The interesting stuff is the second scenario.
>
> After defining x using defvar, the let block do not follow the
> specs; in the specs,
> let creates a new variable binding and that binding is lexical
> unless the name
> is declared special.
>
> Now my question, how come at compile/eval time the foo function was
> not
> lexically bound to the first value of x within the let block (since
> x is the name
> of a new variable binding and it is lexical since there is no
> special declaration
> for x?).
>
> Ok you will say, because x is defined,at toplevel, using DEFVAR. Ok
> fair enough,
> that is how it is implemented; but don't you see that there is a
> clash between how
> the specs defines the let block and how it behaves in the presence
> of a globally
> defined dynamic variable?
>
> I believe that the way dynamic variables are implemented is the
> reason for many bugs
> as said many times in this thread (and among others that is why some
> prefer the setf
> at toplevel in ccl versus the setf as defined by cmucl).
>
> I bilieve that any new variable bound within a let block must shadow
> dynamic variables
> with the same name defined at higher levels; special declarations make
> sense in this context; it is the only way for you to be able to use
> a shadowed dynamic
> variable within a let block:
>
> ? (defvar x 1)
> ? (let ((x 3))
> (+ x (locally (declare (special x)) x))) ; not important how
> to specify to the compiler
> 4 ; which x to use (lexical or dynamic)
>
> This view of how lexical and dynamic variables makes things simpler
> and easier to
> understand, because if something is lexically bound it is not
> dynamic in its scope
> (unless so desired by the programmer using declaring it special).
>
> Dynamic variables sould not be pervasive (unwelcome) but should be
> used with some
> confidence by all programmer and not only experts should use them;
> For this they need
> to be easy to understand and intuitive (no surprises only when there
> is an obvious error
> in the program).
>
> Taoufik
>
>
>
>
>
>
> On Oct 22, 2009, at 8:20 PM, John McAleely wrote:
>
>>
>>> let creates new variable binding for the names x and y and these
>>> bindings are lexical unless they are declared special.
>>
>> OK. I think this is where the mistake in your reasoning occurs,
>> since you appeal only to the CL spec.
>>
>> My understanding is that the closure you create will bind x and y
>> in the thread it executes in.
>>
>> When you jump into another thread via process-run-function, the
>> lexical binding created by your let is no longer visible.
>>
>> My further understanding is that the CL spec does not define this
>> multi-threaded behaviour, and that implementation conventions in
>> this area tend to appeal back to implementations on the Lisp
>> Machine that proved convenient.
>>
>> So your attempt to understand the behaviour of process-run-function
>> only by appeal to the CL spec is where you have made the mistake in
>> your reasoning.
>>
>> J
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20091022/cc74c1b8/attachment.htm>
More information about the Openmcl-devel
mailing list