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.