Subject: Re: Dynamic variable question From: Erik Naggum <erik@naggum.net> Date: Tue, 07 May 2002 14:21:10 GMT Newsgroups: comp.lang.lisp Message-ID: <3229770069494580@naggum.net> * David Sletten | At first I couldn't figure out how it worked since I thought the LET form | created a lexical variable that FORMAT wouldn't be able to see. There is a difference between a global (pervasive) and a local special declaration that you may have missed. The former is obtained with declaim, the latter with declare. defvar does the declaim part. | In my understanding of lexical/dynamic scope I recognized this | distinction: | (defun foo (x) | (pung)) | | (defun pung () | (1+ x)) | | (foo 2) => ERROR | | Whereas: | (defun foo (x) | (declare (special x)) | (pung)) | | (foo 2) => 3 You should _really_ (declare (special x)) in pung, too. | I've always seen lexical scope described such that a variable is only | visible within the text of the form in which it's defined (e.g., LET, | DEFUN). This implies that the scope of a variable should be clear simply | by looking at the code. If I understand things correctly (now!) this is | wrong. The existence of a dynamic variable in the environment in which a | function is defined can affect the scope of said function's parameters | and local variables. What does it is the special proclamation/declamation, not the variable. The two are strictly speaking separate concepts. You may pervasively declare any symbol to have special binding independent of its top-level binding. In other words, (defvar x) only makes it special, but it is still unbound. You may actually use a symbol for its variable property without making it special. | Do I have things worked out now? Well, no, the underlying mechanism is simpler than you think it is. | If so it seems kind of dangerous that you can't tell the scope of a | function's parameters in isolation. Well, there are dangers in life. Your task is to cope with them. There are also declared constants. | I guess this is one reason to follow the *var* convention Kent recently | mentioned. X would be a parameter, while *X* would be the top level | special variable. Generally speaking, it is wise to use the *var* convention for all special bindings, not just global, special variables. -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief. 70 percent of American adults do not understand the scientific process.