Subject: Re: looking closer at funcitons and closure and getting confused
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 26 May 2007 22:22:22 -0500
Newsgroups: comp.lang.lisp
Message-ID: <F4ednXsq6szzZMXbnZ2dnUVZWhednZ2d@speakeasy.net>
<aspolito@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@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607