From: Bill Richter
Subject: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <RICHTER.95Jul19084033@banach.math.purdue.edu>
I'm a pure mathematician (temporarily derailed from the Math gravy
train) turned Scheme newbie, with a passing familiarity with Emacs
Lisp.  I'm really enjoying the Scheme texts SICP and (even more!) EPL.

I'm confused by the description of the Scheme function `set!', called
a "mutation procedure."  EPL warns that "bang signals danger ... hard
to reason," seems to indicate (by proximity of first usage, p 126, p
129) that `set!' is close to OOP.  SICP first mentions `set!' p 170:
"no simple model with `nice' mathematical properties can be an
adequate framework," that mutations wreck their nice substitution
model for procedure calls.  One gets the impression that the Scheme
`set!' is much more complicated that the Lisp `setq'.

Well, I think that the material in SICP Ch3 is quite confusing, but
not for the reasons that they say!  I say it's a scoping rule problem,
not some special property of mutation procedures.

The code below [SICP,p 171] is claimed to be confusing

(S!S)	 (define new-withdraw
	   (let ((balance 100))
	     (lambda (amount)
	       (if (>= balance amount)
		   (begin (set! balance (- balance amount))
			     balance)
		   "Insufficient funds"))))

(new-withdraw 10)	(new-withdraw 10)
 -| 90			 -| 80           



I'm convinced that's confusing!  I don't know an analogue of this
stunt in any other language, including Lisp.  [Correct me please.]
But why is it confusing?  SICP and ELP says `set!' is strange.
Let's analyze this claim in a simpler example:

(S)	 (define balance 100)

	 (define (new-withdraw amount)
	     (set! balance (- balance amount))
	     balance)

(new-withdraw 10)	(new-withdraw 10)
 -| 90			 -| 80           

Does anyone think this is confusing?  The same thing happens in Emacs
Lisp and C, where it's called scoping rules:

(E-L)	 (setq balance 100)

	 (defun new-withdraw (amount)
	   (setq balance (- balance amount))
	   balance)

(new-withdraw 10)	(new-withdraw 10)
 -| 90			 -| 80           

(C)	 main()
	 {
	   printf("%d\n", new_withdraw(10));
	   printf("%d\n", new_withdraw(10));}

	 int balance =100;

	 new_withdraw(int amount)
	   {
	   return(balance -= amount);}

(kepler)richter> gcc ju.c
(kepler)richter> a.out
90
80

So what's the fuss?  C, Common Lisp, Scheme all obey lexical scoping.
(Emacs Lisp has dynamic scoping, but largely we can ignore this.)

There's one confusing aspect of example (S); that if we replace
	     (set! balance (- balance amount))
with         (define balance (- balance amount))
we return 90 every time, no decrementing takes place.

BUT THAT'S CONFUSING ABOUT `DEFINE', NOT `SET!'!

You can't do it in Lisp, where it's silly to write
	   (defun balance (- balance amount)).

How about Fortran:  subroutine( balance, balance - amount ) :-)

Enough.  What I think is confusing about example (S!S) is that we're
allowed to put the local variable binding *before* the `lambda'.  Then
I guess the explanation is that we're in the situation of example (C):
Somehow there's an external declaration before body of the subroutine
`new-withdraw' which is lexically apparent in in `new-withdraw'

Let's try the next example in SICP:

	 (define (make-withdraw balance)
	   (lambda (amount)
	     (if (>= balance amount)
		 (begin (set! balance (- balance amount))
			   balance)
		 "Insufficient funds")))

(define W1 (make-withdraw 100))

(W1 10)		(W2 10)
 -| 90		 -| 80           

OK, I say what's confusing here is that `make-withdraw' is now a
function that returns functions, which can have lexically apparent
extern declarations preceding them!

OK, that's a mind-boggling abstraction.  But why not?  Lisp is
supposed to be good for that kind of thing, that's supposed to be the
advantage of the idea that "everything is a symbolic expression."

