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

#' and lambda

236 views
Skip to first unread message

verec

unread,
Feb 10, 2006, 8:31:39 AM2/10/06
to
Consider:

(defun weird+ (list)
(reduce (lambda (a b)
(when (and a b)
(+ a b)))
list))

(defun weird++ (list)
(reduce #'(lambda (a b)
(when (and a b)
(+ a b)))
list))

CL-USER 2 > (weird+ '(1 2 3))
6

CL-USER 3 > (weird++ '(1 2 3))
6

In code I see here and there, #'(lambda ... is way more
common than simply (lambda ... yet I just don't see why,
in this context,

(function (lambda ...

is any better than just

(lambda ...

Is this a stylistic issue, or am I missing something
more subtle (again :-(

Many thanks
--
JFB

Pascal Costanza

unread,
Feb 10, 2006, 8:50:08 AM2/10/06
to
verec wrote:
> In code I see here and there, #'(lambda ... is way more
> common than simply (lambda ... yet I just don't see why,
> in this context,
>
> (function (lambda ...
>
> is any better than just
>
> (lambda ...
>
> Is this a stylistic issue, or am I missing something
> more subtle (again :-(

It's a stylistic issue. (lambda ...) is a macro that expands into
(function (lambda ...)), and function is a special operator that knows
how to treat an embedded lambda expression. So you get exactly the same
effect in both cases.

Some people prefer #'(lambda ...) because it fits better with the
Lisp-2-ness of Common Lisp. Other people prefer (lambda ...) because at
least that form doesn't need the "silly" #' syntax. Finally, there are
people who prefer (lambda ...) because it's just less to type and saves
two characters of indentation. I am in the latter category, but that
seems to be rare...


Pascal

--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/

verec

unread,
Feb 10, 2006, 9:03:31 AM2/10/06
to
On 2006-02-10 13:50:08 +0000, Pascal Costanza <p...@p-cos.net> said:

> (lambda ...) is a macro that expands into (function (lambda ...)),

Huh?

This reads to me as "X is a macro that expands into (function (X ...))

This may well be what you mean; are you really saying that
lambda is both a macro and "something else" ?

Many thanks
--
JFB

Edi Weitz

unread,
Feb 10, 2006, 9:14:31 AM2/10/06
to
On Fri, 10 Feb 2006 14:03:31 +0000, verec <ve...@mac.com> wrote:

> This may well be what you mean; are you really saying that lambda is
> both a macro and "something else" ?

Yep.

<http://www.lispworks.com/documentation/HyperSpec/Body/a_lambda.htm>

--

European Common Lisp Meeting 2006: <http://weitz.de/eclm2006/>

Real email: (replace (subseq "spam...@agharta.de" 5) "edi")

Lars Brinkhoff

unread,
Feb 10, 2006, 9:20:47 AM2/10/06
to
Edi Weitz <spam...@agharta.de> writes:
> On Fri, 10 Feb 2006 14:03:31 +0000, verec <ve...@mac.com> wrote:
>> This may well be what you mean; are you really saying that lambda
>> is both a macro and "something else" ?
> Yep.
> <http://www.lispworks.com/documentation/HyperSpec/Body/a_lambda.htm>

And perhaps also:

http://clhs.lisp.se/Body/s_fn.htm

Duncan Harvey

unread,
Feb 10, 2006, 9:39:35 AM2/10/06
to
verec <ve...@mac.com> wrote:

> On 2006-02-10 13:50:08 +0000, Pascal Costanza <p...@p-cos.net> said:
>
> > (lambda ...) is a macro that expands into (function (lambda ...)),
>
> Huh?
>
> This reads to me as "X is a macro that expands into (function (X ...))

For X = LAMBDA this is true, as Pascal states.

FUNCTION accepts either a function name (i.e. a symbol[1]) or an
expression denoting a literal, anonymous function (i.e. a lambda
expression). You are discussing this second case, therefore it would be
a mistake to try to generalise Pascal's statement to include named
functions.

> This may well be what you mean; are you really saying that
> lambda is both a macro and "something else" ?

LAMBDA is both a macro and a symbol placed at the head of the lists used
to represent literal, anonymous functions.

Should you have a copy of Graham's /ANSI Common Lisp/ book, the side bar
on page 26 (and associated end note) describe this well.

[1] or a list of the form: (SETF <symbol>).
--
Duncan Harvey

verec

unread,
Feb 10, 2006, 11:15:15 AM2/10/06
to
On 2006-02-10 14:39:35 +0000, usenet-...@abbrvtd.org.uk (Duncan
Harvey) said:

> Should you have a copy of Graham's /ANSI Common Lisp/ book, the side bar
> on page 26 (and associated end note) describe this well.

Indeed. The note at page 402 to the sidebar of page 26 adds:

"In ANSI Common Lisp there is also a lambda macro that
allows you to write (lambda (x) x) for #'(lambda (x) x).
Since the use of this macro obscures the symmetry between
lambda expressions and symbolic function names (where you
still have to use sharp-quote), it yields a specious sort
of elegance at best."

Which I take as meaning; dispense with the use of the
macro, and always write #'(lambda ... rather than (lambda ...

Hmmm...

This question has been puzzling me for a while, because
Lisp-2 or not, I see arguments passed to functions as
single values, What I mean is

(defun foo (x)
(funcall x))

(defun foo (x)
(+ x 3))

x is "just" a stack-frame slot, whether it came from the
symbol-function slot of some symbol or its symbol-value
slot.

Which was making

(reduce #'(lambda (x) ...

a bit mysterious:

(lambda (x) ...

is returning a piece of anonymous executable behavior...
(that which the CLHS refers to as a "function object", right?)

So being anonymous, the question of name-space doesn't really
apply.

So the question as to why sharp-quote should be applied
*not* to some Lisp-2 symbol, *but* to a stack slot whose contents
is a "pointer" to executable behavior is still puzlling...

Obviously, I'm still missing something.
--
JFB

Brian Downing

unread,
Feb 10, 2006, 11:46:35 AM2/10/06
to
In article <43ecbc14$0$1167$5a6a...@news.aaisp.net.uk>,

verec <ve...@mac.com> wrote:
> So the question as to why sharp-quote should be applied
> *not* to some Lisp-2 symbol, *but* to a stack slot whose contents
> is a "pointer" to executable behavior is still puzlling...

Actually I think this is where the macro makes things a bit
confusing, semantically. A lambda expression just names a function,
it doesn't return anything. FUNCTION does that.

I find it's easier to think about it like this:

(function foo) returns the function named by the symbol FOO.
(foo x) calls it (its name is in the CAR of the form).

(function (lambda (x) (* x x))) returns the function named by
(lambda (x) (* x x)). ((lambda (x) (* x x)) x) calls it (its
name is in the CAR of the form).

Of course, that symmetry that breaks for (setf foo) functions.
Oh well!

Having the LAMBDA macro makes one think that evaluating LAMBDA itself
returns a function object, which makes the ((lambda ...) ...) syntax
seem really out of place - if it evaluates its CAR, why doesn't
anything else?

(That being said, I usually wind up leaving the sharpquote off lambda
without even thinking about it. :-)

-bcd
--
*** Brian Downing <bdowning at lavos dot net>

Duncan Harvey

unread,
Feb 10, 2006, 12:16:22 PM2/10/06
to
verec <ve...@mac.com> wrote:

> This question has been puzzling me for a while, because
> Lisp-2 or not, I see arguments passed to functions as
> single values

> [...]


>
> Which was making
>
> (reduce #'(lambda (x) ...
>
> a bit mysterious:
>
> (lambda (x) ...
>
> is returning a piece of anonymous executable behavior...

No, it's the
(function (lambda (x) ...
that does that.

It can be easier to understand if one ignores the LAMBDA macro for the
time being. The macro is much easier to understand afterwards as a
straightforward piece of syntactic sugar.

(lambda (x) ...
by itself is just some unquoted list structure. It is its appearance as
an argument to the FUNCTION special form
(function (lambda (x) ...
that causes the function object to exist[1].

> So the question as to why sharp-quote should be applied
> *not* to some Lisp-2 symbol, *but* to a stack slot whose contents
> is a "pointer" to executable behavior is still puzlling...

Again, if the sharp-quote (or rather, the underlying FUNCTION special
form) had not been present there would be no function object to point
to. So, for example (if the LAMBDA macro did not exist):
(mapcar (lambda (x) (1+ x)) '(1 2 3))
would cause an "Undefined function LAMBDA invoked" error in the same
manner as this:
(mapcar (bouncy-bob (x) (1+ x)) '(1 2 3))


[1] or its presence as the first element of a function call, thus:
((lambda (x) (+ x x)) 12)
is equivalent to:
(funcall (function (lambda (x) (+ x x))) 12)
--
Duncan Harvey

Alan Crowe

unread,
Feb 10, 2006, 1:04:02 PM2/10/06
to
verec <ve...@mac.com> writes:

> On 2006-02-10 14:39:35 +0000, usenet-...@abbrvtd.org.uk (Duncan
> Harvey) said:
>
> > Should you have a copy of Graham's /ANSI Common Lisp/ book, the side bar
> > on page 26 (and associated end note) describe this well.
>
> Indeed. The note at page 402 to the sidebar of page 26 adds:
>
> "In ANSI Common Lisp there is also a lambda macro that
> allows you to write (lambda (x) x) for #'(lambda (x) x).
> Since the use of this macro obscures the symmetry between
> lambda expressions and symbolic function names (where you
> still have to use sharp-quote), it yields a specious sort
> of elegance at best."
>
> Which I take as meaning; dispense with the use of the
> macro, and always write #'(lambda ... rather than (lambda ...
>
> Hmmm...

I've never really got what Graham is on about here.

When a form to be evaluated is a list, the first location in
the list follows special rules, it is either a symbol or a
very particular kind of list, one that begins with the
symbol lambda. You can see FUNCTION as an operator whose
argument works by the exact same rules. In which case it
becomes possible to write a form that evaluates to a
function like this: (function (lambda (x)(* x x)))

If you come at it from that direction then you will soon
tire of writing "(function (lambda" and want to use the #'
abbreviation. Having a macro called lambda to let you leave
off the #' may seem weird and hacky.

However, I don't see the attraction of coming at it from
that direction. It seems very natural to expect CL to
include an operator that lets you write a form that
evaluates to a function. It has to be called something,
perhaps make-function? It might as well be called lambda.

From this direction (lambda (x)(* x x)) is basic. One also
needs to be able to access the function name space in
evaluation positions, so you need to be able to write
(function /symbol/), but "(function (lambda" is redundant
and just a waste of effort.

Further more, the language feature of being able to put a
lambda list as the first element of a list that is a form to
be evaluated is not needed. Unstead of

((lambda(x y)(+ x y)) 5 7) => 12

you can just write

(funcall (lambda(x y)(+ x y)) 5 7) => 12

Looked at from this way round it is ((lambda(x y)(+ x y)) 5 7)
that is the weird, hacky abbreviation, "(function (lambda"
is a waste of space, and #'(lambda is an abbreviation that
is two characters longer than the thing it is abbreviating.

Alan Crowe
Edinburgh
Scotland

verec

unread,
Feb 10, 2006, 7:20:42 PM2/10/06
to
On 2006-02-10 18:04:02 +0000, Alan Crowe <al...@cawtech.freeserve.co.uk> said:

Thank you all for your explanations.

so the reason this works:

(defun weird-2 (f list)
(reduce f list))

CL-USER 1 > (weird-2 #'+ '(1 2 3))
6
CL-USER 2 > (weird-2 (lambda (a b) (when (and a b) (+ a b))) '(1 2 3))
6
CL-USER 3 > (weird-2 #'(lambda (a b) (when (and a b) (+ a b))) '(1 2 3))
6

is because weird-2 just doesn't care where f comes from,
and because #' special cases (lambda...

But #' doesn't special case anything else, and that's
why:

(defun weird-3 (f list)
(reduce #'f list))

doesn't even compile (well, it does, but issues a warning).

But then
(defun weird-4 (list)
(flet ((f (a b)
(when (and a b)
(+ a b))))
(reduce #'f list)))

does compile, and work:
CL-USER 5 > (weird-4 '(1 2 3))
6

My head still hurts a bit :-(

I'll review all this tomorrow.

Many thanks to all
--
JFB

Thomas A. Russ

unread,
Feb 10, 2006, 6:27:06 PM2/10/06
to
Pascal Costanza <p...@p-cos.net> writes:

> verec wrote:
> > In code I see here and there, #'(lambda ... is way more
> > common than simply (lambda ... yet I just don't see why,
> > in this context,
>

> It's a stylistic issue. (lambda ...) is a macro that expands into
> (function (lambda ...)), and function is a special operator that knows
> how to treat an embedded lambda expression. So you get exactly the same
> effect in both cases.

It's also compounded by the fact that the LAMBDA macro was a rather late
addition the ANSI Common Lisp, so all of the really old guys (i.e., like
me) learned their lisp when you needed to supply the #' to the lambda
expression in the mapping functions. Otherwise the non-existent lambda
function would be invoked.

The macro addition changed that, but some of us are too set in our ways
to want to change.


--
Thomas A. Russ, USC/Information Sciences Institute

Thomas A. Russ

unread,
Feb 10, 2006, 6:24:47 PM2/10/06
to
verec <ve...@mac.com> writes:

> On 2006-02-10 14:39:35 +0000, usenet-...@abbrvtd.org.uk (Duncan

> Which was making
>
> (reduce #'(lambda (x) ...
>
> a bit mysterious:

Well, this should be mysterious, since REDUCE needs a function of two
arguments. One would expect to see

(reduce #'(lambda (x y) ...

instead.

Barry Margolin

unread,
Feb 10, 2006, 8:26:23 PM2/10/06
to
In article <Lr3Hf.548096$084.324960@attbi_s22>,
Brian Downing <see-si...@lavos.net> wrote:

> Having the LAMBDA macro makes one think that evaluating LAMBDA itself
> returns a function object, which makes the ((lambda ...) ...) syntax
> seem really out of place - if it evaluates its CAR, why doesn't
> anything else?

The reason this isn't much of a problem is that ((lambda ...) ...)
syntax is virtually never used any more. It was used decades ago,
before LET was created, but now it has little practical use (I can't
think of any reason to use it offhand). Maybe there are some macros
that have some reason for expanding into a call to a lambda rather than
a LET expression -- there are some slight differences in the effect of
declarations at the head of the body (which is why LET is no longer
simply a macro that expands into a call to the corresponding lambda
expression, as it was in MACLISP).

> (That being said, I usually wind up leaving the sharpquote off lambda
> without even thinking about it. :-)

As a corollary of what I said above, in modern code (LAMBDA ...) is
never used without being preceded by sharpquote. So there seems to be a
redundancy. All the other uses of #' are necessary to indicate how the
function name should be evaluated -- as a function name or with ordinary
expression evaluation -- but there was no "ordinary expression
evaluation" for a lambda expression. Since LAMBDA was available as an
operator name, they decided to just use it to conflate this redundancy.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***

Duncan Harvey

unread,
Feb 10, 2006, 8:36:19 PM2/10/06
to
Thomas A. Russ <t...@sevak.isi.edu> wrote:

> verec <ve...@mac.com> writes:
>
> > Which was making
> >
> > (reduce #'(lambda (x) ...
> >
> > a bit mysterious:
>
> Well, this should be mysterious, since REDUCE needs a function of two
> arguments.

Well, if you're going to be pedantic about somebody else's mysteries,
REDUCE needs a function that can accept /zero/ or two arguments (in
general)...

--
Duncan Harvey

Kaz Kylheku

unread,
Feb 11, 2006, 1:49:44 AM2/11/06
to

verec wrote:
> On 2006-02-10 14:39:35 +0000, usenet-...@abbrvtd.org.uk (Duncan
> Harvey) said:
>
> > Should you have a copy of Graham's /ANSI Common Lisp/ book, the side bar
> > on page 26 (and associated end note) describe this well.
>
> Indeed. The note at page 402 to the sidebar of page 26 adds:
>
> "In ANSI Common Lisp there is also a lambda macro that
> allows you to write (lambda (x) x) for #'(lambda (x) x).
> Since the use of this macro obscures the symmetry between
> lambda expressions and symbolic function names (where you
> still have to use sharp-quote), it yields a specious sort
> of elegance at best."
>
> Which I take as meaning; dispense with the use of the
> macro, and always write #'(lambda ... rather than (lambda ...

The symmetry he is talking about is:

(name arg) ;; call the function

(funcall #'name arg) ;; call the function

Here, NAME can be a lambda expression or a symbol. But that symmetry
isn't perfect to begin with. Observe:

(funcall 'symbol arg) ;; use symbol's function binding

(funcall '(lambda ...) arg) ;; doesn't work! A quoted list isn't a
function in any sense.

So if you are going to quibble about symmetries being broken, make sure
they are ... err symmetric to begin with.

But the symmetry is NOT broken, watch ...

> Hmmm...
>
> This question has been puzzling me for a while, because
> Lisp-2 or not, I see arguments passed to functions as
> single values, What I mean is
>
> (defun foo (x)
> (funcall x))

Using this example, we can rescues the symmetry from violation.

You can pretend that (LAMBDA ....) is a function name, which has a
value binding. That's in fact what is going on: the lambda expression
is evaluated, and produces a value. That value is is the function.
(What else should it be?)

> (defun foo (x)
> (+ x 3))
>
> x is "just" a stack-frame slot, whether it came from the
> symbol-function slot of some symbol or its symbol-value
> slot.
>
> Which was making
>
> (reduce #'(lambda (x) ...
>
> a bit mysterious:
>
> (lambda (x) ...
>
> is returning a piece of anonymous executable behavior...

Not in the above example it isn't returning anything. In the above
REDUCE example, the lambda expression is just syntax: an argument to
the FUNCTION operator. It's the function operator which understands how
to parse that function name, the lambda expression, and produce a
function object out of it. The lambda is just dead tree material (parse
tree wood, that is, not paper!). :)

(lambda (x) ...) ;; the lambda /operator/ parses itself and returns
a function

#'(lambda (x) ...) ;; the function operator parses the lambda, and
returns a function

It looks a lot like as if (lambda ...) is a complicated kind of symbol
with a value binding and a function binding, both going to the same
function.

> (that which the CLHS refers to as a "function object", right?)
>
> So being anonymous, the question of name-space doesn't really
> apply.

But

X

also yields some anonymous value, the value of the binding of X. Do
questions of namespace also not apply to X just because its value has
no name? :)

> So the question as to why sharp-quote should be applied
> *not* to some Lisp-2 symbol, *but* to a stack slot whose contents
> is a "pointer" to executable behavior is still puzlling...

But it shouldn't. If X is a lexical variable ("stack slot", as you say,
or more likely a closure vector slot), #'X doesn't have anything to do
with that lexical variable. It resolves to the global (or lexical)
function binding of X. The value of X, or whether it even has one, is
irrelevant.

Kaz Kylheku

unread,
Feb 11, 2006, 2:08:11 AM2/11/06
to

Not really. If I have a symbol X, I can make its function and value
binding both point to the same function. Lexically too!

(flet ((x (arg)))
(let ((x #'x))
(funcall x 3) ;; with or without #', just like lambda!!!
(funcall #'x 3)
(x 3)))

So a lambda is nothing more than a name that comes out of the factory
with both bindings set to the same object.

> However, I don't see the attraction of coming at it from
> that direction. It seems very natural to expect CL to
> include an operator that lets you write a form that
> evaluates to a function. It has to be called something,
> perhaps make-function? It might as well be called lambda.

It's called FUNCTION.

> From this direction (lambda (x)(* x x)) is basic. One also
> needs to be able to access the function name space in
> evaluation positions, so you need to be able to write
> (function /symbol/), but "(function (lambda" is redundant
> and just a waste of effort.

But it's not redundant in one place: macros.

If you're writing a macro that accepts a function name as an argument,
you want it to work with lambda expressions or symbols, or any other
kind of function name supported by your Lisp.

In that macro, you have to write (function ,function-name-arg) if you
want the object, since you can't assume that it's a lambda.

> Further more, the language feature of being able to put a
> lambda list as the first element of a list that is a form to
> be evaluated is not needed. Unstead of

Again, it may be needed in macros. If N is a macro parameter
representing a function name, then your macro can stick it into the
first position of a list to generate a form that calls that function.
It doesn't have to care whether it's a lambda, symbol or what.

> ((lambda(x y)(+ x y)) 5 7) => 12
>
> you can just write
>
> (funcall (lambda(x y)(+ x y)) 5 7) => 12

Well, you'd actually just write

(let ((x 5) (y 7)) (+ x y))

:)

> Looked at from this way round it is ((lambda(x y)(+ x y)) 5 7)
> that is the weird, hacky abbreviation, "(function (lambda"

But, but, but, that's how it's done in Lambda Calculus, which has no
FUNCALL or LET. :)

:)

Pascal Bourguignon

unread,
Feb 11, 2006, 2:13:01 AM2/11/06
to
"Kaz Kylheku" <kkyl...@gmail.com> writes:
>
>> Looked at from this way round it is ((lambda(x y)(+ x y)) 5 7)
>> that is the weird, hacky abbreviation, "(function (lambda"
>
> But, but, but, that's how it's done in Lambda Calculus, which has no
> FUNCALL or LET. :)

Indeed, and it's needed to implement LET.

--
__Pascal Bourguignon__ http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"

Ulrich Hobelmann

unread,
Feb 11, 2006, 4:57:18 AM2/11/06
to
Kaz Kylheku wrote:
> (funcall 'symbol arg) ;; use symbol's function binding

You mean, it does THE SAME as
(funcall #'symbol arg) ?

Now I'm really wondering why we have #' in the first place...

--
Suffering from Gates-induced brain leakage...

Duncan Harvey

unread,
Feb 11, 2006, 5:15:24 AM2/11/06
to
Ulrich Hobelmann <u.hob...@web.de> wrote:

> Kaz Kylheku wrote:
> > (funcall 'symbol arg) ;; use symbol's function binding
>
> You mean, it does THE SAME as
> (funcall #'symbol arg) ?

No, it does not. Note Kaz's comment, quoted above. Witness:

CL-USER 7 > (defun whoosh ()
(print 'global)
(values))
WHOOSH

CL-USER 8 > (whoosh)

GLOBAL

CL-USER 9 > (flet ((whoosh ()
(print 'lexical)
(values)))
(whoosh)
(funcall #'whoosh)
(funcall 'whoosh))

LEXICAL
LEXICAL
GLOBAL

CL-USER 10 >

> Now I'm really wondering why we have #' in the first place...

Because of that Lisp-2ness that you've heard about.

--
Duncan Harvey

Edi Weitz

unread,
Feb 11, 2006, 5:26:44 AM2/11/06
to
On Sat, 11 Feb 2006 10:57:18 +0100, Ulrich Hobelmann <u.hob...@web.de> wrote:

> Kaz Kylheku wrote:
>> (funcall 'symbol arg) ;; use symbol's function binding
>
> You mean, it does THE SAME as
> (funcall #'symbol arg) ?

No.

CL-USER 1 > (defun foo () 42)
FOO

CL-USER 2 > (flet ((foo () 43))
(list (funcall 'foo) (funcall #'foo)))
(42 43)

Cheers,
Edi.

Ulrich Hobelmann

unread,
Feb 11, 2006, 5:41:40 AM2/11/06
to
Duncan Harvey wrote:
> Ulrich Hobelmann <u.hob...@web.de> wrote:
>
>> Kaz Kylheku wrote:
>>> (funcall 'symbol arg) ;; use symbol's function binding
>> You mean, it does THE SAME as
>> (funcall #'symbol arg) ?
>
> No, it does not. Note Kaz's comment, quoted above. Witness:

> CL-USER 9 > (flet ((whoosh ()


> (print 'lexical)
> (values)))
> (whoosh)
> (funcall #'whoosh)
> (funcall 'whoosh))
>
> LEXICAL
> LEXICAL
> GLOBAL

So FLET doesn't set the function binding, but something else?

>> Now I'm really wondering why we have #' in the first place...
>
> Because of that Lisp-2ness that you've heard about.

--

j...@codeartist.org

unread,
Feb 11, 2006, 7:37:32 AM2/11/06
to
You can think of FUNCTION to be a special operator to look up functions
by name in the lexical environment. This is why it cannot be (function
'foo) but has to be (function foo) because after compile-time there is
no connection between a symbol and the lexical binding. For anonymous
functions you can use a so called "lambda expression" instead of the
name. So a lambda expression is a name-like thing for functions without
names.

If you would have Scheme-like evaluation behaviour (where the first
place in a form gets evaluated the same way as any other places) you
would need to write something like this if the function and variable
namespaces are disjunct:

((function +) 1 2) => 3

But Common Lisp does this (function +) name lookup implicitely for the
first position - so you can write:

(+ 1 2) instead of ((function +) 1 2)

or

((lambda (x) (+ x 1)) 2) instead of ((function (lambda (x) (+ x 1))) 2)

But if you want to do a _lexical_ function name lookup in another place
than the first place of a form, you have to use (function ..) again.
Because writing (function ..) all over the place can get tiresome there
is the #' reader macro to make it a bit shorter. Then, some clever guy
came along and saw that there is no operator called "lambda" in CL and
had an idea to make use of it. He wrote a macro called lambda which
just wraps a function around to make a valid lambda-expression lookup.
So the macro lambda is the macroexpansion equivalent to the reader
macro #' applied to lambda expressions. As others already have said: If
you think of a lambda expression as some kind of function name - then
the lambda macro resembles a value binding for anonymous functions.

ciao,
Jochen Schmidt

j...@codeartist.org

unread,
Feb 11, 2006, 7:50:46 AM2/11/06
to
Ulrich Hobelmann wrote:
> So FLET doesn't set the function binding, but something else?

No - it sets the _lexical_ function binding. If you do a FUNCALL using
a symbol it will access the global function binding (the
SYMBOL-FUNCTION slot of the given symbol).

ciao,
Jochen

Rob Warnock

unread,
Feb 11, 2006, 8:13:52 AM2/11/06
to
Duncan Harvey <usenet-...@abbrvtd.org.uk> wrote:
+---------------

| Ulrich Hobelmann <u.hob...@web.de> wrote:
| CL-USER 7 > (defun whoosh () (print 'global) (values))
| WHOOSH
| CL-USER 8 > (whoosh)
| GLOBAL
| CL-USER 9 > (flet ((whoosh () (print 'lexical) (values)))
| (whoosh)
| (funcall #'whoosh)
| (funcall 'whoosh))
| LEXICAL
| LEXICAL
| GLOBAL
| CL-USER 10 >
+---------------

You can go one step further:

> (flet ((whoosh () (print 'lexical) (values))

(whoosh2 () (print 'lexical2) (values)))
(let ((whoosh #'whoosh2))


(whoosh)
(funcall #'whoosh)
(funcall 'whoosh)

(funcall whoosh)))

LEXICAL
LEXICAL
GLOBAL
LEXICAL2
>


-Rob

p.s. And if CL had non-special globals, we could add one more still:

> (defun whoosh2 () (print 'global2) (values))
> (deflexical whoosh #'whoosh2)


> (flet ((whoosh () (print 'lexical) (values))

(whoosh2 () (print 'lexical2) (values)))
(let ((whoosh #'whoosh2))


(whoosh)
(funcall #'whoosh)
(funcall 'whoosh)

(funcall whoosh)
(funcall (symbol-value 'whoosh))))

LEXICAL
LEXICAL
GLOBAL
LEXICAL2
GLOBAL2
>

But that's not CL. [And the DEFINE-SYMBOL-MACRO hack for "global
lexicals" would be cheating, since it needs to point to some *other*
global variable besides WHOOSH, to avoid contaminating WHOOSH with
"specialness", otherwise the (LET ((WHOOSH #'WHOOSH2)) ...) would
rebind the global.]

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

Marcin 'Qrczak' Kowalczyk

unread,
Feb 11, 2006, 8:48:41 AM2/11/06
to
j...@codeartist.org writes:

> Then, some clever guy came along and saw that there is no operator
> called "lambda" in CL and had an idea to make use of it. He wrote
> a macro called lambda which just wraps a function around to make a
> valid lambda-expression lookup.

I've heard that this was for compatibility with ISLisp.

(Such macro couldn't be written portably by user code,
because it rebinds a standard Common Lisp symbol.)

--
__("< Marcin Kowalczyk
\__/ qrc...@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/

Peter Seibel

unread,
Feb 11, 2006, 9:33:35 AM2/11/06
to
Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> writes:

> j...@codeartist.org writes:
>
>> Then, some clever guy came along and saw that there is no operator
>> called "lambda" in CL and had an idea to make use of it. He wrote
>> a macro called lambda which just wraps a function around to make a
>> valid lambda-expression lookup.
>
> I've heard that this was for compatibility with ISLisp.
>
> (Such macro couldn't be written portably by user code,
> because it rebinds a standard Common Lisp symbol.)

Yes, in order to allow one to implement ISLISP as a compatability
layer on top of Common Lisp. (I believe it was Kent Pitman who pushed
to have it added to CL as he was also involved in the ISLISP
standardization effort.)

-Peter

--
Peter Seibel * pe...@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/

j...@codeartist.org

unread,
Feb 11, 2006, 9:35:12 AM2/11/06
to
Well - I did not mean it literally; particularily not in a way that it
may have been brought up by an outsider. Actually it was defined while
ANSI CL was specified so there is no problem here.

Coby Beck

unread,
Feb 11, 2006, 9:42:34 AM2/11/06
to
"Duncan Harvey" <usenet-...@abbrvtd.org.uk> wrote in message
news:1halap0.1yqil3s191tn2xN%usenet-...@abbrvtd.org.uk...

> Ulrich Hobelmann <u.hob...@web.de> wrote:
>
>> Kaz Kylheku wrote:
>> > (funcall 'symbol arg) ;; use symbol's function binding
>>
>> You mean, it does THE SAME as
>> (funcall #'symbol arg) ?
>
> No, it does not. Note Kaz's comment, quoted above. Witness:
>
> CL-USER 7 > (defun whoosh ()
> (print 'global)
> (values))
> WHOOSH
>
> CL-USER 8 > (whoosh)
>
> GLOBAL
>
> CL-USER 9 > (flet ((whoosh ()
> (print 'lexical)
> (values)))
> (whoosh)
> (funcall #'whoosh)
> (funcall 'whoosh))
>
> LEXICAL
> LEXICAL
> GLOBAL

I also recall getting different behaviour from #'whoosh and 'whoosh when
there was only a global function binding. IIRC, I asked about it here and
Kent Pitman among others discussed it with me (summer/fall 2001). I *think*
this was conforming behaviour (LW 4) though not required and by consensus
not desired: in a (mapcar #'whoosh long-list) where whoosh was redefined
during the iteration the new definition was never used, whereas if I used
'whoosh the new definition was used as soon as available. Presumably an
optimisation, retrieving the function was and using it many time vs calling
(symbol-function 'whoosh) every time before using it.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")


Duncan Harvey

unread,
Feb 11, 2006, 10:59:08 AM2/11/06
to
verec <ve...@mac.com> wrote:

> But #' doesn't special case anything else, and that's
> why:
>
> (defun weird-3 (f list)
> (reduce #'f list))
>
> doesn't even compile (well, it does, but issues a warning).

The F in the parameter list and the #'F in the call to REDUCE refer to
different namespaces. Hence CL being referred to as a 'Lisp-2'.

So in your example the #'F is unrelated to the argument F. Because
there are no functions called F defined lexically, #'F refers to the
(non-existent) global function F.

Thus if someone had done:
(defun f (a b)
(+ a b))
before or after[1] the definition of WEIRD-3 this would work:
(weird-3 #'+ '(1 2 3))
(weird-3 #'print '(1 2 3))
(weird-3 nil '(1 2 3))
(weird-3 "loud trumpet" '(1 2 3))

Note that it is irrelevant what we pass as the first argument because
that value is never used by WEIRD-3.

> But then
> (defun weird-4 (list)
> (flet ((f (a b)
> (when (and a b)
> (+ a b))))
> (reduce #'f list)))
>
> does compile, and work:
> CL-USER 5 > (weird-4 '(1 2 3))
> 6

Yes, here there is a function named F lexically visible at REDUCE's
invocation.

[1] being able to define it afterwards demonstrates one aspect of Common
Lisp's dynamic nature and why WEIRD-3 most definitely compiled.
--
Duncan Harvey

alex...@gmail.com

unread,
Feb 11, 2006, 12:07:18 PM2/11/06
to
verec wrote:

> But #' doesn't special case anything else, and that's
> why:
>
> (defun weird-3 (f list)
> (reduce #'f list))
>
> doesn't even compile (well, it does, but issues a warning).

Strange, I'm getting no errors with

(define (weird-3 f list)
(reduce f list))

Duncan Harvey

unread,
Feb 11, 2006, 12:23:49 PM2/11/06
to
<alex...@gmail.com> wrote:

Strange, I'm getting no errors with:

void *reduce(void * (*)(void *, void *), void *);
void *weird_3(void * (*f)(void *, void *), void *list)
{
return reduce(f, list);
}

--
Duncan Harvey

Rob Warnock

unread,
Feb 12, 2006, 12:16:33 AM2/12/06
to
Coby Beck <cb...@mercury.bc.ca> wrote:
+---------------

| I also recall getting different behaviour from #'whoosh and 'whoosh when
| there was only a global function binding. IIRC, I asked about it here and
| Kent Pitman among others discussed it with me (summer/fall 2001). I *think*
| this was conforming behaviour (LW 4) though not required and by consensus
| not desired: in a (mapcar #'whoosh long-list) where whoosh was redefined
| during the iteration the new definition was never used...
+---------------

This is *required* behavior! MAPCAR is a function, and Common Lisp
is call-by-value, so the argument is evaluated *once*, produces a
function object, and that [which is constant, immutable] is passed
to MAPCAR, just as if you had said this:

(let ((temp #'whoosh))
(mapcar temp long-list))

Changing the function binding of WHOOSH during the call can have no
possible effect on the constant/immutable function object.

+---------------
| ...whereas if I used 'whoosh the new definition was used as soon
| as available.
+---------------

That behavior is the one which I believe is optional. In this case
what you are passing to MAPCAR is a symbol, not a function, and
all CLHS "MAPCAR" says is:

If function is a symbol, it is coerced to a function as if by
SYMBOL-FUNCTION.

It leaves unspecified whether that coersion occurs just once upon
entry to MAPCAR or repeatedly before each step of the list traversal.

+---------------


| Presumably an optimisation, retrieving the function was and using
| it many time vs calling (symbol-function 'whoosh) every time before
| using it.

+---------------

Yup. Note that unless APPLY is inlined within MAPCAR (and friends),
it is likely that in most implememntations the function-designator
argument will simply be passed on to APPLY unmodified, and thus APPLY
will do any needed SYMBOL-FUNCTION coercion for each list item.
[This is the case in CLISP & CMUCL, at least.]

But AFAICT there is nothing in the CLHS *forbidding* the optimization
of calling SYMBOL-FUNCTION only once in MAPCAR...


-Rob

Kaz Kylheku

unread,
Feb 12, 2006, 4:19:28 AM2/12/06
to
Ulrich Hobelmann wrote:
> Kaz Kylheku wrote:
> > (funcall 'symbol arg) ;; use symbol's function binding
>
> You mean, it does THE SAME as
> (funcall #'symbol arg) ?
>
> Now I'm really wondering why we have #' in the first place...

I shouldn't have said binding, but "function slot". In the first
example, you are passing a symbol into FUNCALL, where it is then
resolved to a function by looking at that symbol's global function
value. In the second example, the resolution from symbol to function is
done outside of FUNCALL, which gets the resulting function object.
(Additionally, the resolution is lexical, being able to see LABELS and
FLET functions).

It's quite important to have both of these ways of representing a
function: to be able to transparently use a symbol where a function
object can be used.

When you use the symbol, you lose the ability to refer to lexical
functions, true enough.
But you gain something important: a level of indirection for referring
to a global function, which allows for dynamic redefinition.

If you take a global function as an object, that object will not change
if the global function is redefined. It will continue to refer to the
old function. To get the new object, you have to re-evaluate the
original #'SYMBOL expression. Sometimes that's a good thing, sometimes
not. If you hold the symbol instead, looking at its function slot will
always get you the current version
of that function.

So for instance, suppose you have a function FOO and you register it as
a callback somewhere. If you register it as #'FOO, then if you later
redefine foo, the old version of the function will continue to be
registered, unles you update the registration with the new value of
#'FOO. If you register it as 'FOO, the callbacks will just go to the
latest one.

Kaz Kylheku

unread,
Feb 12, 2006, 4:37:12 AM2/12/06
to
Duncan Harvey wrote:
> > Now I'm really wondering why we have #' in the first place...
>
> Because of that Lisp-2ness that you've heard about.

Even in a Lisp 1, I would somehow like to be able to use a symbol where
a function is expected: to be able to use either SYMBOL or 'SYMBOL
where a function is expected. The first would resolve the binding to a
function object, the second would pass the symbol whose top-level
binding would be used at the point of the call. This means that the
syntax ('SYMBOL ARG) would have to work. That would mean, "call the
function that is the top-level binding of the symbol". Then indirect
calls to functions would work in the face of redefinitions.

Barry Margolin

unread,
Feb 12, 2006, 5:10:51 AM2/12/06
to
In article <1139737032.5...@g44g2000cwa.googlegroups.com>,
"Kaz Kylheku" <kkyl...@gmail.com> wrote:

> Even in a Lisp 1, I would somehow like to be able to use a symbol where
> a function is expected: to be able to use either SYMBOL or 'SYMBOL
> where a function is expected. The first would resolve the binding to a
> function object, the second would pass the symbol whose top-level
> binding would be used at the point of the call. This means that the
> syntax ('SYMBOL ARG) would have to work. That would mean, "call the
> function that is the top-level binding of the symbol". Then indirect
> calls to functions would work in the face of redefinitions.

If the Lisp-1 has EVAL, you can do:

((eval 'symbol) arg)

as the equivalent to (funcall 'symbol arg).

Thomas A. Russ

unread,
Feb 13, 2006, 2:07:10 PM2/13/06
to
verec <ve...@mac.com> writes:

> On 2006-02-10 18:04:02 +0000, Alan Crowe <al...@cawtech.freeserve.co.uk> said:
>
> Thank you all for your explanations.
>
> so the reason this works:
>
> (defun weird-2 (f list)
> (reduce f list))
>
...
> is because weird-2 just doesn't care where f comes from,
> and because #' special cases (lambda...


>
> But #' doesn't special case anything else, and that's
> why:
>
> (defun weird-3 (f list)
> (reduce #'f list))
>

OK, this isn't about special casing, per se. It is rather about where
Lisp goes to lookup the values to use. Under normal evaluation rules,
arguments to functions (and REDUCE is a function), evaluate their
arguments. The evaluation of an argument that is denoted by a symbol is
just the value of that symbol. This will be either its lexical value or
its special value, depending on whether the symbol denotes a lexical or
special variable.

Quoting a symbol prevents this evaluation. If you had written

(reduce 'f list)

you would presumably not be surprised that this failed, since a symbol
can't be applied to arguments, only a function can.

Instead, the code #'f refers to the function denoted by the symbol F.
Again, this can either refer to a lexical or a global definition of the
symbol. As others have pointed out, if you use FLET to give F a
functional value, this works, since you invoke the functional value.
Similarly if you use DEFUN to give F a global definition, then a
functional value can also be found.

This is all about namespaces.

For fun compare:

(defun weird (f list)
(flet ((f (x y)
(+ x y)))
(values (reduce f list)
(reduce #'f list))))

(weird #'- '(1 2 3))
==> ??

Joerg Hoehle

unread,
Feb 24, 2006, 2:05:56 PM2/24/06
to nobody
Barry Margolin <bar...@alum.mit.edu> writes:
> The reason this isn't much of a problem is that ((lambda ...) ...)
> syntax is virtually never used any more. It was used decades ago,
> before LET was created, but now it has little practical use (I can't
> think of any reason to use it offhand).

I used it here in there. Always in (expansion of) macros. You
yourself point at the reason below.


> there are some slight differences in the effect of
> declarations at the head of the body

By using ((lambda ... ,@body) ...,@args...)
I can make it crystal clear that declarations have nothing to do with
the evaluation of args. It's not so obvious with LET

> [...] in modern code (LAMBDA ...) is never used without being preceded by


> sharpquote. So there seems to be a redundancy.

Ken M. Pitman advocated this redundancy months ago in cll. #'(lambda
hits the eye and is thus useful. I tend to agree with him.

Maybe there's another reason: I've corrected code from even advanced
programmers here and then. The mistake used to be as follows:

(defvar foo '("menu" (lambda (x)....)))

Some people thought they need EVAL for this (no!). Some
implementations coerced the lambda on the fly when passed to funcall
(or maybe an explicit (coerce thunk 'function) was in the code.
The error was revealed when we moved to another implementation.

I showed them that the solution is backquote:
(defvar foo `("menu" ,#'(lambda (x)....)))

Now one can argue that #' is still superfluous. I argue that in
nested lists, it makes it easy for me to know that indeed a closure
object is needed *and* shall be created in the visible lexical context.
[Sort of a variation on Pitman's argument]

No (COERCE thunk 'FUNCTION) which would cause some systems to compile
at run-time. No EVAL.

Regards,
Jorg Hohle
Telekom/T-Systems Technology Center

0 new messages