Newsgroups: comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!bb3.andrew.cmu.edu!newsfeed.pitt.edu!gatech!EU.net!usenet2.news.uk.psi.net!uknet!usenet1.news.uk.psi.net!uknet!uknet!newsfeed.ed.ac.uk!edcogsci!jeff
From: jeff@cogsci.ed.ac.uk (Jeff Dalton)
Subject: Re: EVAL Implementations
X-Nntp-Posting-Host: pitcairn
Message-ID: <DwrDLA.26q@cogsci.ed.ac.uk>
Sender: cnews@cogsci.ed.ac.uk (C News Software)
Organization: HCRC, University of Edinburgh
References: <3049576919413620@arcana.naggum.no> <4virns$3te@Venus.mcs.com> <3049754333170201@arcana.naggum.no>
Date: Mon, 26 Aug 1996 18:48:46 GMT
Lines: 200

In article <3049754333170201@arcana.naggum.no> Erik Naggum <erik@naggum.no> writes:
>Robert Munyer's exceedingly lengthy diatribe seems to hinge on one issue:
>whether the semantics of `setq' at top-level of a variable that has not
>been declared special is defined by Common Lisp.  I can't see that it is.
>I'd like Robert to show me how he found the semantics of this to be defined
>by the language specification since he makes so many conclusion based on
>his assumption that its semantics _is_ defined.

It's not clear that the standard is entirely consistent with itself.
In section 3.1.2.1.1.2, Dynamic Variables, it says

  A dynamic variable can be referenced at any time in any program;
  there is no textual limitation on references to dynamic variables. At
  any given time, all dynamic variables with a given name refer to
  exactly one binding, either in the dynamic environment or in the
  global environment.

  ...

  A dynamic variable can be referenced outside the dynamic extent of a
  form that binds it. Such a variable is sometimes called a ``global
  variable'' but is still in all respects just a dynamic variable whose
  binding happens to exist in the global environment rather than in some
  dynamic environment.

Yet in the glossary we find:

  dynamic variable n. a variable the binding for which is in the
  dynamic environment. See special.

Nothing about the global environment _there_.

3.1.2.1.1.2 also says

  A variable is a dynamic variable if one of the following conditions hold: 

    * It is locally declared or globally proclaimed special. 

    * It occurs textually within a form that creates a dynamic binding
      for a variable of the same name, and the binding is not shadowed[2]
      by a form that creates a lexical binding of the same variable name. 

The 1st item just above suggests that Eric may be right, so far as the
ANSI standard is concerned.  However, "if" is not the same as "only if"
or "if and only if", so perhaps things aren't as clear here as they
might be.  "No textual limitation" and the (so far as I know) lack
of anything that says the semantics are _not_ defined, suggests that
free refs are refs to global special variables.  (N.B. special but
not _proclaimed_ special, an important distinction.  Special
proclamations make all bindings of the name special, declarations don't.)

In 3.1.2.1.1, Symbols as Forms, we find:

  If a form is a symbol that is not a symbol macro, then it is the
  name of a variable, and the value of that variable is returned. There
  are three kinds of variables: lexical variables, dynamic variables,
  and constant variables. A variable can store one object. The main
  operations on a variable are to read[1] and to write[1] its value.

There's no hint here (or anywhere else that I've found) that's
another case: variables that aren't lexical or constant yet not
dynamic either because there's hasn't been a special proclamation
or declaration.  Moreover, the description of setq uses examples such
as the following without any declarations or proclamations:

 ;; A simple use of SETQ to establish values for variables.
 (setq a 1 b 2 c 3) =>  3
 a =>  1
 b =>  2
 c =>  3

CLtL 2 is perhaps clearer.  Section 5.1.2 (p 70) says

  ... if the symbol occurs textually within a program construct
  that creates a _binding_ for a variable of the same name, then
  the reference is to the variable specified by the binding; if
  no such program construct textually contains the reference,
  then it is taken to refer to the special variable of that name.

The description of setq (p 121) is less clear than it might be,
since it says only that "the usual rules" determine whether
the variable being assigned to is lecical or dynamic.  But I
think it's fair to conclude at least that there's not meant
to be a difference between the rules for assignment and the
rules for reference.

Section 7.1.1, Reference (p 114) says that whether the variable
is special or lexical depends on the presence of absence of a
special declaration; but I don't think that is meant to contradict
page 70.

However, the situation is muddued by the pactice in many
implementations of giving warnings on references to undeclared
free variables.  Language such as "assumed to be special" is
often used.  This is because implementors suspect that most
such cases are unintentional and indicate mistakes in the code.

>barring any overlooked clauses which Robert will bring to my attention,
>whatever it is that he's trying to distinguish between `setq' and `defvar'
>at top-level is purely a matter of how _implementations_ differ in
>implementing undefined semantics.