But my belief is that you cannot do this in Lisp.  In Emacs Lisp,
evaluating the first 2 sexps is fine, but the third gives

	 (defun make-withdraw (balance)
	   (lambda (amount)
	     (if (>= balance amount)
		 (progn (setq balance (- balance amount))
			   balance)
		 "Insufficient funds")))

(setq W1 (make-withdraw 100))

(W1 10)		

Invalid function: (lambda (make-withdraw 100))

Same error with (defun W1 (make-withdraw 100)) for 2nd sexp.

From: Pete Halverson
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <pch-1907951304510001@m142.mystech.com>
In article <·····················@banach.math.purdue.edu>,
·······@banach.math.purdue.edu (Bill Richter) wrote:

> The code below [SICP,p 171] is claimed to be confusing
> 
> (S!S)    (define new-withdraw
>            (let ((balance 100))
>              (lambda (amount)
>                (if (>= balance amount)
>                    (begin (set! balance (- balance amount))
>                              balance)
>                    "Insufficient funds"))))
> 
> (new-withdraw 10)       (new-withdraw 10)
>  -| 90                   -| 80           
> 
> 
> 
> I'm convinced that's confusing!  I don't know an analogue of this
> stunt in any other language, including Lisp.
 ....     
> 
> I say what's confusing here is that `make-withdraw' is now a
> function that returns functions, which can have lexically apparent
> extern declarations preceding them!
> 
> OK, that's a mind-boggling abstraction.  But why not?  Lisp is
> supposed to be good for that kind of thing, that's supposed to be the
> advantage of the idea that "everything is a symbolic expression."
> 
> But my belief is that you cannot this in Lisp. 

It's not clear what's meant by "Lisp" in these and other similar
references, as distinct from Scheme, Emacs Lisp, and Common Lisp (all of
which are mentioned separately).  As you point out, Scheme allows you to
create functional objects that refer to lexical bindings outside the
function definition, usually referred to as "lexical closures" (they
"close over" or "capture" the bindings, even after the function that
originally set up the bindings has returned).  Common Lisp also supports
this (albeit with a somewhat klunkier calling form)

  > (setq new-withdraw
         (let ((balance 100))
           #'(lambda (amount)
               (if (>= balance amount)
                   (setq balance (- balance amount))
                   "Insufficient funds")))))
  #<LEXICAL-CLOSURE #01AB915>

  > (funcall new-withdraw 10)
  90
  > (funcall new-withdraw 10)
  80

Emacs Lisp does not support this, though, having only dynamic (vs.
lexical) bindings.

Or did you really mean Common Lisp?  There's no single language called
"Lisp"; it's more like a family of languages, members of which include
Scheme, CL, ELisp, LeLisp, Zetalisp, MacLisp, Dylan (!), ... which share a
number of core language features and (except for Dylan) similar-looking
syntaxes.  Some of these support lexical closures, some don't.

pch
From: Bill Richter
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <3uk5qc$ol6@mozo.cc.purdue.edu>
In article <····················@m142.mystech.com> ···@mystech.com (Pete Halverson) writes:
>In article <·····················@banach.math.purdue.edu>,
>·······@banach.math.purdue.edu (Bill Richter) wrote:
>
>> The code below [SICP,p 171] is claimed to be confusing
>> 
>> (S!S)    (define new-withdraw
>>            (let ((balance 100))
>>              (lambda (amount)
>>                (if (>= balance amount)
>>                    (begin (set! balance (- balance amount))
>>                              balance)
>>                    "Insufficient funds"))))
>> 
>> (new-withdraw 10)       (new-withdraw 10)
>>  -| 90                   -| 80           
>> 
>> I'm convinced that's confusing!  I don't know an analogue of this
>> stunt in any other language, including Lisp.

