From: Joe Marshall
Subject: Re: nested lambda-expressions
Date: 
Message-ID: <ll39lft4.fsf@ccs.neu.edu>
···@zedat.fu-berlin.de (Stefan Ram) writes:

>   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? 
>
>   I was actually trying to get something like:
>
> #<FUNCTION :LAMBDA (X) (FUNCALL INC (FUNCALL INC X))>

That depends on how the implementation prints things.

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

It generally doesn't rename parameters but instead keeps them in a
lookup table that is associated with the function object.  The X in
INC is therefore looked up in a different table from the X in DOUBLE.
From: Thomas A. Russ
Subject: Re: nested lambda-expressions
Date: 
Message-ID: <ymik6isf9a9.fsf@sevak.isi.edu>
···@zedat.fu-berlin.de (Stefan Ram) writes:

> 
> Joe Marshall <···@ccs.neu.edu> writes:
> >That depends on how the implementation prints things.
> 
>   CLisp seems to print different functions using the same
>   representation:
> 
> > (funcall double inc)
> #<FUNCTION :LAMBDA (X) (FUNCALL F (FUNCALL F X))>
> 
> > (setq imitation (lambda(x)(funcall f(funcall f x))))
> #<FUNCTION :LAMBDA (X) (FUNCALL F (FUNCALL F X))>
> 
>   Here "imitation" does not represent the same function
>   as "(funcall double inc)" but is represented the same
>   way. Once a function is built, there seems to be no
>   standard way back to a list representation of that
>   function.

What's not shown is the "closure" associated with the function.  That
closure contains the bindings of the variables that are present in the
function code.  One reason the bindings aren't just substituted in place
is that one is allowed to modify the binding value.  One of the classic
examples is the following:

(let ((x 0))
  (defun set-it (val) (setq x val))
  (defun read-it () x))

Then you can do the following:

(read-it)    ==> 0
(set-it 10)  ==> 10
(read-it)    ==> 10

This can also be done with lambda expressions:

(defun make-counter (initial-value)
  ;; Creates a counter and returns reader & setter
  ;; functions for that value.
  (let ((counter initial-value))
    (values (lambda () counter)
            (lambda (val) (setq counter val)))))

(make-counter) ==> ...(printed representation depends on implementation

(multiple-value-bind (reader setter) (make-counter 42)
   (print (funcall reader))
   (funcall setter 10)
   (print (funcall reader))
   :done)

==> 
42
10
:DONE




-- 
Thomas A. Russ,  USC/Information Sciences Institute