From: Pierre THIERRY
Subject: Difference between function and closure
Date: 
Message-ID: <pan.2006.08.12.16.57.28.214701@levallois.eu.org>
I'm just playing with lambda and closure, and I don't understand why two
forms don't evaluate to the same result. I defined a dynamic variable to
hold the closure, named *incrementer*. (FWIW, I'm under SLIME with SBCL)

The first form and it's result are:

CL-USER> (setf *incrementer*
	       (let ((increment 3))
		 (lambda (x)
		   (+ x increment))))
#<FUNCTION (LAMBDA (X)) {C0C946D}>

Then I can do:

CL-USER> (funcall *incrementer* 1)
4

The second use involves a function to automate the creation of the
closure:

CL-USER> (defun create-incrementer (increment)
	   (let ((increment increment))
	     (lambda (x)
	       (+ x increment))))
CREATE-INCREMENTER

In which I copy-pasted the previous form, replacing the constant number
with the argument of the function... But:

CL-USER> (setf *incrementer* (create-incrementer 4))
#<CLOSURE (LAMBDA (X)) {C257F45}>

Which works the same way:

CL-USER> (funcall *incrementer* 1)
5

But why was one result qualified as #<FUNCTION (LAMBDA (X)) ...> and the
other as #<CLOSURE (LAMBDA (X)) ...>?

Curiously,
Nowhere man
-- 
···········@levallois.eu.org
OpenPGP 0xD9D50D8A
From: Barry Margolin
Subject: Re: Difference between function and closure
Date: 
Message-ID: <barmar-36156C.13445112082006@comcast.dca.giganews.com>
In article <······························@levallois.eu.org>,
 Pierre THIERRY <···········@levallois.eu.org> wrote:

> I'm just playing with lambda and closure, and I don't understand why two
> forms don't evaluate to the same result. I defined a dynamic variable to
> hold the closure, named *incrementer*. (FWIW, I'm under SLIME with SBCL)
> 
> The first form and it's result are:
> 
> CL-USER> (setf *incrementer*
> 	       (let ((increment 3))
> 		 (lambda (x)
> 		   (+ x increment))))
> #<FUNCTION (LAMBDA (X)) {C0C946D}>
> 
> Then I can do:
> 
> CL-USER> (funcall *incrementer* 1)
> 4
> 
> The second use involves a function to automate the creation of the
> closure:
> 
> CL-USER> (defun create-incrementer (increment)
> 	   (let ((increment increment))
> 	     (lambda (x)
> 	       (+ x increment))))
> CREATE-INCREMENTER
> 
> In which I copy-pasted the previous form, replacing the constant number
> with the argument of the function... But:
> 
> CL-USER> (setf *incrementer* (create-incrementer 4))
> #<CLOSURE (LAMBDA (X)) {C257F45}>
> 
> Which works the same way:
> 
> CL-USER> (funcall *incrementer* 1)
> 5
> 
> But why was one result qualified as #<FUNCTION (LAMBDA (X)) ...> and the
> other as #<CLOSURE (LAMBDA (X)) ...>?

Looks like the compiler noticed that in the first case there was no way 
to modify INCREMENT, so it optimized the code into

(lambda (x) (+ x 3))

Now there's no closed variable, so it can be implemented as a normal 
function.  Try this:

(multiple-value-setq (*incrementer* *increment-changer*)
  (let ((increment 3))
    (values (lambda (x) (+ x increment))
            (lambda (new) (setq increment new))))

This time *incrementer* should be a closure.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***