From: Barry Margolin
Subject: Re: nested lambda-expressions
Date: 
Message-ID: <barmar-7D0220.18553510082005@comcast.dca.giganews.com>
In article <····················@ram.dialup.fu-berlin.de>,
 ···@zedat.fu-berlin.de (Stefan Ram) wrote:

>   I just wanted to try something with CLisp. Here is an
>   abbreviated transscript:
> 
> > (setq inc (lambda (x)(+ 1 x)))
> #<FUNCTION :LAMBDA (X) (+ 1 X)>
> 
> > (funcall inc 10)
> 11
> 
> > (setq double (lambda (f)(lambda(x)(funcall f(funcall f x)))))
> #<FUNCTION :LAMBDA (F) (LAMBDA (X) (FUNCALL F (FUNCALL F X)))>
> 
>   I.e., apply the function "f" twice, which is assumed
>   to be a function with one parameter.
> 
> > (funcall double inc)
> #<FUNCTION :LAMBDA (X) (FUNCALL F (FUNCALL F X))>
> 
>   I assume the last line to be the value of the expression
>   I have entered. How can "F" be a seemingly free variable
>   in the result and why is "inc" not used? 

You've created a lexical closure.  The free variable F is "closed over", 
meaning that the function remembers the binding it had when the function 
was created.  The value of INC that was passed is remembered in that 
closure.

> 
>   I was actually trying to get something like:
> 
> #<FUNCTION :LAMBDA (X) (FUNCALL INC (FUNCALL INC X))>

That's essentially what you have, but it remembers the value that INC 
had at the time that you did the FUNCALL.  If you re-assign INC, this 
new function will still call the old one.

> 
>   or even:
> 
> #<FUNCTION :LAMBDA (X)(FUNCALL #<FUNCTION :LAMBDA (X) 
>       (+ 1 (FUNCALL #<FUNCTION :LAMBDA (X1) (+1 X)>))>)>
> 
>   Because I was curious to see how Lisp might rename the 
>   inner parameter "x".

Lisp doesn't perform substitution.  The closure has a set of bindings 
that you don't see, which maps F to #<FUNCTION :LAMBDA (X) (+ 1 X)>.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***