Thanks to Pete and Will Clinger who pointed out I was wrong, you can
mimic this in Common Lisp, but not Emacs Lisp.  Where is a Scheme text
which discusses "lexical closures"?  That sounds like a cool concept,
but it's not in the index to either SICP, EPL, or Wilensky's book,
which is too elementary I think for this discussion.  I have the dvi
file for Steele's book but it's tough going!

   Pete> Common Lisp also supports this (albeit with a somewhat
   Pete> klunkier calling form)
   Pete> 
   Pete>   > (setq new-withdraw
   Pete>          (let ((balance 100))
   Pete>            #'(lambda (amount)
   Pete>                (if (>= balance amount)
   Pete>                    (setq balance (- balance amount))
   Pete>                    "Insufficient funds")))))

Will sent me the same thing, so I guess I'll believe it!  

   Pete> Emacs Lisp does not support this, though, having only dynamic
   Pete> (vs.  lexical) bindings.

I don't understand this; Will also said this.  Seems to me that
dynamic scoping is even better for this purpose.  The point of lexical
scoping is that the variable `balance' which is bound essentially in
the frame above can be modified in our frame.  Dynamic scoping would
mean to me that anyone anywhere can modify `balance'...


Anyway, I'm glad to learn there is a Common Lisp way to do, and I'm
also glad to learn that you can't do it in Emacs Lisp, for whatever
reason.  I guess I'd like to know more about why not.  

I've done a lot of thinking & reading spurred on by Will's email to
me, so let me respond to some of my other points:


1) I still contend that the environment/mutation model of SICP is
really just lexical scoping as in C.  But the more I think about it,
and read the text, the more I think IT'S A VERY GOOD DESCRIPTION OF
LEXICAL SCOPING.  I just wish, as a pedagogical point, that they had
pointed out that it wasn't a new concept.  I suppose that the audience
of MIT 6.001 hopefully has no programming experience anyway.