I don't think so.  For one thing, there isn't much variation between
implementations.  So far as I know (and I've used over a dozen Common
Lisps), they all interpret references (including in assignments) to
undeclared free variables as refrences to the special variable.
They differ in whether and when they give a warning.  Most
implementations do not give a warning except when compiling.
CMU CL is an exception.  I suspect it's the only one.  In any
case, it has the behaviour I'd expect from p 70.  E.g.

* (setq x 1)
Warning:  Declaring x special.
1

* (setq x 2)
2

* (defun fx () x)

* (fx)
2

>the question is: does ANSI Common Lisp (or CLtL2 for that matter) define
>the semantics of `setq' at top-level, including whether the symbol should
>be declared or proclaimed special?  this is a very specific question, and I
>will hear no more about Robert's delusions of "vagueness" in response.

Well, neither the standard not CLtL 2 makes things entirely and
explicitly clear.  But I've never, before this, heard it suggested
that the semantics was not defined, not even in X3J13 discussions that
covered this area when considering the PROCLAIM-LEXICAL issue.  It was
noted that the warnings mentioned above made it a pain in practice to
use undeclared free refs; but that's about as far as it went.

For instance, from PROCLAIM-LEXICAL version 2:

Description of problem:

  CLtL pp. 55-56 implies that if a name (symbol) is not proclaimed or
  declared special, then a free reference to that name is a reference to
  the special variable of that name, while a LAMBDA-binding of that name
  indicates a binding of the lexical variable of that name.  This would
  mean that the following program is legal and that (TST) => 4:

    (defun tst ()
      (setq x 3)
      (funcall (let ((x 4)) #'(lambda () x))))

  However, if you feed this program to many Common Lisp compilers
  (including Symbolics's and DEC's), a warning message will be
  produced for the SETQ, saying something like "Warning: X not
  declared or bound, assuming special."

  These warnings, unlike the annotations of undefined functions (which
  occur only at the end of a compilation), are presented so
  prominently that a user would be hard put to say that a program
  which elicited such warning messages was "correct" in that
  implementation.  Unlike the situation with unused variables, there is
  no possible declaration one can write which suppresses the warning
  messages.

  This disagreement between theory and practice should be mended
  somehow.

Proposal (PROCLAIM-LEXICAL:CURRENT-PRACTICE):

  Change the language definition (page 55?) to say that it is an error
  for there to be a free reference or assignment to a name unless a
  SPECIAL proclamation or declaration is in effect for that name.

  This would legitimize the behavior of current implementations.

Proposal (PROCLAIM-LEXICAL:BY-THE-BOOK):

  Shame implementors into going by the book.  Implementations should
  simply stop intimidating users who want to write code like this.
  "Apparently unbound variable" warnings should be given the same
  purely advisory status that "apparently undefined function" warnings
  now enjoy.  The exact meaning of this is of course implementation-
  dependent.

[... omitting, among other things, other proposals ...]

Cost of adopting change:

  CURRENT-PRACTICE: Ostensibly none, although implementations which
  don't signal this as an error should be explicitly encouraged
  to do so.  It ought to be signalled in interpreted code as well.

  BY-THE-BOOK: This would be an easy fix to the error reporting and
  bookkeepping components of existing compilers.  Of course it is not
  a change to the language, so there is no impact on portable code.

(Later versions of the proposal use more neutral language and
went into more technical detail about the proposed semantics.
But this version is better than later ones as a guide to how
the issue was seen and the motivations for change.)

-- jd
