<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I compared openmcl and cmucl and found that openmcl setf create a lexical variable <div>and mcucl setf create a dynamic variable</div><div><br></div><div><div>>>> cmucl</div><div>* (setf d 2)</div><div><br></div><div>Warning: Declaring D special.</div><div><br></div><div>2</div><div>* (defun f () (+ 1 d))</div><div><br></div><div>F</div><div>* (let ((d 5)) (f))</div><div><br></div><div>6</div><div>* </div><div><br></div><div>>>> openmcl</div><div><div>? (setf d 2)</div><div>2</div><div>? (defun f () (+ 1 d)) </div><div>;Compiler warnings :</div><div>; In F: Undeclared free variable D</div><div>F</div><div>? (let ((d 5)) (f))</div><div>;Compiler warnings :</div><div>; In an anonymous lambda form: Unused lexical variable D</div><div>3</div><div><br></div><div><br></div><div><br></div><div>This shows that setf is implemented differently; maybe it is interesting to compare</div><div>this with other implementations.</div><div><br></div><div><br></div><div>Another thing about the generated warning after POP when a variable is not defined </div><div>using DEFVAR or DEFPARAMETER. </div><div><br></div><div>taoufik-dachraouis-imac:ccl taoufik$ ccl</div><div>Welcome to Clozure Common Lisp Version 1.3-r11936 (DarwinX8632)!</div><div><div>? (setf lst '(1 2 3))</div><div>(1 2 3)</div><div>? (push 0 lst)</div><div>(0 1 2 3)</div><div>? (pop lst)</div><div>;Compiler warnings :</div><div>; In an anonymous lambda form: Undeclared free variable LST (3 references)</div><div>0</div><div><div>? (pprint (macroexpand-1 '(pop lst)))</div><div><br></div><div>(PROG1 (CAR LST) (SETQ LST (CDR (THE LIST LST))))</div><div>? (pprint (macroexpand-1 '(push 0 lst)))</div><div><br></div><div>(SETQ LST (CONS 0 LST))</div><div>? </div><div><br></div><div>In the macroexpansion of POP, unlike PUSH, declares LST to be a LIST (THE LIST LST).</div><div>It is THE that raises the warning. I find this inconsistent that PUSH does not declare </div><div>LST to be a list as in POP or may be both should not use specify the type of lst.</div><div><br></div><div>The CLHS describes THE as follows:</div></div><div><div><br></div><div><span class="Apple-style-span" style="font-family: Times; "><b><font class="Apple-style-span" face="Helvetica"><span class="Apple-style-span" style="font-weight: normal;">"</span></font><a rel="DEFINITION" href="file:///usr/local/doc/HyperSpec/Body/s_the.htm#the">the</a></b> specifies that the <a rel="DEFINITION" href="file:///usr/local/doc/HyperSpec/Body/26_glo_v.htm#value"><i>values</i></a>[1a] returned by <i>form</i> are of the <a rel="DEFINITION" href="file:///usr/local/doc/HyperSpec/Body/26_glo_t.htm#type"><i>types</i></a> specified by <i>value-type</i>. The consequences are undefined if any <i>result</i> is not of the declared type."</span></div></div><div><font class="Apple-style-span" face="Times"><br></font></div><div>It is clear that THE specifies the type of the returned values; I do not understand why THE</div><div>expects an expression if it is a symbol to be dynamic (special).</div><div><br></div><div>The following is to show that THE should not expect nor verify that a variable is dynamic</div><div>and that THE should use the returned values of the expression:</div><div><br></div><div><div>? (setf x 3)</div><div>3</div><div>? (the fixnum x)</div><div>;Compiler warnings :</div><div>; In an anonymous lambda form: Undeclared free variable X</div><div>3</div><div>? (defun f () x)</div><div>;Compiler warnings :</div><div>; In F: Undeclared free variable X</div><div>F</div><div>? (the fixnum (f))</div><div>3</div><div><div>? (the fixnum 3)</div><div>3</div><div>? </div><div><br></div></div><div><br></div><div>Also, according to the standard the consequence is undefined if any result of the expression </div><div>is not of the declared type. What should be undefined here? is it better to raise an error? </div><div><br></div><div>Taoufik</div><div><br></div><div><br></div></div><div>On Oct 18, 2009, at 1:44 AM, Taoufik Dachraoui wrote:</div></div></div><div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi,<br><br>I understand your explantion but what do you think about the following:<br><br>? (setf lst '(1 2 3))<br>(1 2 3)<br>? (push 0 lst)<br>(0 1 2 3)<br>? lst<br>(0 1 2 3)<br>? (pop lst)<br>;Compiler warnings :<br>; In an anonymous lambda form: Undeclared free variable LST (3 references)<br>0<br>? (setf h (make-hash-table))<br>#<HASH-TABLE :TEST EQL size 0/60 #x8F0E5F6><br>? (setf (gethash :a h) 1)<br>1<br>? (gethash :a h)<br>1<br>T<br><br>No warning when using push and gethash<br><br>Taoufik<br><br><br>On Oct 16, 2009, at 9:56 PM, Gary Byers wrote:<br><br><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">On Fri, 16 Oct 2009, David L. Rager wrote:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite">Hi Taoufik,<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">You need to define x to avoid those warnings.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">(defvar *x* '(a b c))<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Note that I'm fairly sure that defvar only sets a variable's value<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">upon initialization. Any subsequent calls to define the same variable<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">are effectively no-ops.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">See also DEFPARAMETER.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">IIRC, I think that if you're in a multi-threaded environment, not<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">defining a variable causes the setf's to be thread-local.<br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">A (special) binding is basically a mapping between a special variable<br></blockquote><blockquote type="cite">name (a symbol) and a value. One trivial and traditional way to<br></blockquote><blockquote type="cite">establish such a binding is to reserve a word in the symbol for<br></blockquote><blockquote type="cite">its global special value; this word is sometimes referred to as the<br></blockquote><blockquote type="cite">symbol's "value cell", and that binding is sometimes called a "static<br></blockquote><blockquote type="cite">binding".<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Things like LET/LET*/LAMBDA can establish new dynamic (and<br></blockquote><blockquote type="cite">thread-local) bindings for special variables.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">SETF/SETQ of a special variable always assign to the current thread's<br></blockquote><blockquote type="cite">current binding of that special variable. The current binding is either<br></blockquote><blockquote type="cite">the most recently established (by LET/LET*/LAMBDA ...) dynamic binding<br></blockquote><blockquote type="cite">or the global static binding if the thread has no dynamic binding.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Things like DEFVAR are usually used at toplevel (in the REPL or in a<br></blockquote><blockquote type="cite">file), and so any assignment that they do usually affects the global,<br></blockquote><blockquote type="cite">static binding.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Back to the original poster's question: in something like:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">? (setq x '(1 2 3))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">what exactly is X ? Let's assume that:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">1) it's not something proclaimed (via DEFCONSTANT) to be the name of<br></blockquote><blockquote type="cite"> a constant<br></blockquote><blockquote type="cite">2) it's not something proclaimed (via DEFVAR, DEFPARAMETER, or other<br></blockquote><blockquote type="cite"> means) to be the name of a SPECIAL (dynamic) variable.<br></blockquote><blockquote type="cite">3) it's not a lexical variable established by a surrounding LET/LET*/<br></blockquote><blockquote type="cite"> LAMBDA/... form that establishes lexical bindings.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">In portable CL, those are the only well-defined possibilities. In<br></blockquote><blockquote type="cite">practice (and in most? all? implementations), there are at least two<br></blockquote><blockquote type="cite">other possibilities:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">4) it's a reference/assignment to the "static binding" of X, e.g., the<br></blockquote><blockquote type="cite"> "value cell of X", which is likely to be a meaningful concept.<br></blockquote><blockquote type="cite">5) it's a typographical error or a symptom of one; it can be treated<br></blockquote><blockquote type="cite"> something like case (4), but is anomalous enough to be worth warning<br></blockquote><blockquote type="cite"> about.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">When compiling a file, it's desirable to treat references/assignments<br></blockquote><blockquote type="cite">to "undeclared free variables" (variables that don't fit into one of<br></blockquote><blockquote type="cite">the first 3 cases above) as being deserving of warnings. Some people<br></blockquote><blockquote type="cite">habitually introduce "undeclared free variables" when typing<br></blockquote><blockquote type="cite">expressions to the REPL; some forms typed into the REPL in CCL are<br></blockquote><blockquote type="cite">handled by very simple evaluator (which generally doesn't try to warn<br></blockquote><blockquote type="cite">about this sort of thing); other forms are "evaluated" by compiling<br></blockquote><blockquote type="cite">them and funcalling the resulting function, and the compiler generally<br></blockquote><blockquote type="cite">does warn in this case.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Some people have requested that warnings like this be suppressed in the<br></blockquote><blockquote type="cite">REPL. I used to be more sympathetic to that than I am now (for whatever<br></blockquote><blockquote type="cite">reason); I think that I've convinced myself that the small extra effort<br></blockquote><blockquote type="cite">involved in saying something like:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">? (defvar *x* '(1 2 3))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">rather than<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">? (setq x '(1 2 3))<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">even for something trival done in the REPL. (Things that start out trivial<br></blockquote><blockquote type="cite">sometimes get at least a bit more complicated, actual typos get introduced,<br></blockquote><blockquote type="cite">and it starts to get hard to remember what "the convenience of not having<br></blockquote><blockquote type="cite">to use DEFVAR when you more-or-less meant to" was all about.)<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">I guess that I'd agree that things should be consistent (and the simple<br></blockquote><blockquote type="cite">evaluator should warn in the same cases that the compiler does), but I<br></blockquote><blockquote type="cite">find it harder to agree that warnings should be suppressed: case (4) above<br></blockquote><blockquote type="cite">isn't all that well-defined and to the extent that pretending that it is<br></blockquote><blockquote type="cite">is a habit, that habit's breakable.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">David<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">_______________________________________________<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Openmcl-devel mailing list<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><a href="mailto:Openmcl-devel@clozure.com">Openmcl-devel@clozure.com</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><a href="http://clozure.com/mailman/listinfo/openmcl-devel">http://clozure.com/mailman/listinfo/openmcl-devel</a><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><br></blockquote><br></div></blockquote></div><br></div></body></html>