2) I understand now the `define' vs `set!', it's explained in SICP.
In the more old-fashioned C parlance, a `define' statement in a
function definition only creates a binding in that function, while
`set!' (like = in C) can modify variables that are apparent in the
function.  Although my C model breaks down a little here: if a C
variable from higher up is lexically apparent in a function, then
defining the same name as an automatic variable in the function gives
a compiler error:
"parm types given both in parmlist and separately"
and as far as I can tell, the local binding is ignored in favor of the
external variation.  I guess my C needs a lotta work too...
From: Marco Antoniotti
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <MARCOXA.95Jul21100812@liberty.cs.nyu.edu>
In article <··········@mozo.cc.purdue.edu> ·······@banach.math.purdue.edu (Bill Richter) writes:


   From: ·······@banach.math.purdue.edu (Bill Richter)
   Newsgroups: comp.lang.scheme,comp.lang.lisp
   Date: 20 Jul 1995 14:36:32 GMT
   Organization: Purdue University, West Lafayette, Indiana
   Lines: 58
   Distribution: world
   Xref: cmcl2 comp.lang.scheme:13392 comp.lang.lisp:18674

   Thanks, Steve, and also to Tim Bradshaw (···@ed.ac.uk) and Karl
   Czajkowski (······@uclink.berkeley.edu), who sent me helpful email
   about indefinite extent and closures.  I know see what's happening in
   Emacs.  In fact, By `s extent' in the Emacs Lisp info file, I get to
   the node "Extent", which reads in part:

	 "Extent" refers to the time during program execution that a
      variable name is valid.  In Emacs Lisp, a variable is valid only
      while the form that bound it is executing.  This is called "dynamic
      extent".  "Local" or "automatic" variables in most languages,
      including C and Pascal, have dynamic extent.

	 One alternative to dynamic extent is "indefinite extent".  This
      means that a variable binding can live on past the exit from the
      form that made the binding.  Common Lisp and Scheme, for example,
      support this, but Emacs Lisp does not.

	 Some Lisp dialects have "closures", objects that are like
      functions but record additional variable bindings.  Emacs Lisp does
      not have closures.

   So that's why the Scheme [SICP,p 171] `new-withdraw' wouldn't work as
   coded in Emacs Lisp.  However, I still say that I can get much the
   same phenomenon in C or Emacs Lisp by rewriting the code, e.g.

   (C)	 main()
	    {
	      printf("%d\n", new_withdraw(10));
	      printf("%d\n", new_withdraw(10));}

	    int balance =100;
	    new_withdraw(int amount)
	      {
	      return(balance -= amount);}

   What I did was take the local variable `balance' and lengthen it's
   extent by  putting the declaration above the function definition.

   So my speculation remains that a reasonable model for what Scheme does
   is that it takes your code and produces a C program like the one.  So
   the lexical scoping of C wins, and in the translated code the fact
   that C doesn't have indefinite extent doesn't lose.

   I won't be too surprised if it turns out I'm wrong here, though, that
   we could concoct Scheme programs that would really break my C
   model.

Yes you are. Get your copy of SICP (one of the best book on
programming ever written - whichever language you choose) and check a
few pages around the balance account


(define (make-account balance)
  (define (withdraw amount)
    (if (>= balance amount)
	(begin
	  (set! balance  (- balance amount))
	  balance)
	(error 'insufficient-funds)))

  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)

  (define (dispatch operation)
    (cond ((eq? operation 'withdraw) withdraw)
	  ((eq? operation 'deposit) deposit)
	  (else (error 'unknown-request))
	  ))
  dispatch)

   And the frames/environments model of SICP is very interesting, it's
   worth puzzling over.  I still contend it's crazy to teach the Scheme
   frames/environments without explaining that we can mimic the results
   in a lot of cases in a language like C, just using lexical scoping.

	...

The C code you wrote is even better written as

	 main()
         {
	      printf("%d\n", new_withdraw(10));
	      printf("%d\n", new_withdraw(10));
	 }

	 
	 int new_withdraw(int amount)
	 {
   	      static int balance = 100;

	      return(balance -= amount);
         }

In order to actually simulate the behavior of closures. However there
are a lot of interesting things that simply cannot be done in C/C++ or
languages that do not support first class functional objects like
Common Lisp or Scheme (or Emacs Lisp - even though dynamic binding
makes things complicated).

You cannot write
	
	typedef enum {withdraw, deposit} operation;
	typedef int (*intfun)(operation, int);

	intfun new_account(int starting_balance);
	{
		return new intfun(operation o, int x) {
			   {
				/* do whatever */
			   };
	}

or something similar. This is what makes Languages with first class
functional objects more expressive than other ones.

Happy Lisping

--
Marco G. Antoniotti - Resistente Umano
-------------------------------------------------------------------------------
Robotics Lab		| room: 1220 - tel. #: (212) 998 3370
Courant Institute NYU	| e-mail: ·······@cs.nyu.edu
			| WWW:    http://found.cs.nyu.edu/marcoxa

...e` la semplicita` che e` difficile a farsi.
...it is simplicity that is difficult to make.
				Bertholdt Brecht
