From: D. Michael McFarland
Subject: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <m3bto27cpj.fsf@localhost.localdomain>
I guess it's time to delurk.

I've been working my way through Robert Wilensky's _Common LISPcraft_,
and have hit a snag running an example he uses to demonstrate the
scope of variables.  In Section 3.4 he defines the functions

(defun sum-average (x y)
   (setq sum (+ x y))
   (/ sum 2))

(defun sum-average-caller (sum x y)
   (sum-average x y) sum)

and then, at the top level, assigns

(setq sum '(a b c))

The purpose of the example is to demonstrate the effect of
sum-average-caller on this variable sum.

Using clisp and Wilensky's sample input I get

> (sum-average-caller 0 55 65)
0
> sum
120

which agrees with the text.  However, with the same definitions in CMU 
CL, the results are much different:

* (sum-average-caller 0 55 65)
120
* sum
(A B C)

Naturally, this is the Lisp I tried first. :-)

I'd appreciate any insights anyone can offer into which result is
"correct", how two CL implementations can differ on what seems a
fundamental point, or what I could have done wrong.

Best regards,
Michael

--
    D. Michael McFarland    <········@neca.com>

From: Erik Naggum
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <3115842049861794@naggum.no>
* ········@neca.com (D. Michael McFarland)
| I'd appreciate any insights anyone can offer into which result is
| "correct", how two CL implementations can differ on what seems a
| fundamental point, or what I could have done wrong.

  it was a really bad example.  it tried to show you that the SUM in
  SUM-AVERAGE-CALLER is not the same SUM as that in SUM-AVERAGE, but it
  attempts to use a "global, non-special variable", and those do not
  actually exist in Common Lisp.

  the example depends on the effects of the form (setq sum '(a b c)) when
  evaluated at top-level.  CMUCL marks SUM as special, in effect performs a
  DEFVAR, which means SUM-AVERAGE-CALLER actually _binds_ the SUM that
  SUM-AVERAGE sets, so the outermost (= global) binding is not affected.
  CLISP and Wilensky assume that it is valid for a variable to be assigned
  a value in the top-level loop without being special.

  the reasonable behavior is to assume that a variable that is not closed
  over lexically has a special binding.  if setting the value of a
  previously unbound symbol also causes it to be marked special in the
  top-level loop, I'd consider that a nicety of the implementation for most
  uses, but is by no means a requirement, and good Common Lisp programmers
  never rely on the effects of such operations, anyway.  one could also
  argue that it would be a pain to declare variables you set at top-level
  special just because you need them to have some value when testing code,
  and I have come to think this is why some implementations don't do it.
  but, come to think of it, CMUCL prints a warning that it declares such a
  variable special, which you _should_ have noticed -- it's what lawyers
  call "material evidence".  :)

#:Erik
From: Rainer Joswig
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <joswig-2709980424240001@194.163.195.67>
In article <················@naggum.no>, Erik Naggum <······@naggum.no> wrote:

>   the reasonable behavior is to assume that a variable that is not closed
>   over lexically has a special binding.

I would rather not assume that. It would introduce unnecessary
errors in interactive use. Implementations like ACL, LW, MCL, Genera
are doing it "right". AFAIK, only CMU CL is different.
From: Barry Margolin
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <jShP1.11$cR3.554601@burlma1-snr1.gtei.net>
In article <·······················@194.163.195.67>,
Rainer Joswig <······@lavielle.com> wrote:
>In article <················@naggum.no>, Erik Naggum <······@naggum.no> wrote:
>
>>   the reasonable behavior is to assume that a variable that is not closed
>>   over lexically has a special binding.
>
>I would rather not assume that. It would introduce unnecessary
>errors in interactive use. Implementations like ACL, LW, MCL, Genera
>are doing it "right". AFAIK, only CMU CL is different.

That's not what I recall.  When you compiled code in most Lisps and it saw
a reference to a free variable, it would warn "Assuming variable SUM is
special."  In other words, a top-level form like:

