Google 网上论坛不再支持新的 Usenet 帖子或订阅项。历史内容仍可供查看。

(lambda ()) vs #'(lambda ())

已查看 13 次
跳至第一个未读帖子

Peter Seibel

未读,
2002年1月6日 19:21:372002/1/6
收件人
So I'm confused; is there a difference between (lambda ()) and
#'(lambda ())? (Other than the obvious syntactic one ;-)). I was
reading Paradigms in AI Programming and he says that a lambda
expression is just a non-atomic name for an anonymous function. Thus
you can write ((lambda (x) (* 2 x)) 4) and it will evaluate to
8. Therefore, you should write (mapcar #'(lambda ())) rather than
(mapcar (lambda())). Yet according to CLISP (FWIW; obviously an
implementation isn't the spec.):

[1]> (type-of (lambda ()))
FUNCTION
[2]> (type-of #'(lambda ()))
FUNCTION
[3]> (functionp (lambda ()))
T
[4]> (functionp #'(lambda ()))
T
[5]> (funcall (lambda () 1))
1
[6]> (funcall #'(lambda () 1))
1

-Peter

Kaz Kylheku

未读,
2002年1月6日 19:40:172002/1/6
收件人
In article <m2wuyvf...@javamonkey.com>, Peter Seibel wrote:
>So I'm confused; is there a difference between (lambda ()) and
>#'(lambda ())? (Other than the obvious syntactic one ;-)).

The first is a standard macro which expands to the second. The handy macro
allows you to dispense with the #' notation, if you want.

>I was
>reading Paradigms in AI Programming and he says that a lambda
>expression is just a non-atomic name for an anonymous function.

Strictly speaking, this isn't right; a lambda expression is not considered
a function name. (See ``function name'' in the Common Lisp HyperSpec
glossary).

Thus
>you can write ((lambda (x) (* 2 x)) 4) and it will evaluate to
>8.

In this context, the lambda expression appears in the first position
of a list expression that is evaluated. This position is subject to
different evaluation rules. The lambda macro does not come into effect;
the lambda expression is simply recognized as denoting a function.
If the macro came into effect, that wouldn't work, because

(#'(lambda (x) (* 2 x)) 4)

is not valid.

In other contexts where it is evaluated, you obtain a funcallable object,
a closure, thanks to the lambda macro which brings in the function operator.
That function operator's job is to create the funcallable object from
a function name or from a lambda expression.

>Therefore, you should write (mapcar #'(lambda ())) rather than
>(mapcar (lambda())).

Many programmers write #' anyway.

Michael J. Ferrador

未读,
2002年1月7日 00:10:162002/1/7
收件人
Has anyone ever thought it would be nice to recurse an anonymous lambda?

Or are recursive functions important enough to have (be bound to) a name.


I was thinking about a symbol recurse, always bound to the current lambda

But then it is not exactly anonymous any more, is it?


Maybe I was cutting and pasting functions, renaming,
BUT forgetting to rename the inner recursion(s).

Is this an editor / x-ref / emacs job?


> In article <m2wuyvf...@javamonkey.com>, Peter Seibel wrote:
>
> >I was
> >reading Paradigms in AI Programming and he says that a lambda
> >expression is just a non-atomic name for an anonymous function.

I'm still chewing on the non-atomic part, maybe It's too late at night

> Strictly speaking, this isn't right; a lambda expression is not considered
> a function name. (See ``function name'' in the Common Lisp HyperSpec
> glossary).

---

And I'd like to thank ftp servers everywhere
for forcing me to learn to spell anonymous...

Christopher Stacy

未读,
2002年1月7日 03:17:202002/1/7
收件人
>>>>> On Mon, 07 Jan 2002 05:10:16 GMT, Michael J Ferrador ("Michael") writes:
Michael> Has anyone ever thought it would be nice to recurse an anonymous lambda?
Michael> Or are recursive functions important enough to have (be bound to) a name.

That's what LABELS is for.

Or you could pass the function to itself:

(defun factorializationism (n)
(let ((fact #'(lambda (f x)
(if (= x 1) 1 (* x (funcall f f (- x 1)))))))
(funcall fact fact n)))

Dr. Edmund Weitz

未读,
2002年1月7日 06:08:002002/1/7
收件人
Peter Seibel <pe...@localhost.i-did-not-set--mail-host-address--so-shoot-me> writes:

See the CLHS
<http://www.xanalys.com/software_tools/reference/HyperSpec/index.html>
entry for the macro LAMBDA. Here's an excerpt:

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

Edi.

Johan Kullstam

未读,
2002年1月7日 09:58:032002/1/7
收件人
Peter Seibel <pe...@localhost.i-did-not-set--mail-host-address--so-shoot-me> writes:

> So I'm confused; is there a difference between (lambda ()) and
> #'(lambda ())? (Other than the obvious syntactic one ;-)). I was
> reading Paradigms in AI Programming and he says that a lambda
> expression is just a non-atomic name for an anonymous function. Thus
> you can write ((lambda (x) (* 2 x)) 4) and it will evaluate to
> 8. Therefore, you should write (mapcar #'(lambda ())) rather than
> (mapcar (lambda())). Yet according to CLISP (FWIW; obviously an
> implementation isn't the spec.):

the short answer is that you can use or not use #' with lambda at your
option. it used to be true in previous versions of common-lisp.
however, since the ansi spec it has been fudged by a little creative
macrology. this doesn't break old code which uses #', but allows you
to not use #' with lambda. use of #'(lambda () ..) is now more a
matter of taste and ineritia.

> [1]> (type-of (lambda ()))
> FUNCTION
> [2]> (type-of #'(lambda ()))
> FUNCTION
> [3]> (functionp (lambda ()))
> T
> [4]> (functionp #'(lambda ()))
> T
> [5]> (funcall (lambda () 1))
> 1
> [6]> (funcall #'(lambda () 1))
> 1
>
> -Peter
>
>
>

--
J o h a n K u l l s t a m
[kull...@ne.mediaone.net]
sysengr

Erik Naggum

未读,
2002年1月7日 16:14:382002/1/7
收件人
* "Michael J. Ferrador" <n2...@orn.com>

| Has anyone ever thought it would be nice to recurse an anonymous lambda?

(defun jestcall (function &rest arg)
(apply function function args))

Where you would funcall a function that would funcall itself by name to
make a recursive call, you jestcall a function that jestcalls its first
argument to make a recursive call.

///
--

Kaz Kylheku

未读,
2002年1月7日 17:09:432002/1/7
收件人
In article <Y4a_7.1210$jk5.1...@news02.optonline.net>, Michael

J. Ferrador wrote:
>Has anyone ever thought it would be nice to recurse an anonymous lambda?
>
>Or are recursive functions important enough to have (be bound to) a name.
>
>
>I was thinking about a symbol recurse, always bound to the current lambda
>
>But then it is not exactly anonymous any more, is it?
>
>
>Maybe I was cutting and pasting functions, renaming,
>BUT forgetting to rename the inner recursion(s).

Do you know about the labels form for defining local functions that
can be recursive? Maybe that's all you want.

Also note that a function can call itself recursively using funcall,
apply or similar functions, rather than by name. It just needs to have
a function object representing itself, passed in as an argument.

E.g.

(setf factorial #'(lambda (self arg)
(if (<= arg 0) 1 (* arg (funcall self self (1- arg))))))

(funcall factorial factorial 10)

Oh, and about your idea regarding the symbol recurse, here is a stupid
macro which lets you write closures in whose contexts you can use
the symbol recurse to refer to the function. It illustrates a
use of labels, if nothing else.

(defmacro recursive-closure ((&rest lambda-list) &body forms)
(let ((args-bounce (gensym)))
`#'(lambda (&rest ,args-bounce)
(labels ((recurse (,@lambda-list) ,@forms))
(apply #'recurse ,args-bounce)))))

James McDonald

未读,
2002年1月7日 22:39:102002/1/7
收件人
Michael J. Ferrador wrote:

> Has anyone ever thought it would be nice to recurse an anonymous lambda?

You might want to research the Y combinator. Dick Gabriel wrote a nice
little paper called "The Why of Y" (or something close).

Sorry I'm to pressed for time to say more now, except to warn you that
the concepts related to fixpoint combinators are subtle (especially the
implementations of them!) and it may take a bit of patient study before
it all makes sense, but the effort is well worth it.

James McDonald

Ikram

未读,
2002年1月8日 10:08:402002/1/8
收件人
>>>>> Michael J Ferrador <n2...@orn.com> writes:
> Has anyone ever thought it would be nice to recurse an anonymous
> lambda? Or are recursive functions important enough to have (be
> bound to) a name.

do self-referential lambdas count? :-)

(#1=(LAMBDA (X)
"Factorial of X."
(IF (= X 1)
1
(* X (#1# (1- X)))))
10)

I entered this into the repl expecting the worst to happen, and was
pleasantly surprised to see it evaluated in the intended way by ACL.

however CMUCL went into a consing frenzy and produced puzzling GC
messages like
[GC completed with 37,874,208 bytes retained and -10,088 bytes freed.]
(-10,088 bytes freed?) until the Lisp process had to be killed.

--
I. M. Ikram ik...@cs.pdn.ac.lk

Kent M Pitman

未读,
2002年1月8日 07:35:562002/1/8
收件人
Ikram <ik...@cs.pdn.ac.lk> writes:

> >>>>> Michael J Ferrador <n2...@orn.com> writes:
> > Has anyone ever thought it would be nice to recurse an anonymous
> > lambda? Or are recursive functions important enough to have (be
> > bound to) a name.
>
> do self-referential lambdas count? :-)
>
> (#1=(LAMBDA (X)
> "Factorial of X."
> (IF (= X 1)
> 1
> (* X (#1# (1- X)))))
> 10)
>
> I entered this into the repl expecting the worst to happen, and was
> pleasantly surprised to see it evaluated in the intended way by ACL.

Yes, this might sometimes accidentally work interpreted. Since the very
definition of interpretation is incremental (in this case, read: lazy)
application of semantics. If you did total application of semantics,
you'd pretty much be obliged to lose, for reasons outlined below.
So DON'T rely on it.



> however CMUCL went into a consing frenzy and produced puzzling GC
> messages like
> [GC completed with 37,874,208 bytes retained and -10,088 bytes freed.]
> (-10,088 bytes freed?) until the Lisp process had to be killed.

This is more likely. LispWorks 4.2 blows up this way, too.
Not surprisingly. I see no implementation bug here; the bug is the user's.
You've made a circular program. Some implementations may catch this,
others may not.

Before you go thinking that EQ-ness is something the compiler should be
catching in order to avoid doing gratuitous compilation, consider that
#1# had no free variables in the above situation. Had it, though, as in
(LET ((X 10))
(#1=(LAMBDA ()

(IF (= X 1) 1

(* X (LET ((X (1- X)))
(#1#)))))))
in which each invocation refers to a different lexically apparent X.
Just because two expressions are EQ doesn't mean they should be compiled
the same. ;) A simpler example to prove that is:
(LET ((X 1) (Y 2))
(+ X (SYMBOL-MACROLET ((X Y)) X)))
=> 3
Each X in the sum means utterly different things.

So you can't rely even on EQ (nor EQ hash tables) for circularity checking.
It's not obvious what criterion you CAN use. The compiler needs to recurse
into each one of these things to compile it, EVEN IF it is EQ to something
seen before, and therefore (since there are an infinite number) is going to
lose without some VERY sophisticated graph matching (which would slow down
all other compilation, all REASONABLE compilation, because it should never
have to be done in the first place) and logical inferencing about certain
such matching graphs.

We all go through this silliness at some point--discovering the wonders of
the circular statement. Enjoy it. Then forget it.

Joe Schaefer

未读,
2002年1月8日 08:02:192002/1/8
收件人
Ikram <ik...@cs.pdn.ac.lk> writes:

> do self-referential lambdas count? :-)
>
> (#1=(LAMBDA (X)
> "Factorial of X."
> (IF (= X 1)
> 1
> (* X (#1# (1- X)))))

^^^^^

X-1 ?

--
Joe Schaefer

Joe Schaefer

未读,
2002年1月8日 08:16:192002/1/8
收件人
Joe Schaefer <joe+u...@sunstarsys.com> writes:

Eh, sorry- insufficient caffeine level.
My mistake.

--
Joe Schaefer

0 个新帖子