From: Steve VanDevender
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <STEVEV.95Jul21151702@miser.uoregon.edu>
In article <··········@mozo.cc.purdue.edu>
·······@banach.math.purdue.edu (Bill Richter) writes:

   Thanks, Steve, and also to Tim Bradshaw (···@ed.ac.uk) and Karl
   Czajkowski (······@uclink.berkeley.edu), who sent me helpful email
   about indefinite extent and closures.  I know see what's happening in
   Emacs.  In fact, By `s extent' in the Emacs Lisp info file, I get to
   the node "Extent", which reads in part:

	 "Extent" refers to the time during program execution that a
      variable name is valid.  In Emacs Lisp, a variable is valid only
      while the form that bound it is executing.  This is called "dynamic
      extent".  "Local" or "automatic" variables in most languages,
      including C and Pascal, have dynamic extent.

	 One alternative to dynamic extent is "indefinite extent".  This
      means that a variable binding can live on past the exit from the
      form that made the binding.  Common Lisp and Scheme, for example,
      support this, but Emacs Lisp does not.

	 Some Lisp dialects have "closures", objects that are like
      functions but record additional variable bindings.  Emacs Lisp does
      not have closures.

There is another concept you might find illuminating.  Extent
refers to the period of execution time during which a variable
exists.  Scope refers to the portion of a program in which a
variable is visible.  I'll also make reference to the concept of
a free variable, which is one that is not defined in the
immediately enclosing environment.

Lexical scope means that the scope of a variable can be
determined entirely by looking at the program source; you can
actually "color in" the region of the source in which the
variable is available for reference.  Scheme, Pascal, and C are
examples of languages with lexical scope; the scope of a variable
starts at its definition and continues through the block in
which it is defined.

Dynamic scope, on the other hand, means that the availability of
a variable can only be determined by looking at the runtime
behavior of the program.  A reference to a variable that is free
in a given function may be satisfied by an instance of that
variable in a calling function.  As an example, here is some code
that will behave differently depending on whether it is evaluated
using lexical or dynamic scope rules:

(define a 1)

(define calling-func
  (lambda (a)
    (called-func 1)))

(define called-func
  (lambda (b)
    (+ a b)))

(calling-func 2)

(called-func 1)

When evaluated with lexical scope rules, the call to calling-func
will return 2, because the free reference a in called-func gets
the global value of a, which is 1.  If we replace the defines
with setqs or defuns to turn this into original Lisp code, then
instead the call to calling-func will return 3 -- the binding of
a in calling-func will shadow the global value of a _while
calling-func calls called-func_.  On the other hand, called-func
as called from the global environment above will return 2 under
both lexical and dynamic scope rules.

Although this is a small and artificial (but hopefully correct)
example, it does demonstrate that in a dynamic-scoped language,
it is much harder to reason about program behavior just by
looking at the program source.

A comparison of how a few example languages handle both extent
and scope is also illuminating.

Pascal and C have indefinite scope and extent for global
variables, and limited scope and extent for local variables (the
scope is limited to the lexical block, the extent to the runtime
of the lexical block), and lexical scope rules.

What I've been calling "original Lisp" has indefinite scope and
extent for global variables, but for local variables, scope is
potentially indefinite because of dynamic scoping -- any free
reference to a variable in any function can be satisfied by a
definition of the variable in any function up the chain of
calling.  However, the extent of a local variable is the same as
in C or Pascal.

Scheme also has indefinite scope and extent for global variables.
On the other hand, local variables have lexical scope, but
potentially indefinite extent -- a free reference to a variable is
always satisfied by a lexically enclosing environment, rather
than the runtime nesting of function environments.
--
Steve VanDevender 	······@greylady.uoregon.edu
"Bipedalism--an unrecognized disease affecting over 99% of the population.
Symptoms include lack of traffic sense, slow rate of travel, and the
classic, easily recognized behavior known as walking."
From: Bill Richter
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <3vul6p$oea@mozo.cc.purdue.edu>
Jeff, I sure don't know how to implement lazy lists in C!  As you say,
it must be possible, since Scheme->C translators exist.

I was just complaining about the way that SICP was written, and I think
I didn't do a good job of explaining what I didn't like. I see now (I
didn't know then) that you can do a lot more with Scheme than you can do
with C (at least easily) in terms of protecting local variables, making
multiple copies of a procedure.  All I really was saying was that the
simplest advantages of set! are available in C via lexical scoping.  I'm
grateful to all the people who pointed out the more advanced advantages.

I've been working quite hard to understand the frames/enviro model that
SICP proposes.  I claim there has to be a simpler way of thinking about
it!  I was very excited that the "sequel" Essentials of Programming
Languages (EPL), Friedman et al, did not use frames and environments to
explain set!.  Unfortunately, in the first 4 chapters they fail to give
any model for it all.  They do give what I think is a very nice
"mathematical" treatment of SICP's substitution model, talking
extensively about alpha & beta conversion, the lambda calculus.  In
Chapters 5 onward, they must discuss a good model for set!, but I'm not
going to be able to read that soon, it's all about building your own
interpreter.  I'm hoping to post again soon, but I gotta learn it first!
From: Steve VanDevender
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <STEVEV.95Jul20011310@miser.uoregon.edu>
In article <··········@mozo.cc.purdue.edu>
·······@banach.math.purdue.edu (Bill Richter) writes:

      Pete> Emacs Lisp does not support this, though, having only dynamic
      Pete> (vs.  lexical) bindings.

   I don't understand this; Will also said this.  Seems to me that
   dynamic scoping is even better for this purpose.  The point of lexical
   scoping is that the variable `balance' which is bound essentially in
   the frame above can be modified in our frame.  Dynamic scoping would
   mean to me that anyone anywhere can modify `balance'...

The difference is that in purely dynamic-scoped languages, you
can't create permanent local environments because they don't have
such a thing as a lexical closure.  In a dynamic-scoped language,
local environments are created by function calls and destroyed
when functions exit; trying to make "new-withdraw" in a
dynamic-scoped language will result in an undefined variable
reference when the function returned by new-withdraw is called,
as the value "balance" in the enclosing let goes away when it
finishes right after the inner lambda is returned.
--
Steve VanDevender 	······@greylady.uoregon.edu
"Bipedalism--an unrecognized disease affecting over 99% of the population.
Symptoms include lack of traffic sense, slow rate of travel, and the
classic, easily recognized behavior known as walking."
From: Bill Richter
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <3ulplg$bco@mozo.cc.purdue.edu>
Thanks, Steve, and also to Tim Bradshaw (···@ed.ac.uk) and Karl
Czajkowski (······@uclink.berkeley.edu), who sent me helpful email
about indefinite extent and closures.  I know see what's happening in
Emacs.  In fact, By `s extent' in the Emacs Lisp info file, I get to
the node "Extent", which reads in part:

      "Extent" refers to the time during program execution that a
   variable name is valid.  In Emacs Lisp, a variable is valid only
   while the form that bound it is executing.  This is called "dynamic
   extent".  "Local" or "automatic" variables in most languages,
   including C and Pascal, have dynamic extent.

      One alternative to dynamic extent is "indefinite extent".  This
   means that a variable binding can live on past the exit from the
   form that made the binding.  Common Lisp and Scheme, for example,
   support this, but Emacs Lisp does not.

      Some Lisp dialects have "closures", objects that are like
   functions but record additional variable bindings.  Emacs Lisp does
   not have closures.

