From: Spitfire
Subject: lexical scoping
Date: 
Message-ID: <eu79bp$iqr$1@newsreader.wustl.edu>
   I'm having trouble understanding the concept of "dynamic scoping". A 
small example that I wrote to understand the concept is as follows:

[code]


(defvar *status* "I'm running amuck")

(defun report-status ()
   (format t *status*))

(defun query-current-status ()
   (let ((*status* "I'm rolling on the floor laughing"))
         (report-status)))


[/code]


   Now the argument I found for dynamic scoping in this example is that 
when the function "query-current-status", the call to function 
"report-status" inside it will print the status string as "I'm rolling 
on the floor laughing", instead of "I'm running amuck". Isn't this 
simply a concept of variable name shadowing? I look at it simple as a 
local variable shadowing the value of a global variable. Doesn't this 
work even in lexically scoped languages?

ciao,

-- 
_ _ _]{5pitph!r3}[_ _ _
__________________________________________________
“I'm smart enough to know that I'm dumb.”
   - Richard P Feynman

From: Kaz Kylheku
Subject: Re: lexical scoping
Date: 
Message-ID: <1174876313.775191.118220@n76g2000hsh.googlegroups.com>
On Mar 25, 6:58 pm, Spitfire <············@gmail.com> wrote:
>    I'm having trouble understanding the concept of "dynamic scoping". A
> small example that I wrote to understand the concept is as follows:
>
> [code]
>
> (defvar *status* "I'm running amuck")
>
> (defun report-status ()
>    (format t *status*))
>
> (defun query-current-status ()
>    (let ((*status* "I'm rolling on the floor laughing"))
>          (report-status)))
>
> [/code]
>
>    Now the argument I found for dynamic scoping in this example is that
> when the function "query-current-status", the call to function
> "report-status" inside it will print the status string as "I'm rolling
> on the floor laughing", instead of "I'm running amuck". Isn't this
> simply a concept of variable name shadowing?

Shadowing simply means that one thing occludes another and is visible
in its place. So yes, it is a case of shadowing. The rebinding of the
dynamic variable causes the old binding to be shadowed by the new
binding.

Both dynamic scope and lexical scope are capable of different kinds of
shadowing.

> I look at it simple as a
> local variable shadowing the value of a global variable. Doesn't this
> work even in lexically scoped languages?

No, because under lexical scope, the shadow is not inherited by the
chain of functions that the lexical scope calls into.  If *STATUS* was
a global lexical variable (something that Common Lisp doesn't have out-
of-the-box, note well), then REPORT-STATUS would simply refer to the
global binding which contains "I am running amuck", because that would
be the one in its lexical scope. Nothing that any caller of REPORT-
STATUS could do would cause it to see a different binding. (Of course,
a caller could assign a different value into the global binding, which
isn't what we are interested in).

Under dynamic scope, the shadow is visible to anything which is called
from within the block where the shadow is established. When that block
terminates, the shadow is removed.

That is why REPORT-STATUS has access to the value of the shadowing
binding even though it is not lexically enclosed within the LET block
which establishes that value.

Lexical scope does not do this by definition; it does not reach back
through the run-time calling chain to locate bindings. Lexical scope
resolves only bindings which are set up in syntactically enclosing
constructs.
From: Spitfire
Subject: Re: lexical scoping
Date: 
Message-ID: <eu7dnd$iqr$2@newsreader.wustl.edu>
Kaz Kylheku wrote:
> On Mar 25, 6:58 pm, Spitfire <············@gmail.com> wrote:
>>    I'm having trouble understanding the concept of "dynamic scoping". A
>> small example that I wrote to understand the concept is as follows:
>>
>> [code]
>>
>> (defvar *status* "I'm running amuck")
>>
>> (defun report-status ()
>>    (format t *status*))
>>
>> (defun query-current-status ()
>>    (let ((*status* "I'm rolling on the floor laughing"))
>>          (report-status)))
>>
>> [/code]
>>
>>    Now the argument I found for dynamic scoping in this example is that
>> when the function "query-current-status", the call to function
>> "report-status" inside it will print the status string as "I'm rolling
>> on the floor laughing", instead of "I'm running amuck". Isn't this
>> simply a concept of variable name shadowing?
> 
> Shadowing simply means that one thing occludes another and is visible
> in its place. So yes, it is a case of shadowing. The rebinding of the
> dynamic variable causes the old binding to be shadowed by the new
> binding.
> 
> Both dynamic scope and lexical scope are capable of different kinds of
> shadowing.
> 
>> I look at it simple as a
>> local variable shadowing the value of a global variable. Doesn't this
>> work even in lexically scoped languages?
> 
> No, because under lexical scope, the shadow is not inherited by the
> chain of functions that the lexical scope calls into.  If *STATUS* was
> a global lexical variable (something that Common Lisp doesn't have out-
> of-the-box, note well), then REPORT-STATUS would simply refer to the
> global binding which contains "I am running amuck", because that would
> be the one in its lexical scope. Nothing that any caller of REPORT-
> STATUS could do would cause it to see a different binding. (Of course,
> a caller could assign a different value into the global binding, which
> isn't what we are interested in).
> 
I can understand what you are saying!

> Under dynamic scope, the shadow is visible to anything which is called
> from within the block where the shadow is established. When that block
> terminates, the shadow is removed.
> 

This was very insightful, and I totally overlooked it. Thanks!

> That is why REPORT-STATUS has access to the value of the shadowing
> binding even though it is not lexically enclosed within the LET block
> which establishes that value.
> 
> Lexical scope does not do this by definition; it does not reach back
> through the run-time calling chain to locate bindings. Lexical scope
> resolves only bindings which are set up in syntactically enclosing
> constructs.
> 


-- 
_ _ _]{5pitph!r3}[_ _ _
__________________________________________________
“I'm smart enough to know that I'm dumb.”
   - Richard P Feynman
From: Ken Tilton
Subject: Re: lexical scoping
Date: 
Message-ID: <CiGNh.46$7Z3.28@newsfe12.lga>
Spitfire wrote:
>   I'm having trouble understanding the concept of "dynamic scoping". A 
> small example that I wrote to understand the concept is as follows:
> 
> [code]
> 
> 
> (defvar *status* "I'm running amuck")
> 
> (defun report-status ()
>   (format t *status*))
> 
> (defun query-current-status ()
>   (let ((*status* "I'm rolling on the floor laughing"))
>         (report-status)))
> 
> 
> [/code]
> 
> 
>   Now the argument I found for dynamic scoping in this example is that 
> when the function "query-current-status", the call to function 
> "report-status" inside it will print the status string as "I'm rolling 
> on the floor laughing", instead of "I'm running amuck". Isn't this 
> simply a concept of variable name shadowing? I look at it simple as a 
> local variable shadowing the value of a global variable. Doesn't this 
> work even in lexically scoped languages?

If it is a local variable, how would report-status see it? You did not 
pass it to report-status. That is the point you missed: how would the 
same code in C work? Nor did you assign a value to *status* after saving 
the original value, restoring it later, as one would with a global in C.

hth,kt

-- 

"As long as algebra is taught in school,
there will be prayer in school." - Cokie Roberts

"Stand firm in your refusal to remain conscious during algebra."
    - Fran Lebowitz

"I'm an algebra liar. I figure two good lies make a positive."
    - Tim Allen

"Algebra is the metaphysics of arithmetic." - John Ray

http://www.theoryyalgebra.com/
From: Spitfire
Subject: Re: lexical scoping
Date: 
Message-ID: <eu7dp5$iqr$3@newsreader.wustl.edu>
Ken Tilton wrote:
> If it is a local variable, how would report-status see it? You did not 
> pass it to report-status. That is the point you missed:

Yes! True! Thanks for the pointers.

-- 
_ _ _]{5pitph!r3}[_ _ _
__________________________________________________
“I'm smart enough to know that I'm dumb.”
   - Richard P Feynman
From: Ron Garret
Subject: Re: lexical scoping
Date: 
Message-ID: <rNOSPAMon-70A5DF.23392225032007@news.gha.chartermi.net>
In article <············@newsreader.wustl.edu>,
 Spitfire <············@gmail.com> wrote:

>    I'm having trouble understanding the concept of "dynamic scoping".

http://www.flownet.com/ron/specials.pdf

rg
From: Alan Crowe
Subject: Re: lexical scoping
Date: 
Message-ID: <86ps6vbxo3.fsf@cawtech.freeserve.co.uk>
CL-USER> (let ((x 1)
               (y 2))
           (declare (special y))
           (flet ((f ( #|I ain't got no parameters|# )
                    ;; Where oh where will
                    ;; my x and y come from?
                    (list x y)))
             (let ((x 3)
                   (y 4))
               (declare (special y)
                        (ignorable x))
               (f))))
(1 4)

Play!

Alan Crowe
Edinburgh
Scotland
From: viper-2
Subject: Re: lexical scoping
Date: 
Message-ID: <1175212699.551139.280600@y80g2000hsf.googlegroups.com>
On Mar 25, 8:58 pm, Spitfire <············@gmail.com> wrote:
>    I'm having trouble understanding the concept of "dynamic scoping".



Here is my understanding of dynamic scooping.

First, you need to recognize that there are 2 mechanisms for binding
variables in Lisp (we refer loosely to a variable's binding as the
storage location for the value of the variable). Lisp's default
mechanism is lexical binding, the other is dynamic binding, which is
what you are concerned about.

When a variable is lexically bound, it appears as a parameter of the
procedure, LET, or DO form in which it is found. When a lexically
bound variable is referenced, Lisp knows that its binding is attached
to the procedure's (LET's or DO's) lexical environment i.e., it has
lexical scope.

On the other hand, when a variable is dynamically bound its binding is
attached not to any lexical environment, but to a record of calls
conceptually simulated as a stack. Lisp knows that a variable is to be
treated as dynamic when it has been declared to be so using, for
example, a DEFVAR form. The "special" variable so declared has its
binding attached to a stack.

Dynamic variables are useful in cases where you may want to
temporarily change the value of a variable so that some procedure and
those called by it behave in a certain way without having to suffer
the inconvenience of passing the parameter as an argument from
procedure to procedure. This temporary state of affairs ceases once
the original calling procedure returns and the variable's original
value is restored.

Each successive call by a procedure (LET or DO) can rebind the
variable with a different value. Each time the variable is rebound the
new value is pushed onto the top of the stack where it becomes the
reference for all current evaluations of that variable, masking or
shadowing all previous values pushed onto the stack. When the binding
form returns, this value is popped from the stack and the previous
value - i.e. the value before execution of the binding form - again
becomes the current reference for evaluations. Reassigning a new value
to the variable using SETF or SETQ changes the value of the variable
at the top of the stack, but does not alter the height of the stack.

Battlestar Galactica fans might enjoy the following code, which is
illustrative of dynamic scope:


;;;Kara.lsp

#|In a Cylon-infested universe it is safer to assume that everyone is
a Cylon
unless proven otherwise; so we declare CYLON to be a special variable.|
#

> (defvar cylon)
CYLON


#|Cylons and humans are represented as lists, where the FIRST of the
list denotes whether the entity is cylon or human. For example, Sharon
Athena Agathon, who is a cylon, would be represented as (cylon sharon
athena agathon), while Lee Adama who is human would be represented as
(human lee adama). Subsequent elements may be added to the list to
depict characteristics of the entity being represented.|#

#|The cylons have found a way to use their resurrection ship to effect
alterations that disguise cylons as humans, and human collaborators as
cylons. This is of course accomplished by changing the FIRST of the
list.|#

#|The procedure HUMAN-RESURRECTION transforms a cylon so that he/she
appears to be human.|#

>(defun human-resurrection (cylon)
  (print cylon)

#|But Gaclactica's hackers have found a way, with the help of Athena,
to secretly plant some code in the resurrection ship to test whether
or not the entity being resurrected is really a cylon |#

  (locally (declare (special cylon-test)) (setf cylon-test cylon))
  ;We can declare a variable as special locally with (DECLARE
(SPECIAL ...
  (let ((cylon (cons 'human (rest cylon))))
    (print cylon)
    (board-galactica)) ;The altered cylon boards Galactica as a spy
and returns to the resurrection ship where he/she is restored as a
cylon.
  (print cylon))
HUMAN-RESURRECTION


>(defun board-galactica ()
  (let ((cylon (append cylon '(galactica))))
    (print cylon)
    (make-viper-pilot) ;The cylon becomes a viper-pilot
    (galactica-knows))) ;But Galactica's hackers can test if he/she is
really a cylon in disguise.
BOARD-GALACTICA


>(defun make-viper-pilot ()
  (let ((cylon (append cylon '(viper-pilot))))
    (print cylon)
    (make-hotshot))) ;The cylon becomes a hotshot viper pilot!
MAKE-VIPER-PILOT


>(defun make-hotshot ()
  (let ((cylon (append cylon '(hotshot))))
    (print cylon)))
MAKE-HOTSHOT


>(defun galactica-knows ()
  (if (eql (first cylon-test) 'human)  (print 'human)
      (print (append (list (second cylon)) '(is a cylon - oh
fraktals!!)))))
GALACTICA-KNOWS
;Galactica's hackers are also mathematicians!


#|Kara Thrace's strange reappearance in the finale of season 3 might
indicate that she was a cylon all along.|#

>(human-resurrection '(cylon Kara Thrace))
(CYLON KARA THRACE)
(HUMAN KARA THRACE)
(HUMAN KARA THRACE GALACTICA)
(HUMAN KARA THRACE GALACTICA VIPER-PILOT)
(HUMAN KARA THRACE GALACTICA VIPER-PILOT HOTSHOT)
(KARA IS A CYLON - OH FRAKTALS!!)
(CYLON KARA THRACE)
(CYLON KARA THRACE)


#|The procedure HUMAN-RESURRECTION-2 uses SETF to make the cylon-human
transformation more permanent|#

>(defun human-resurrection-2 (cylon)
  (print cylon)
  (locally (declare (special cylon-test)) (setf cylon-test cylon))
  (setf cylon (cons 'human (rest cylon)))
  (print cylon)
  (board-galactica)
  (print cylon)) ;This time SETF made restoration to a cylon more
difficult.
HUMAN-RESURRECTION-2


>(human-resurrection-2 '(cylon Kara Thrace))
(CYLON KARA THRACE)
(HUMAN KARA THRACE)
(HUMAN KARA THRACE GALACTICA)
(HUMAN KARA THRACE GALACTICA VIPER-PILOT)
(HUMAN KARA THRACE GALACTICA VIPER-PILOT HOTSHOT)
(KARA IS A CYLON - OH FRAKTALS!!)
(HUMAN KARA THRACE)
(HUMAN KARA THRACE)



The value of CYLON corresponds to the value at the top of the stack,
which grows as each LET establishes a new binding and shrinks as the
LETs return eliminating their bindings. Note that the procedure HUMAN-
RESURRECTION-2 uses SETF to effect the cylon to human transformation.
The assignment by SETF changed the value of the existing binding
attached to the top of the stack of value slots, leaving the height of
the stack unchanged. So when KARA returned from BOARD-GALACTICA, she
returned in her human form and not as a cylon.

By contrast, in the first procedure, HUMAN-RESURRECTION, a LET
accomplished the cylon to human transformation by establishing a new
binding which pushed a new value slot onto the stack. This slot was
popped on KARA'S return from BOARD-GALACTICA and she resumed her cylon
form.

Also observe that had we not DEFVARed CYLON, running the program would
have given an error:
Error in EVAL [or a callee] : The variable CYLON is unbound.

The following online sources should help to clear up any question you
might have on special variables:

1)	Practical Common Lisp by Peter Seibel, http://www.gigamonkeys.com/book/variables.html

2)	The Idiot's Guide to Special Variables and Lexical Closures, by
Erann Gat, http://www.flownet.com/ron/specials.pdf

3)	See also Dave Roberts' post on Special vs Lexical Variables at
http://www.findinglisp.com/blog/2004/05/special-vs-lexical-variables.html