(setq sum '(a b c))

was treated as:

(locally
  (declare (special sum))
  (setq sum '(a b c)))

In the interactive interpreter they didn't print warnings, but behaved
similarly.

The difference in CMUCL is that it interprets it as:

(declaim (special sum))
(setq sum '(a b c))

As a result, the first mention of a free variable will have pervasive
effects on the rest of your code (or session, if you enter it
interactively) in CMUCL, resulting in the strange results in the original
post.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
From: Erik Naggum
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <3115877644197036@naggum.no>
* Erik Naggum <······@naggum.no>
| the reasonable behavior is to assume that a variable that is not closed
| over lexically has a special binding.

* ······@lavielle.com (Rainer Joswig)
| I would rather not assume that.  It would introduce unnecessary errors in
| interactive use.  Implementations like ACL, LW, MCL, Genera are doing it
| "right".  AFAIK, only CMU CL is different.

  CMUCL does not _assume_ that, it actively goes ahead and declares it
  special.  to me, that is a hell of a difference.

  when is it legitimate, then, to _assume_ special bindings for undeclared
  variables?  I thought it would be sufficiently clear that it would be
  under evaluation and compilation.  when else would it be meaningful to
  discuss this?  i.e., SUM in SUM-AVERAGE is assumed to have special
  binding.  what else would it be when it is not closed over lexically?
  suggestions?

#:Erik
From: Rainer Joswig
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <joswig-2709981337070001@194.163.195.67>
In article <················@naggum.no>, Erik Naggum <······@naggum.no> wrote:

> * Erik Naggum <······@naggum.no>
> | the reasonable behavior is to assume that a variable that is not closed
> | over lexically has a special binding.
> 
> * ······@lavielle.com (Rainer Joswig)
> | I would rather not assume that.  It would introduce unnecessary errors in
> | interactive use.  Implementations like ACL, LW, MCL, Genera are doing it
> | "right".  AFAIK, only CMU CL is different.
> 
>   CMUCL does not _assume_ that, it actively goes ahead and declares it
>   special.  to me, that is a hell of a difference.

That's right. I'd rather not like to see it declaring it special.
This is what I meant.
From: Howard R. Stearns
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <3612412F.9B9017B3@elwood.com>
Rainer Joswig wrote:
> 
> In article <················@naggum.no>, Erik Naggum <······@naggum.no> wrote:
> 
> > * Erik Naggum <······@naggum.no>
> > | the reasonable behavior is to assume that a variable that is not closed
> > | over lexically has a special binding.
> >
> > * ······@lavielle.com (Rainer Joswig)
> > | I would rather not assume that.  It would introduce unnecessary errors in
> > | interactive use.  Implementations like ACL, LW, MCL, Genera are doing it
> > | "right".  AFAIK, only CMU CL is different.
> >
> >   CMUCL does not _assume_ that, it actively goes ahead and declares it
> >   special.  to me, that is a hell of a difference.
> 
> That's right. I'd rather not like to see it declaring it special.
> This is what I meant.

Another point, in my opinion, that suggests CMUCL is going to far in
making the variable special, is that there is no good way to make a
variable no longer be special.  In other words, you can't undo what
CMUCL does for you. 

Using CMUCL, I've often resorted to uninterning the symbol and
recompiling effected code.  Yuk.  Perhaps some CMUCL guru can tell me
the intended CMUCL idiom is for undoing the damage.
From: Jeff Dalton
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <x2iui5lo3g.fsf@gairsay.aiai.ed.ac.uk>
There are a couple of issues here.  One is that Common Lisp does not
have global variables that are not special.  A ref to a free var has
to be a ref to the special of that name or else be taken as referring
to nothing and hence presumably an error.  So it's reasonable for
implementations to "assume" that the intention is to refer to the
special variable.

The other issue -- described in Barry Margolin's article -- is the
difference between (a) declaring something special with declare, and
(b) making it special using proclaim, declaim, or defvar.  (b) has a
pervasive effect, and I don't know of any CL other than CMU CL that
does (b) without being explicitly told to do so by the user.

However, when this came up a while back, it appeared that the CL
standard allows CMU CL's behaviour, even though it's at least
arguable that CLtL did not.  I can't recall X3J13 ever explicitly
deciding that the CMU CL behaviour should be allowed, but perhaps
Barry or KMP can remember something I've overlooked or forgotten.

-- jd
From: D. Michael McFarland
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <m3af3h6lfw.fsf@localhost.localdomain>
In response to my original post, Erik Naggum <······@naggum.no> wrote:
>   [...]
>   but, come to think of it, CMUCL prints a warning that it declares such a
>   variable special, which you _should_ have noticed -- it's what lawyers
>   call "material evidence".  :)
> 
> #:Erik

Erik,

Thank you for the explanation of the behavior I observed.  Re what I
_should_ have noticed, I did indeed see the message from CMU CL, but
did not know enough at the time I first encountered it to appreciate
its implications.  Ignorance of the law, your honor. :)

Michael
From: Rainer Joswig
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <joswig-2709980123010001@194.163.195.67>
In article <··············@localhost.localdomain>, ········@neca.com (D.
Michael McFarland) wrote:

> I'd appreciate any insights anyone can offer into which result is
> "correct", how two CL implementations can differ on what seems a
> fundamental point, or what I could have done wrong.

The result depends on what kind of variable SUM is being declared.
If it is a special variable introduced for example by (defvar sum '(a b c))
you will get the second result. The first result is the lexical
version. It is common usage to write global variables being introduced
by DEFVAR or DEFPARAMETER like *sum* so that the difference
is visible.

You would need to check if SUM is a special variable in CMU CL.
Actually:

CMU Common Lisp 18b, running on meta
Send questions and bug reports to your local CMU CL maintainer, or to
··········@cons.org. and ·········@cons.org. respectively.
Loaded subsystems:
    Python 1.0, target SPARCstation/Solaris 2
    CLOS based on PCL version:  September 16 92 PCL (f)

* (setq sum '(a b c))
Warning:  Declaring SUM special.

Huh?

This is not what I would want from a Common Lisp.
Maybe some of the CMU CL maintainers can shed a light on this.
I guess it should be changed. Genera and MCL do it differently.
Others?


Greetings,

Rainer Joswig
From: Georg Bauer
Subject: Re: "Wrong" results from _Common LISPcraft_ scope example
Date: 
Message-ID: <gb-2909982056270001@jill.westfalen.de>
In article <·······················@194.163.195.67>, ······@lavielle.com
(Rainer Joswig) wrote:

>* (setq sum '(a b c))
>Warning:  Declaring SUM special.
>
>Huh?

Hmm. I remember something about toplevel-variables always to be special
variables - so you can rebind them dynamically. Might be that I am far off
the track, though. 

bye, Georg

-- 
http://www.westfalen.de/hugo/