So that's why the Scheme [SICP,p 171] `new-withdraw' wouldn't work as
coded in Emacs Lisp.  However, I still say that I can get much the
same phenomenon in C or Emacs Lisp by rewriting the code, e.g.

(C)	 main()
	 {
	   printf("%d\n", new_withdraw(10));
	   printf("%d\n", new_withdraw(10));}

	 int balance =100;
	 new_withdraw(int amount)
	   {
	   return(balance -= amount);}

What I did was take the local variable `balance' and lengthen it's
extent by  putting the declaration above the function definition.

So my speculation remains that a reasonable model for what Scheme does
is that it takes your code and produces a C program like the one.  So
the lexical scoping of C wins, and in the translated code the fact
that C doesn't have indefinite extent doesn't lose.

I won't be too surprised if it turns out I'm wrong here, though, that
we could concoct Scheme programs that would really break my C model.

And the frames/environments model of SICP is very interesting, it's
worth puzzling over.  I still contend it's crazy to teach the Scheme
frames/environments without explaining that we can mimic the results
in a lot of cases in a language like C, just using lexical scoping.

But maybe I'm confused about a more fundamental point.  The assertion
of SICP wasn't exactly that the `new-withdraw' procedure showed the
true power of Lips, that it couldn't be replicated in simpler
languages like C.  They said it broke their "substitution model" for
evaluating procedures.  Well, does lexical scoping also break a
"substitution model" for understanding C programs?
From: Michael Greenwald
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <michaelg.806264013@Xenon.Stanford.EDU>
·······@banach.math.purdue.edu (Bill Richter) writes:

