I'm reading "On Lisp" and noticed the following example:
(mapcar #'(lambda (x) (+ x 10)) '(1 2 3))
However, if I try to omit the #' (which seems logical to me
as mapcar really accepts a function, so to complicate it
by dereferencing a symbol doesn't make much sense), and
write:
(mapcar (lambda (x) (+ x 10)) '(1 2 3))
It also works (GNU CLISP v2.28). Could you Lisp gurus please
elaborate ? What is the right way to do it ?
TIA
--
Eli Bendersky - http://www.geocities.com/spur4444/
> However, if I try to omit the #' (which seems logical to me
> as mapcar really accepts a function, so to complicate it
> by dereferencing a symbol doesn't make much sense), and
> write:
FUNCTION (which is what #' is equivalent to) doesn't `dereference a
symbol', what it does is gets at the functional value of its argument
in the current lexical environment. The argument can either be a
function name (such as a symbol or a list of the form (SETF x)), or it
can be a lambda expression, which `names' an anonymous function.
> (mapcar (lambda (x) (+ x 10)) '(1 2 3))
LAMBDA is defined as a macro, and its expansion is (FUNCTION (LAMBDA
...)). So if you omit the FUNCTION, then the evaluator/compiler will
macroexpand the LAMBDA and essentially put one back in for you.
> What is the right way to do it ?
I prefer to say #'(lambda ...) but it's a matter of taste I suppose.
They are entirely equivalent. If you ever need to use some very old
CL systems, the macro definition of LAMBDA might be missing (it
arrived relatively late in the standardisation process).
--tim
#' is a reader macro just like '. #'x means (function x) just as 'x means
(quote x). It is not as optional as you might think. If you come from a
Scheme background (which I believe you might do because you think that
"logical" /alone/ is useful and has anything to do with language design,
i.e., "alone" as apart from the /premises/ of the logic employed), you
should realize that Common Lisp is not a dialect of Scheme and that you
should endeavor to understand it in its own right.
`lambda´ is a macro that returns the whole form wrapped in a `function´, so
if you observe that it "works", the important thing is to understand /why/.
So when you evaluate (lambda (x) (+ x 10)), the macro is first expanded so
you get (function (lambda (x) (+ x 10))) which can then be evaluated to a
function object and returned.
| Could you Lisp gurus please elaborate? What is the right way to do it?
The right way is to understand what the `function´ special operator does and
then to use it consistently. If you feel uncomfortable with the heavy use
of punctuation marks in the #' reader macro, the easiest solution is to
write "function" out in full.
As you get more experienced with Common Lisp, you will see that `function´
is also used to name functions that consist of more than a symbol name, so
your initial assumption that it is the same as `symbol-function´ should be
discarded as soon as possible.
--
Erik Naggum, Oslo, Norway
Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.
I am not really sure I understand what you are saying here. My reading
of the hyperspec[1] tells me that (lambda (x) (+ x 10)) and
#'(lambda (x) (+ x 10)) are equivalent. If you mean that in the general
case (as in x perhaps) they are not the same, then I think I follow you.
Could you please clarify?
[1] Which might be a bit unstable, since I only started lightly browsing
it a few days ago.
--
Thomas.
Equivalent for what purpose and under what conditions? Surely you
understand that there /are/ differences. So what made you think that these
differences magically disappear and when do you think this happens?
What makes me think that is this paragraph under 'macro LAMBDA' from
the HyperSpec:
"Description:
Provides a shorthand notation for a function special form involving
a lambda expression such that:
(lambda lambda-list [[declaration* | documentation]] form*)
== (function (lambda lambda-list [[declaration* | documentation]] form*))
== #'(lambda lambda-list [[declaration* | documentation]] form*)"
Maybe I am reading it wrong...
I can maybe think of a difference, but that would be pure speculation
and not worth writing down here.
--
Thomas.
Some situations where (function (lambda (x) ...)) is not equivalent
to (lambda (x) ...):
((lambda (x) (+ x 10)) 5) => 15
((function (lambda (x) (+ x 10))) 5) => error
(defmacro foo (x) `(quote ,(car x)))
(foo (function (lambda (x) (+ x 10)))) => FUNCTION
(foo (lambda (x) (+ x 10))) => LAMBDA
(setq expr1 '(function (lambda (x) (+ x 10))))
(setq expr2 '(lambda (x) (+ x 10)))
(equal expr1 (macroexpand expr1)) => t
(equal expr2 (macroexpand expr2)) => nil
Actually it makes a lot of sense, because a lambda expression is not
a function, but a function name.
The MAPCAR function doesn't accept function names. For example,
(mapcar print '(1 2 3))
will not print the elements of the list. Instead the function
call will fail, because PRINT has no value binding. Since you cannot
omit the #' from #'print, it's not reasonable at all to expect
that it can be omitted from #'(lambda ...). But it turns out that
the usage is supported.
> (mapcar (lambda (x) (+ x 10)) '(1 2 3))
This works because Common Lisp has a standard macro called LAMBDA.
This macro allows something meaningful to happen when a lambda
expression is evaluated; namely it bounces that expression to
the FUNCTION operator, to do the equivalent of #'(lambda ...).
Without the macro, this wouldn't work; it would complain that
there is no such function as LAMBDA.
Neither way is preferred over the other; they are both correct.
Incidentally, because a lambda expression is a function name,
this works:
((lambda (x y) (+ x y)) 1 1) ==> 2
In this case, the LAMBDA macro is *not* involved. Quite simply,
a lambda expression in the first position of a list expression
is treated as the name of a function which is created on the
spot.
The forms (lambda (...) ...) and (function (lambda (...) ...)) evaluate
equivalently, but are (of course) different symbolic expressions.
Try figuring out what the following expressions evaluate, and explain why:
(car '(lambda () t))
(car '#'(lambda () t))
(car (macroexpand '(lambda () t)))
BTW, I prefer to use (lambda ...) instead of #'(lambda ...). When I see
"lambda", I already know I'm dealing with an anonymous function, so the
"#'" are just two wasted characters that don't improve the code. Old
school lispers probably disagree. :)
--
Knut Arild Erstad
But if less is more, then just think how much more more will be.
-- from "Frasier"
> The MAPCAR function doesn't accept function names. For example,
>
> (mapcar print '(1 2 3))
What about (mapcar 'print '(1 2 3)). You're passing the name PRINT to
mapcar, no? Of course, I disagree with the idea that (lambda ...) is
a function name, but to each his own. :)
--
-> -/ - Rahul Jain - \- <-
-> -\ http://linux.rice.edu/~rahul -=- mailto:rj...@techie.com /- <-
-> -X "Structure is nothing if it is all you got. Skeletons spook X- <-
-> -/ people if [they] try to walk around on their own. I really \- <-
-> -\ wonder why XML does not." -- Erik Naggum, comp.lang.lisp /- <-
|--|--------|--------------|----|-------------|------|---------|-----|-|
(c)1996-2002, All rights reserved. Disclaimer available upon request.
But that would then be analogous to '(lambda ...). You didn't just
drop #', but added '.
> Of course, I disagree with the idea that (lambda ...) is
> a function name, but to each his own. :)
My mistake; re-reading the glossary definition, I see that it's
a ``list which can be used in place of a function name in certain contexts
to denote a function by directly describing its behavior ...''.