Subject: Re: looking closer at funcitons and closure and getting confused
From: (Rob Warnock)
Date: Sat, 26 May 2007 22:22:22 -0500
Newsgroups: comp.lang.lisp
Message-ID: <>
<> 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)

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

    (FUNCTION (LAMBDA (X Y) (+ X Y)))

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))

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

    (5 6 6)


| 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

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)


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


Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607