> However, I still say that I can get much the
>same phenomenon in C or Emacs Lisp by rewriting the code

Not quite; you lose the lexical _scope_ of "balance".  It is now
lexically apparent to all the code in that lexical unit (assuming no
funny declarations, then the lexical unit in C is the file).  So all
instances of references to "balance" would share the >same< identical
balance.  In scheme or common lisp each account would have its own
private balance.

Of course, you >can< achieve the same effect in C (or Emacs Lisp).
You must explicitly create the closure, by keeping all closed variables
in a structure and passing it as the first argument everytime you call
the function.  This is ugly code, and while functionally equivalent,
it is syntactically more cumbersome.  

You can clean this up a _little_ in C++.  There are obvious dualities
between lexical closures and objects, so you could implement the same
functionality by having a class for each lexical closure.

In addition to the ugliness, there are always slightly subtle cases
that make you glad that lexical closures are supported in the
language.  Consider cases where you have multiple lexical closures
sharing parts of the same environment.  To implement this using
classes (or structures..) you define a class which contains the union
of all the environments in the transitive closure over all partially
shared environments.  Then each individual lexical closure is a method
(member function) of the large class (an example would be creating a
new account and having methods for Withdrawl, Deposit, and Balance)

Michael Greenwald
·········@cs.stanford.edu
From: Riccardo PUCELLA
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <3unf9m$kul@sifon.cc.mcgill.ca>
Howdy

Bill Richter (·······@banach.math.purdue.edu) wrote:
: So that's why the Scheme [SICP,p 171] `new-withdraw' wouldn't work as
: coded in Emacs Lisp.  However, I still say that I can get much the
: same phenomenon in C or Emacs Lisp by rewriting the code, e.g.

: (C)	 main()
: 	 {
: 	   printf("%d\n", new_withdraw(10));
: 	   printf("%d\n", new_withdraw(10));}

: 	 int balance =100;
: 	 new_withdraw(int amount)
: 	   {
: 	   return(balance -= amount);}

: What I did was take the local variable `balance' and lengthen it's
: extent by  putting the declaration above the function definition.

However, this means that you made the variable 'balance' a global
variable - any function can refer to or modify the value of that
variable. One of the advantage of the original Scheme code was that
the variable 'balance' was local to the function (new-withdraw).

Indeed, once you study the environment model of Scheme, you see that
by closing over the definition of 'balance' --- thereby constructing a
closure --- the binding for 'balance' only exists in the environment
stored in the closure. This you cannot do directly in C.



: So my speculation remains that a reasonable model for what Scheme does
: is that it takes your code and produces a C program like the one.  So
: the lexical scoping of C wins, and in the translated code the fact
: that C doesn't have indefinite extent doesn't lose.

: I won't be too surprised if it turns out I'm wrong here, though, that
: we could concoct Scheme programs that would really break my C model.

: And the frames/environments model of SICP is very interesting, it's
: worth puzzling over.  I still contend it's crazy to teach the Scheme
: frames/environments without explaining that we can mimic the results
: in a lot of cases in a language like C, just using lexical scoping.


Mmm. It has been my experience teaching and tutoring students in
Scheme that it is best to stay away from comparing what you can do in
Scheme with what you can do in an imperative language like Pascal or
C. The sooner the student learns to 'think' in Scheme, namely using
higher-order functions and closures, the sooner he/she is able to
tackle on what I consider the more interesting aspects of the
language. Whereas the comparison with C could be justified when you
program simple imperative-style programs, the analogy is quite certain
to break down when dealing with what amounts to object-oriented style
of programming (which can easily be implemented in Scheme) and/or
continuations. 


Following this thread with interest,

Riccardo.

--

*****************************************************************************
     Riccardo R. Pucella (Snowman), McGill University, Montreal, Canada.
                          (·······@cs.mcgill.ca)
          WWW home page  -  http://www-acaps.cs.mcgill.ca/~pucella
EITHER LEAVE 'EM LAUGHING... OR LEAVE 'EM WONDERING WHAT THE HELL YOU MEANT.
From: Christer Gessler
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <D94-CGE.95Jul20091309@mumrik.nada.kth.se>
> There's one confusing aspect of example (S); that if we replace
> 	     (set! balance (- balance amount))
> with         (define balance (- balance amount))
> we return 90 every time, no decrementing takes place.
> 
> BUT THAT'S CONFUSING ABOUT `DEFINE', NOT `SET!'!

