Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Basics of #'(lambda ...

14 views
Skip to first unread message

Eli Bendersky

unread,
Aug 19, 2002, 10:58:53 AM8/19/02
to
Hi all,

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/


Tim Bradshaw

unread,
Aug 19, 2002, 11:08:40 AM8/19/02
to
* Eli Bendersky wrote:

> 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

Erik Naggum

unread,
Aug 19, 2002, 12:54:32 PM8/19/02
to
* Eli Bendersky

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

#' 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.

Thomas Stegen CES2000

unread,
Aug 19, 2002, 5:26:14 PM8/19/02
to
"Erik Naggum" <er...@naggum.no> wrote in message
news:32387648...@naggum.no...

> * Eli Bendersky
> | 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)
>
> #' 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.

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.


Erik Naggum

unread,
Aug 19, 2002, 5:34:25 PM8/19/02
to
* Thomas Stegen CES2000

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

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?

Thomas Stegen CES2000

unread,
Aug 19, 2002, 5:53:36 PM8/19/02
to
"Erik Naggum" <er...@naggum.no> wrote in message
news:32387816...@naggum.no...

> * Thomas Stegen CES2000
> | 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.
>
> 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.


Joe Marshall

unread,
Aug 19, 2002, 7:38:27 PM8/19/02
to

"Thomas Stegen CES2000" <tho_s...@hotmail.com> wrote in message news:3d61...@nntphost.cis.strath.ac.uk...

> "Erik Naggum" <er...@naggum.no> wrote in message
> news:32387648...@naggum.no...
> > * Eli Bendersky
> > | 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)
> >
> > #' 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.
>
> 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?

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

Kaz Kylheku

unread,
Aug 19, 2002, 8:14:50 PM8/19/02
to
Eli Bendersky <just....@in.the.newsgroup> wrote in message news:<3D6107AD...@in.the.newsgroup>...

> Hi all,
>
> 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:

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.

Knut Arild Erstad

unread,
Aug 19, 2002, 8:43:35 PM8/19/02
to
[Thomas Stegen CES2000]
:
: 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.

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"

Rahul Jain

unread,
Aug 20, 2002, 4:31:27 AM8/20/02
to
k...@ashi.footprints.net (Kaz Kylheku) writes:

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

Kaz Kylheku

unread,
Aug 20, 2002, 3:20:54 PM8/20/02
to
Rahul Jain <ra...@rice.edu> wrote in message news:<873ctau...@photino.localnet>...

> k...@ashi.footprints.net (Kaz Kylheku) writes:
>
> > 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?

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 ...''.

0 new messages