From: Tom Christiansen
Subject: dynamic scoping question
Date: 
Message-ID: <1991Aug24.234723.19887@convex.com>
As I dimly understand these matters, lisp has a scoping problem.
I'd like some confirmation and refererence on it.

The story runs this way:  if routine A passes of chunk of code to routine
B to be evaluated, and that chunk references one of A's variables by name,
but B has happened to name a local variable of its own by the same name,
you're stuck with B's version instead of A's.  This was explained to me as
"the dynamic scoping bug".

My questions are: 

    1) Is this really so?  Is the answer is yes...
    2) Can you somehow force evaluation of the code to be in 
       A's context instead of B's to avoid this problem?
    3) Does anyone have a reference that discusses this issue in 
	 print? (a book, paeer, etc.)


thanks,

--tom

From: Bob Kerns
Subject: Re: dynamic scoping question
Date: 
Message-ID: <1991Aug25.010229.2630@crl.dec.com>
In article <······················@convex.com>, ·······@convex.COM (Tom Christiansen) writes:
> As I dimly understand these matters, lisp has a scoping problem.
> I'd like some confirmation and refererence on it.
> 
> The story runs this way:  if routine A passes of chunk of code to routine
> B to be evaluated, and that chunk references one of A's variables by name,
> but B has happened to name a local variable of its own by the same name,
> you're stuck with B's version instead of A's.  This was explained to me as
> "the dynamic scoping bug".
> 
> My questions are: 
> 
>     1) Is this really so?  Is the answer is yes...
>     2) Can you somehow force evaluation of the code to be in 
>        A's context instead of B's to avoid this problem?
>     3) Does anyone have a reference that discusses this issue in 
> 	 print? (a book, paeer, etc.)

Nope!  Glad you asked; It seems you've been talking to someone who's
been asleep for over a decade, since this has been false for that
long.  Or maybe the explainer is refering to some specific offshoot
dialect which has this characteristic; there are still a few around.

