Subject: Re: LISP
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 12 May 2009 20:04:03 -0500
Newsgroups: comp.lang.lisp
Message-ID: <h8Gdncsru7oegZfXnZ2dnUVZ_sGdnZ2d@speakeasy.net>
Kaz Kylheku  <kkylheku@gmail.com> wrote:
+---------------
| Rob Warnock <rpw3@rpw3.org> wrote:
| > That is, to me (LAMBDA ...something...) is an executable form [albeit
| > a special form] which returns a value, a new function which has closed
| > over its free variables with the current dynamic values of the lexically
| > visible bindings in the current environment.
| 
| Likewise, there is the view that #'(lambda ...) is an executable form
| for creating a function; a syntactic sugar for the FUNCTION operator
| whose job it is to manufacture functions out of lambda expressions.
+---------------

That's correct as far as it goes [but see below]. There is still, IMHO,
value in distinguishing  between #'(LAMBDA ...) -- simply naming one --
and (LAMBDA ...) -- actually executing it and returning a new value.

+---------------
| > This doesn't seem like
| > "naming" to me so much as "creating", since the resulting closure you
| > get back is [potentially] *different* every time you execute the LAMBDA.
| > Contrast that with (FUNCTION FOO), which always gives you the *same*
| > [functional value of] FOO every time [modulo runtime redefinitions].
| 
| Modulo compile-time redefinitions too.
| 
|  (flet (foo (...) ...) (function foo))
| 
| The form #'foo contains, guess what, a free reference which
| captures a lexical binding.
+---------------

You're confusing closure-creation time with closure-reference time.
In your example, closure-creation time is when the FLET binding occurs.
*That's* when the underlying (implicit here) LAMBDA was *executed*.
All subsequent mentions of #'FOO or (FUNCTION FOO) are simply *referencing*
that already-created closure.

+---------------
| And of course the lexical function FOO can itself capture variables,
| and so (function foo) may have to produce a different object on different
| invocations, exactly like (function (lambda ...)) when the lambda
| captures variables.
| 
| Your argument has bit the bag here, sorry. :)
+---------------

Again, you're confusing closure-creation time with closure-reference
time. (FUNCTION FOO) will never capture a *new* free variable reference
[it already had it chance, once when it was FLET-bound], and will never
produce a *different* value, whereas (FUNCTION (LAMBDA (Y) (+ X Y)))
will capture a "new" X each time it's executed, and will return a new,
different closure for each such execution.

Let's back up a step: Whether or not one writes (LAMBDA ...) or
#'(LAMBDA ...) or (FUNCTION (LAMBDA ...)) is really irrelevant
to the semantics. The value that (FUNCTION FOO) produces -- say,
when one does (SETQ BAR (FUNCTION FOO)), which definitely *does*
produce a value!! -- will be "the same" wherever one evaluates it
[within the scope of the binding of #'FOO]. Whereas the closure value
that (FUNCTION (LAMBDA ...)) produces might have captured an entirely
different value each time it is executed. So in that sense (FUNCTION FOO)
is more of a "constant name" and (FUNCTION (LAMBDA ...)) is more of an
"executable form"... *when* it's closing over free variables. When it's
not, then (FUNCTION (LAMBDA ...)) is "just a name" like (FUNCTION FOO).

Given that, all I'm saying is that I prefer to make that distinction
visible in my code by writing #'(LAMBDA ...) when I'm just "naming"
an anonymous function [with no free variables] and by writing
(LAMBDA ...) when I'm "executing" it to capture free variables
and produce a closure value [even though technically there is no
difference under the hood -- either form could be used in either place].

But YMMV...


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607