In the definition

(define foo 4)
(define (proc x)
  (define foo (- foo x))
  foo)

the second foo in the procedure is bound to the external definition of foo.
The first foo in the procedure is a local definition that goes out of scope
as soon as its value is returned when the procedure is exited.
So the procedure is equivalent to

(define (proc x)
  (define bar (- 4 x))
  bar)
-- 

<  Christer Gessler    email: ·······@nada.kth.se               >
<  Stockholm, Sweden   www:   http://www.nada.kth.se/~d94-cge/  >
From: John Burdick
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <3up90b$ah3@news-s01.ny.us.ibm.net>
·······@banach.math.purdue.edu (Bill Richter) wrote:

>OK, I say what's confusing here is that `make-withdraw' is now a
>function that returns functions, which can have lexically apparent
>extern declarations preceding them!

There seems to be two problems here: you don't get first class
procedures yet, and you don't know about the goals of functional
programming.

C only has three levels of scope: global, module static, and private.
There is no nesting of functions. This point is important: the
difference between full nesting and a fixed three level system is not
a minor issue. Closures would not have the important place in LISP
programming they have if there were only the fixed levels of C.

C also doesn't allow the creation of functions. Again, this is
crucial. Further more, the definition of a function is unlike normal
statements. In Scheme, a lambda expression is an ordinary expression
that can go anywhere. There may be visible bindings where that lambda
is created. Those binding continue to exist as long as they are
visible from anywhere, including from lambdas. Why shouldn't you be
able to define a function anywhere you want?

As for set!, you seem to be mixing two different ideas of difficult.
set! is difficult because it breaks referential transparency (which is
important for a substitution model). That doesn't mean it's tricky to
understand what the function does in the small scale view. In other
words, once you grasp the Scheme way, it simplifies some things. You
seem to be defining confusing as being unlike C. When I was taking
algebra I in high school, I found immutable variables in algebra
confusing. I wanted to know how to solve x = x + 1, as an equation. I
had that problem because I knew BASIC before I entered high school. C,
BASIC and numerous other language communities don't want a
substitution model. The pure functional people are more commited to it
than Schemers; they don't provide mutation procedures in their
languages. Schemers take a compromise approach of using set! with
care.

John
From: ·····@liverpool.ac.uk
Subject: Re: Confused over Scheme Pedagogy of mutation procedures
Date: 
Message-ID: <BRUCE.95Jul21114614@iasc3.scm.liv.ac.uk>
>>>>> "Bill" == Bill Richter <·······@banach.math.purdue.edu> writes:

>> (defun ... 
>>     (let ((balance ..))
>>         (lambda (...) ...)))

> I don't understand this; Will also said this.  Seems to me that
> dynamic scoping is even better for this purpose.  The point of
> lexical scoping is that the variable `balance' which is bound
> essentially in the frame above can be modified in our frame.
> Dynamic scoping would mean to me that anyone anywhere can modify
> `balance'...

That's true, but the `balance' that they'll modify could be any
`balance'; it would depend on who called them.  Lexical closure means
that you know which balance it's going to be: it's going to be the one
created by let.
-- 
Bruce                   Institute of Advanced Scientific Computation
·····@liverpool.ac.uk   University of Liverpool
http://supr.scm.liv.ac.uk/~bruce/