<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Why do you think that let necessarily establishes a lexical binding?<div><br><div><div>On Oct 22, 2009, at 22:04 , Taoufik Dachraoui wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I would like to add the following:<div><br></div><div>SPECIAL as defined in the specs:</div><div><br></div><div>"<span class="Apple-style-span" style="font-family: Times; ">Specifies that all of the <i>vars</i> named are dynamic"</span></div><div><font class="Apple-style-span" face="Times"><br></font></div><div><div><div>So if a variable is defined in a let block it is a lexical binding and cannot </div><div><br></div><div><div>> ccl</div><div>? (let ((h 1))  ; there is no defvar for h</div><div>    (declare (special h))</div><div>    (let ((h 2))</div><div>      (+ h (locally (declare (special h)) h))))</div><div>3   ; here the programmer controls everything, decides what is special and what is not</div><div><br></div><div>? (defvar x 1) ; x is special</div><div>X</div><div>? (let ((x 1))       ; without declaring x special it is special because of defvar (lost control)</div><div>     (let ((x 2))    ; so where in the specs that says (defvar name init) </div><div>       (+ x x)))     ; must treat name as special everywhere even if it is</div><div>4      <span class="Apple-tab-span" style="white-space:pre">   </span>    <span class="Apple-tab-span" style="white-space:pre">      </span>     ; used in a let block, where let is supposed to create</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>             ; a new lexical variable binding (not special unless declared so)</div><div><br></div><div>Only because a symbol is implicitly declared special within a let block</div><div>when defvar'ed that we may be in trouble with our code as we saw in many examples.</div><div><br></div><div>Again look at this example of a closure:</div><div><br></div><div>(let ((x 1)) (defun foo (y) (+ x y)))</div><div><br></div><div>It is obvious that if x is defvar'ed then the code will not behave as the programmer</div><div>intention. This closure definition is legitimate, but the programmer can use a symbol</div><div>name that is defvar'ed without him knowing.</div><div><br></div><div><br></div><div>Again, a symbol is special only when you declared so using defvar or (declare (special ..))</div><div>and that when let is used it creates a NEW  variable binding and it is not special unless</div><div>declared so.</div><div><br></div><div>Taoufik</div><div><br></div></div><div>On Oct 22, 2009, at 9:27 PM, Taoufik Dachraoui wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Ok let me be more methodic<br><br>1. how do you recognize if a binding is lexical (dynamic)<br><br>>ccl<br>?(let ((x 1))<br>    (flet ((foo () x))<br>       (let ((x 5)) (+ x (foo)))))<br>6<br>?<br>ok the first x is lexical thus the x in foo was replaced by the value<br>of x at the time of definition/eval/compile.<br><br>? (defvar x 2)<br>X<br>? (let ((x 1))<br>    (flet ((foo ()  x))<br>       (let ((x 5)) (+ x (foo)))))<br>10<br>?<br>Ok here the first x is dynamic (see below for comments about this) thus the x in<br>foo was replaced by <get last value of x at runtime> and it is 5 when foo is<br>executed.<br><br>So now I hope it is clear what is lexical and what is dynamic.<br><br>The interesting stuff is the second scenario.<br><br>After defining x using defvar, the let block do not follow the specs; in the specs,<br>let creates a new variable binding and that binding is lexical unless the name<br>is declared special.<br><br>Now my question, how come at compile/eval time the foo function was not<br>lexically bound to the first  value of x within the let block (since x is the name<br>of a new variable binding and it is lexical since there is no special declaration<br>for x?).<br><br>Ok you will say, because x is defined,at toplevel, using DEFVAR. Ok fair enough,<br>that is how it is implemented; but don't you see that there is a clash between how<br>the specs defines the let block and how it behaves in the presence of a globally<br>defined dynamic variable?<br><br>I believe that the way dynamic variables are implemented is the reason for many bugs<br>as said many times in this thread (and among others that is why some prefer the setf<br>at toplevel in ccl versus the setf as defined by cmucl).<br><br>I bilieve that any new variable bound within a let block must shadow dynamic variables<br>with the same name defined at higher levels; special declarations make<br>sense in this context; it is the only way for you to be able to use a shadowed dynamic<br>variable within a let block:<br><br>? (defvar x 1)<br>? (let ((x 3))<br>    (+ x (locally (declare (special x)) x)))    ; not important how to specify to the compiler<br>4<span class="Apple-tab-span" style="white-space:pre"> </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span>; which x to use (lexical or dynamic)<br><br>This view of how lexical and dynamic variables makes things simpler and easier to<br>understand, because if something is lexically bound it is not dynamic in its scope<br>(unless so desired by the programmer using declaring it special).<br><br>Dynamic variables sould not be pervasive (unwelcome) but should be used with some<br>confidence by all programmer and not only experts should use them; For this they need<br>to be easy to understand and intuitive (no surprises only when there is an obvious error<br>in the program).<br><br>Taoufik<br><br><br><br><br><br><br>On Oct 22, 2009, at 8:20 PM, John McAleely wrote:<br><br><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">let creates new variable binding for the names x and y and these<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">bindings are lexical unless they are declared special.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">OK. I think this is where the mistake in your reasoning occurs, since you appeal only to the CL spec.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">My understanding is that the closure you create will bind x and y in the thread it executes in.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">When you jump into another thread via process-run-function, the lexical binding created by your let is no longer visible.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">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.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">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.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">J<br></blockquote><blockquote type="cite"><br></blockquote><br></div></blockquote></div><br></div></div>_______________________________________________<br>Openmcl-devel mailing list<br><a href="mailto:Openmcl-devel@clozure.com">Openmcl-devel@clozure.com</a><br>http://clozure.com/mailman/listinfo/openmcl-devel<br></blockquote></div><br></div></body></html>