From: ········@gmail.com
Subject: looking closer at funcitons and closure and getting confused
Date: 
Message-ID: <1180234114.241234.38100@n15g2000prd.googlegroups.com>
I;ve been playing around with clisp and I thought things had started
making pretty good sense, when suddenly I threw myself for a loop and
things that were perfectly clear from day one suddenly made no sense
at all.

It all started when I looked at the hyperspec for the function special
operator which says:

> Examples:
>
> (defun adder (x) (function (lambda (y) (+ x y))))
> The result of (adder 3) is a function that adds 3 to its argument:
>
> (setq add3 (adder 3))
> (funcall add3 5) =>  8
>
> This works because function creates a closure of the lambda expression that is able to refer to the
> value 3 of the variable x even after control has returned from the function adder.


But wait... let's open up clisp

[1]> (defun adder (x) (lambda (y) (+ x y)))
ADDER
[2]>  (setq add3 (adder 3))
#<FUNCTION :LAMBDA (Y) (+ X Y)>
[3]> (funcall add3 5)
8


It doesn't look like I need (function ... ) in there at all.  I
thought lambda expressions always had closure,
and it sure seems to act like they do.  Am I missing something about
closures here?

Now this all started because I had realized I've been doing things
like

(funcall '+ 1 2)

and I'd get 3 like I expected, but I had realized I was doing the
wrong thing, after all wasn't I supposed to
be using

(funcall #'+ 1 2)

instead?  Wasn't the function operator supposed to take a variable and
give me the function associated with that variable?  Why is the
hyperspec talking about closures?

Let's look a little closer:

(macroexpand '(defun foo (x) (1+ x)))
(LET NIL (SYSTEM::REMOVE-OLD-DEFINITIONS 'FOO)
 (SYSTEM::EVAL-WHEN-COMPILE
  (SYSTEM::C-DEFUN 'FOO (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(X))))
 (SYSTEM::%PUTD 'FOO
  (FUNCTION FOO
   (LAMBDA (X) (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (1+ X)))))
 (EVAL-WHEN (EVAL)
  (SYSTEM::%PUT 'FOO 'SYSTEM::DEFINITION
   (CONS '(DEFUN FOO (X) (1+ X)) (THE-ENVIRONMENT))))
 'FOO) ;

WHAT!!!  What is function doing in there?  And why does the hyperspec
say nothing about about that use?

(funcall (function bar (lambda (x) (+ 2 x))) 2)

hmm, that gave me a 4.  What is going on here?

So what exactly does that function operator do and what does it have
to do with closures?

I'm just confused now,
Anthony

From: Rob Warnock
Subject: Re: looking closer at funcitons and closure and getting confused
Date: 
Message-ID: <F4ednXsq6szzZMXbnZ2dnUVZWhednZ2d@speakeasy.net>
<········@gmail.com> wrote:
+---------------
| But wait... 
...
| It doesn't look like I need (function ... ) in there at all.
...
| Am I missing something about closures here?
+---------------

No, actually, you're missing something about LAMBDA:

    > (setf *print-pretty* nil)

    NIL
    > (macroexpand '(lambda (x y) (+ x y)))

    (FUNCTION (LAMBDA (X Y) (+ X Y)))
    T
    > 

Read the CLHS entries for *both* "Symbol LAMBDA" and "Macro LAMBDA",
and things should become more clear.

+---------------
| Now this all started because I had realized I've been doing things
| like (funcall '+ 1 2)
| and I'd get 3 like I expected, but I had realized I was doing the
| wrong thing, after all wasn't I supposed to be using (funcall #'+ 1 2)
| instead?
+---------------

[To avoid possible complaints about re-binding, I'm going to change
this example to one which does not use a function defined in the
COMMON-LISP package...]

(funcall 'foo 1 2) is perfectly legal, and will always give you
exactly the same thing as (funcall (symbol-function 'foo) 1 2).

(funcall #'foo 1 2) is *also* perfectly legal, but will give
you the same thing as (funcall 'foo 1 2) only when there is
no lexically-apparent binding for a different function FOO. E.g.:

    > (defun foo (x y) (+ x y))

    FOO
    > (flet ((foo (x y) (* x y)))
	(list (funcall 'foo 2 3)
	      (funcall #'foo 2 3)
	      (foo 2 3)))

    (5 6 6)
    > 

Clear?

+---------------
| Wasn't the function operator supposed to take a variable
| and give me the function associated with that variable?
| Why is the hyperspec talking about closures?
+---------------

Quoting [emphasis added]:

    The value of FUNCTION is the functional value
    of name IN THE CURRENT LEXICAL ENVIRONMENT.

That functional value very well might be a closure.

    > (let ((increment 17))
	(flet ((add17 (x)
		 (+ x increment)))
	  (function add17)))

    #<Interpreted Function (FLET ADD17) {4898BD51}>
    > (funcall * 5)

    22
    > 

See? ADD17 is a closure, closed over the value of INCREMENT.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Pascal Bourguignon
Subject: Re: looking closer at funcitons and closure and getting confused
Date: 
Message-ID: <87r6p2g3i8.fsf@thalassa.lan.informatimago.com>
········@gmail.com writes:
> [...]
> Wasn't the function operator supposed to take a variable and
> give me the function associated with that variable?  

No, not _variable_. The special operator FUNCTION takes the _name_ of
a function.

> [...]
> Let's look a little closer:
>
> (macroexpand '(defun foo (x) (1+ x)))
> (LET NIL (SYSTEM::REMOVE-OLD-DEFINITIONS 'FOO)
>  (SYSTEM::EVAL-WHEN-COMPILE
>   (SYSTEM::C-DEFUN 'FOO (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(X))))
>  (SYSTEM::%PUTD 'FOO
>   (FUNCTION FOO
>    (LAMBDA (X) (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (1+ X)))))
>  (EVAL-WHEN (EVAL)
>   (SYSTEM::%PUT 'FOO 'SYSTEM::DEFINITION
>    (CONS '(DEFUN FOO (X) (1+ X)) (THE-ENVIRONMENT))))
>  'FOO) ;
>
> WHAT!!!  What is function doing in there?  And why does the hyperspec
> say nothing about about that use?

Here, you are looking at implementation dependant stuff.  The
hyperspec doesn't say anything about implementation specific stuff, it
specifies only what DEFUN should do.  The implementation can expand
DEFUN to anything it wants.


> (funcall (function bar (lambda (x) (+ 2 x))) 2)
>
> hmm, that gave me a 4.  What is going on here?

You're activating some clisp specific behavior.

Since CL:FUNCTION is specified to take only one argument, it's a
little unfortunate on the part of clisp to accept an optional
argument, but since this won't break an conforming program, it's an
acceptable extension.  Of course you should never give two arguments
to the FUNCTION special operator.  This is someting that's only done
internaly by clisp itself.

 
> So what exactly does that function operator do and what does it have
> to do with closures?

    (FUNCTION name)

    If name is a function name, the functional definition of that name
    is that established by the innermost lexically enclosing flet,
    labels, or macrolet form, if there is one.  Otherwise the global
    functional definition of the function name is returned.

    If name is a lambda expression, then a lexical closure is
    returned. In situations where a closure over the same set of
    bindings might be produced more than once, the various resulting
    closures might or might not be eq.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.