(defun outer (x)
  (inner #'(lambda () x)))

(defun inner (fcn)
  (let ((x 'inner-x))
    (list :inner x :outer (funcall fcn))))

(outer 'outer-x)
will give:

(:inner inner-x :outer outer-x)

This is called "lexical scoping", and is the default.

Of course, if you *WANT* dynamic scoping, you can get it:

(defun outer (x)
  (declare (special x))
  (inner #'(lambda () x)))

(defun inner (fcn)
  (let ((x 'inner-x))
    (declare (special x))
    (list :inner x :outer (funcall fcn))))

(outer 'outer-x)
=>
(:inner inner-x :outer inner-x)

but this is used only in a small percentage of cases.
(And to help keep it straight, by convention, variables which
are used this way are named with asterixes before and after;
i.e. *X*.)

To see what modern Lisp is, I suggest you get a copy of
Guy Steel's "Common Lisp the Language", second edition,
which describes the forthcoming ANSI standard for
Common Lisp.  (The standard isn't finalized yet, but the
differences between the book and the final standard won't
be major).

Now if you want to see scoping bugs, have a look at C
or Pascal!
From: Barry Margolin
Subject: Re: dynamic scoping question
Date: 
Message-ID: <1991Aug25.030405.19272@Think.COM>
In article <······················@convex.com> ·······@convex.COM (Tom Christiansen) writes:
>As I dimly understand these matters, lisp has a scoping problem.
...
>"the dynamic scoping bug".

>    1) Is this really so?  Is the answer is yes...

It depends on the dialect of Lisp.  Maclisp, GNU Emacs Lisp, and maybe
Xlisp use dynamic scoping (actually, Maclisp uses dynamic scoping in the
interpreter, but lexical scoping in the compiler).  Common Lisp (as RWK
mentioned) and Scheme use lexical scoping (but Common Lisp permits selected
variables to be scoped dynamicly (by declaring them "special"), and Scheme
permits selected bindings to be dynamic (this is fluid-let).

>    2) Can you somehow force evaluation of the code to be in 
>       A's context instead of B's to avoid this problem?

In dynamic-scoped Lisps, no.  Lexical Lisps do the right thing.

>    3) Does anyone have a reference that discusses this issue in 
>	 print? (a book, paeer, etc.)

Scheme was the first major Lisp dialect to embrace lexical scoping, so the
early Scheme technical reports may discuss this.  The textbook "Structure
and Interpretation of Computer Programs" may also discuss the issue.
-- 
Barry Margolin, Thinking Machines Corp.

······@think.com
{uunet,harvard}!think!barmar
From: Simon Leinen
Subject: Re: dynamic scoping question
Date: 
Message-ID: <SIMON.91Aug25125818@liasun5.epfl.ch>
In article <·····················@crl.dec.com> ···@crl.dec.com (Bob
Kerns) writes:

   Or maybe the explainer is refering to some specific offshoot
   dialect which has this characteristic; there are still a few
   around.

To add to the list of ``offshoot'' dialects which use dynamic scoping
in the interpreter:

   Standard Lisp
     Portable Standard Lisp (on which the REDUCE system is based)
     Cambridge Lisp

Haven't tried Standard Lisp, but both PSL and Cambridge Lisp compile
lambda variables lexically unless they are declared dynamic (fluid in
their terminology).  Both don't have full lexical closures like Common
Lisp/Scheme.
-- 
Simon.
From: Matthias Felleisen
Subject: Re: dynamic scoping question
Date: 
Message-ID: <1991Aug26.015629.7344@rice.edu>
In article <······················@Think.COM> ······@think.com writes:
> ... Common Lisp (as RWK
>mentioned) and Scheme use lexical scoping (but Common Lisp permits selected
>variables to be scoped dynamicly (by declaring them "special"), and Scheme
>permits selected bindings to be dynamic (this is fluid-let).

Just for clarification: 
Fluid variables in Scheme are *NOT* dynamically scoped variables.
Indeed, FLUID VARIABLES in Scheme are LEXICALLY SCOPED. The facility 
  (fluid-let ((x <value>)) <body>)
is a temporary assignment statement/expression (and should have the
syntax 
  (temporary-set! ((x <value>)) <body>) 
to avoid any confusion). In other words, the variable has a single
lexical binding, but its value temporarily changes.

To see the difference, run the following program in a dynamically
scoped dialect and Scheme:
  (define f
    (let ([x 0])
      (lambda () x)))

  (define x 1)

  (fluid-let ([x 13]) (f))
The former will return 13, the latter produces 0. 

-- Matthias Felleisen
From: Doug Moen
Subject: Re: dynamic scoping question
Date: 
Message-ID: <1991Aug29.153439.1767@sni.ca>
>······@think.com writes:
>> ... Common Lisp (as RWK
>>mentioned) and Scheme use lexical scoping (but Common Lisp permits selected
>>variables to be scoped dynamicly (by declaring them "special"), and Scheme
>>permits selected bindings to be dynamic (this is fluid-let).

········@leto.rice.edu (Matthias Felleisen) writes:
>Just for clarification: 
>Fluid variables in Scheme are *NOT* dynamically scoped variables.
>Indeed, FLUID VARIABLES in Scheme are LEXICALLY SCOPED. The facility 
>  (fluid-let ((x <value>)) <body>)
>is a temporary assignment statement/expression (and should have the
>syntax 
>  (temporary-set! ((x <value>)) <body>) 
>to avoid any confusion). In other words, the variable has a single
>lexical binding, but its value temporarily changes.

Matthias is not quite wrong, but his statement is certainly misleading.

In R1 Scheme, there was a concept of "fluid variables", and they
most certainly were dynamically scoped.  Please see "The Revised Report
on SCHEME" (1978, MIT AI Memo #452) if you don't believe me.

Fluid variables seem to have been deleted from the most recent standard.

The only reference on "fluid-let" I could find was in "The Structure and
Interpretation of Computer Programs":
	Another way to achieve the desirable effects of dynamic binding
	is to use static variables only but to provide a structured means
	for temporarily changing the value of a variable.  ...

In summary, "fluid-let" as defined by SICP does work as Matthias describes,
but "fluid-let" does NOT implement fluid (ie, dynamically scoped) variables,
as defined by the R1 Scheme standard.

Note to the original poster:
"Structure and Interpretation of Computer Programs", by Abelson and Sussman,
1985, the MIT Press, has an excellent discussion of static binding,
dynamic binding, and the upward and downward funarg problems that plagued
early dialects of Lisp.
-- 
Doug Moen | ····@snitor.uucp | uunet!snitor!doug | ········@sni.de (Europe)
From: Niels P. Mayer
Subject: Re: dynamic scoping question
Date: 
Message-ID: <MAYER.91Aug26023256@hplnpm.hpl.hp.com>
In article <······················@Think.COM> ······@think.com (Barry Margolin) writes:
   In article <······················@convex.com> ·······@convex.COM (Tom Christiansen) writes:
   >As I dimly understand these matters, lisp has a scoping problem.
   ...
   >"the dynamic scoping bug".
   ...
   It depends on the dialect of Lisp.  Maclisp, GNU Emacs Lisp, and maybe
   Xlisp use dynamic scoping


Xlisps >= version 2.0 have lexical scoping. It didn't start out that way,
but eventually moved in that direction. I haven't used XLISP before version
2.0, so I don't know what it was like in the old days.

Xlisp version 2.1c (Tom Almy's bugfixed and more CL compatible xlisp 2.1)
has 'special variables' via 'defparameter' available as an compilation
option. I haven't had a chance to use this dynamic scoping enhancement.


-------------------------------------------------------------------------------
	    Niels Mayer -- hplabs!mayer -- ·····@hplabs.hp.com
		  Human-Computer Interaction Department
		       Hewlett-Packard Laboratories
			      Palo Alto, CA.
				   *
From: John Sybalsky
Subject: Re: dynamic scoping question
Date: 
Message-ID: <1991Aug29.044630.12367@parc.xerox.com>
>   In article <······················@convex.com> ·······@convex.COM (Tom Christiansen) writes:
>   >As I dimly understand these matters, lisp has a scoping problem.
>   ...
>   >"the dynamic scoping bug".
>   ...
>   It depends on the dialect of Lisp.  Maclisp, GNU Emacs Lisp, and maybe
>   Xlisp use dynamic scoping
>
>

And in Medley, you can play it either way!  Being a merger of Interlisp and 
Common Lisp, it's set up to let things default either way:  If you're
writing Interlisp code, the default is dynamic scoping; with Common Lisp
code, it's lexical.

--John
-- 

--John

········@parc.xerox.com