In reading Graham's _ANSI Common Lisp_, I encountered functions that return functions. There's an example in the book of a definition of complement:
(defun our-complement (f) #'(lambda (&rest args) (not (apply f args))))
I understand this definition; a function name is taken, and a function is returned. The returned function takes any number of optional arguments and returns the complement value of calling the passed function name on args.
I tried to twist Graham's function a bit:
(defun my-complement (f) (lambda (&rest args) (not (apply f args))))
This returns a lambda expression. Since I know:
((lambda (x) (+ x 1)) 1) => 2
I assumed:
((my-complement #'oddp) 2)
Would be a valid function call, but my compiler seems to disagree. Can someone please explain why this fails?
Thanks a lot, -- Jordan Katz <k...@underlevel.net> | Mind the gap
> In reading Graham's _ANSI Common Lisp_, I encountered functions that > return functions. There's an example in the book of a definition of > complement:
> I understand this definition; a function name is taken, and a > function is returned. The returned function takes any number of > optional arguments and returns the complement value of calling the > passed function name on args.
> This returns a lambda expression. Since I know: OK so far...
> ((lambda (x) (+ x 1)) 1) => 2
> I assumed:
> ((my-complement #'oddp) 2)
> Would be a valid function call, but my compiler seems to disagree. > Can someone please explain why this fails?
The ((lambda (x) ...) 'foo) syntax is special; a lambda expression is the only non-symbol form that's allowed in the function position in a call. This isn't Scheme. For what you want you'd do: (funcall (my-complement #'oddp) 2)
tmo...@sea-tmoore-l.dotcast.com (Tim Moore) writes: > On 10 Mar 2002 17:14:25 -0500, Jordan Katz <k...@underlevel.net> wrote: > >Hi,
> > In reading Graham's _ANSI Common Lisp_, I encountered functions that > > return functions. There's an example in the book of a definition of > > complement:
> > I understand this definition; a function name is taken, and a > > function is returned. The returned function takes any number of > > optional arguments and returns the complement value of calling the > > passed function name on args.
> > This returns a lambda expression. Since I know: > OK so far...
Is it? Perhaps you're eliding for the benefit of the OP, as I'm sure you know that it doesn't return a lambda expression at all, but is in fact completely equivalent to our-complement, as (lambda ...) is a macro that expands to (function (lambda ...)), just as #' is a read-macro that expands to function. Just in case this confuses the issue ("but why doesn't that expand indefinitely?") remember that FUNCTION is a special form, and therefore the normal rules of evaluation do not apply.
On 10 Mar 2002 17:14:25 -0500, Jordan Katz <k...@underlevel.net> wrote:
> This returns a lambda expression. Since I know:
> ((lambda (x) (+ x 1)) 1) => 2
> I assumed:
> ((my-complement #'oddp) 2)
> Would be a valid function call, but my compiler seems to disagree. > Can someone please explain why this fails?
Your compiler is a Common Lisp compiler, not a Scheme compiler. That's why it complains. ;-) I guess this is the most common error when you have a Scheme background.
Look for #' and funcall in the help files.
---- Fernando Rodríguez frr at wanadoo dot es -------
In article <7o4p8u8liqf998oj2ujgslkbq4gcanv...@4ax.com>, Fernando Rodríguez <f...@wanadoo.es> wrote:
>Your compiler is a Common Lisp compiler, not a Scheme compiler. That's why it >complains. ;-) I guess this is the most common error when you have a Scheme >background.
Based on the way he wrote his original post, I doubt he had any Scheme background. Schemers are usually more familiar than Common Lispers with functions that return functions, but it seemed like a new concept to him.
-- Barry Margolin, bar...@genuity.net Genuity, Woburn, MA *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups. Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
> In reading Graham's _ANSI Common Lisp_, I encountered functions that > return functions. There's an example in the book of a definition of > complement:
You know Scheme: the language whose main design goal is the shortness of the spec document.
> I assumed:
> ((my-complement #'oddp) 2)
> Would be a valid function call, but my compiler seems to disagree. > Can someone please explain why this fails?
Anonymous functions are called through FUNCALL in CL. Maybe inelegant, but that is the way things are.
(funcall (my-complement #'oddp) 2)
will do what you want.
Cheers
-- Marco Antoniotti ======================================================== NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488 719 Broadway 12th Floor fax +1 - 212 - 995 4122 New York, NY 10003, USA http://bioinformatics.cat.nyu.edu "Hello New York! We'll do what we can!" Bill Murray in `Ghostbusters'.
Marco Antoniotti <marc...@cs.nyu.edu> writes: > Anonymous functions are called through FUNCALL in CL. Maybe > inelegant, but that is the way things are.
> (funcall (my-complement #'oddp) 2)
> will do what you want.
Geez I hate it when we in our community knuckle under to the single-view-of-the-world-is-all-there-is mentality. It's not inelegant. It's simply differently defined.
In CL, the car of a form is a function name. (lambda (x) x) is the name of an anonymous function. Think of functions as being named by either common nouns [lambda expressions] or proper nouns [lambda expressions you've given a name to]. Likewise, the FUNCTION special form takes a function name, and #'(lambda (x) (+ x 3)) is the "common noun" form of something you'd call ADD3 if you called it often enough to care about giving it a name.
In Scheme, the care of a form is an expression in the variable namespace. This makes life simpler in some ways and more complex in others. It means you cannot simultaneously accomodate a variable named list and a function named list, even the simultaneous presence of two meanings of the same word is both semantically well-formed and something that the human brain is known to have experience with, to process correctly and efficiently, and is known through tons of experiential data about the formation of natural languages to actively prefer. (I know of no modern, successful, human language that does not overload word meanings based on context. Surely if having only one meaning per word, independent of context, were important, there would be some evidence of a similarly anal natural language that has survived and thrived.)
So choose CL or choose Scheme according to your personal taste, but please don't assert that either is canonically elegant nor canonically inelegant. There is plenty of data on both sides.
Barry Margolin <bar...@genuity.net> writes: > In article <7o4p8u8liqf998oj2ujgslkbq4gcanv...@4ax.com>, > Fernando Rodríguez <f...@wanadoo.es> wrote: > >Your compiler is a Common Lisp compiler, not a Scheme > compiler. That's why it > >complains. ;-) I guess this is the most common error when you have a Scheme > >background.
> Based on the way he wrote his original post, I doubt he had any Scheme > background. Schemers are usually more familiar than Common Lispers with > functions that return functions, but it seemed like a new concept to him.
It's interesting to see what people will assume about your background based on your post. Actually, I have limited background in Scheme, but in my study of it I never got to learn functions that return functions. The concept is new to me, but I think I understand pretty (maybe it didn't come across my post, or maybe I really don't understand it but the idea doesn't confuse me now) well but am having trouble with certain lambda expressions and notations (like #' and what (lambda ...) expanded to when returned in a function, etc.) in CL. -- Jordan Katz <k...@underlevel.net> | Mind the gap
Marco Antoniotti <marc...@cs.nyu.edu> writes: > > This returns a lambda expression. Since I know:
> > ((lambda (x) (+ x 1)) 1) => 2
> You know Scheme: the language whose main design goal is the shortness > of the spec document.
Everyone who responded seems to think I'm thinking in Scheme, and, as far as I can tell it seems to be rooted in what I wrote above, but I don't see why. CMUCL groks ((lambda (x) (+ x 1)) 1) for me just like a Scheme would, it doesn't only accept (funcall (lambda (x) (+ x 1)) 1). Is that a liberty taken by CMUCL authors to make it more friendly for Schemers, or is that in accordance with CL specs?
Thanks a lot, -- Jordan Katz <k...@underlevel.net> | Mind the gap
Jordan Katz <k...@underlevel.net> writes: > Everyone who responded seems to think I'm thinking in Scheme, and, > as far as I can tell it seems to be rooted in what I wrote above, > but I don't see why.
Scheme doesn't have multiple syntactic cases for functions and values.
> CMUCL groks ((lambda (x) (+ x 1)) 1) for me just like a Scheme > would, it doesn't only accept (funcall (lambda (x) (+ x 1)) 1). Is > that a liberty taken by CMUCL authors to make it more friendly for > Schemers, or is that in accordance with CL specs?
This is a special case that was retained for hysterical raisins. LET is syntactic sugar for that use of LAMBDA.
-- -> -/ - Rahul Jain - \- <- -> -\ http://linux.rice.edu/~rahul -=- mailto:rj...@techie.com /- <- -> -/ "Structure is nothing if it is all you got. Skeletons spook \- <- -> -\ 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.
> Everyone who responded seems to think I'm thinking in Scheme, and, as > far as I can tell it seems to be rooted in what I wrote above, but I > don't see why. CMUCL groks ((lambda (x) (+ x 1)) 1) for me just like > a Scheme would, it doesn't only accept (funcall (lambda (x) (+ x 1)) > 1). Is that a liberty taken by CMUCL authors to make it more friendly > for Schemers, or is that in accordance with CL specs?
It's in the CL spec, but they're two different things, and different again from what Scheme does.
When you write (foo x y z) to call a function in Lisp, FOO is a symbol naming the function. I.e., it's not a function object, just its name. (lambda ...) is just another way of naming a function, so you get to write ((lambda ...) x y z) to call that function.
When you write (foo x y z) to call a function in Scheme, FOO is a function object -- you can put a symbol there, of course, or even an arbitrary expression, since the position is evaluated, but ultimately what you want is a function. (lambda ...) doesn't _name_ a function; it's an expression that you can evaluate to get a function.
Note that the first position is *not* evaluated in Lisp -- (lambda ...) is just the name of a function, not something you can evaluate; in CLtL Common Lisp (the original Common Lisp, prior to the ANSI standardization), LAMBDA was not a function, a macro or a special form; it had no definition at all, and (lambda (x) (1+ x)) would just signal an "undefined function" error.
In ANSI Common Lisp, LAMBDA is a macro whose expansion is the same LAMBDA form wrapped in a FUNCTION form; e.g.,
(lambda (x) (+ x 1)) => (function (lambda (x) (+ x 1)))
which is the same as #'(lambda (x) (+ x 1)), of course. FUNCTION is a special operator, similar to QUOTE, so the lambda form inside it is *not* calling for another invocation of the macro.
In your first case, ((lambda (x) (+ x 1)) 1) in Lisp, you're just using the fact that a lambda form names a function. The position is not evaluated, and the macro doesn't come into play.
In your second case, (funcall (lambda (x) (+ x 1)) 1), you're using the LAMBDA macro; its expansion is using the FUNCTION special form to get an actual function object named by the lambda form.
In your third case, ((lambda (x) (+ x 1)) 1) in Scheme, you're evaluating the lambda form itself to produce a function. [i.e., lambda is a special form in Scheme; it's not in CL]
-- If that makes any sense to you, you have a big problem. -- C. Durance, Computer Science 234 (setq reply-to (concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz>"))
* Jordan Katz | Everyone who responded seems to think I'm thinking in Scheme, and, as far | as I can tell it seems to be rooted in what I wrote above, but I don't | see why.
You have asked a very typical Scheme question, and people are somewhat sensitive to this sort of question because Scheme victims keep asking it over and over. It seems that this one-namespace thing acts like a virus that takes over the host system to produce more of its own kind.
The problem is one of faulty reasoning and muddy thinking, and this is also typical of Scheme victims.
| CMUCL groks ((lambda (x) (+ x 1)) 1) for me just like a Scheme would, it | doesn't only accept (funcall (lambda (x) (+ x 1)) 1). Is that a liberty | taken by CMUCL authors to make it more friendly for Schemers, or is that | in accordance with CL specs?
This has already been asnwered with a reference to the Hyperspec. Please pay attention, or you just annoy people. Perhaps you did not understand the answer you got. Let ma assume you did not, and try a different angle:
(foo ...) calls the function named foo. ((lambda ..) ...) calls the "anonymous" function that _is_ (lambda ...). Kent calls the function itself its name, but I find that confusing -- your name is _not_ your identity, it is a label on your identity. An anonymous function has its own identity as a function, but no name. Specifically, it _is_ a function. Now, you can call the function directly, or you can call it by its name, which the compiler will resolve for you to either be the lexically defined functionn or the globally defined function that is the value of the symbol with the name you gave. The first position in a form either _is_ a function or _names_ a function. (In addition to all the other types of operators, of course.)
Now, how is this different from Scheme and from your faulty reasoning? Suppose you think that (lambda ...) _evaluates_ to a function when it is in the first position of a form. This is clearly not how Common Lisp does it, because it expressly does _not_ evaluate the first position, but it _is_ how Scheme does things. If you did not pay much attention to the differences in evaluation rules between Scheme and Common Lisp -- and it seems you have not really studied the evaluation rules of either language just sort of adopted them by osmosis (example) -- you would perhaps think that the operator is somehow evaluated in a different way in Common Lisp. But Common Lisp does expressly _not_ evaluate the operator. The operator either is a function or names a function. So if you place something there that would need to be _evaluated_ to produce a function, it is just not how Common Lisp does things. In summary, ((lambda ...) ...) works because it _is_ a function, not because it _evaluates_ to a function.
In (funcall (lambda ...) ...), (lambda ...) evaluates to a function, and the _function_ funcall is called with a regular evaluated value. I quote from the standard and its entry on funcall:
The difference between funcall and an ordinary function call is that in the former case the function is obtained by ordinary evaluation of a form, and in the latter case it is obtained by the special interpretation of the function position that normally occurs.
Note the special interpretation.
/// -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
Jordan Katz <k...@underlevel.net> writes: > Marco Antoniotti <marc...@cs.nyu.edu> writes:
> > > This returns a lambda expression. Since I know:
> > > ((lambda (x) (+ x 1)) 1) => 2
> > You know Scheme: the language whose main design goal is the shortness > > of the spec document.
> Everyone who responded seems to think I'm thinking in Scheme, and, as > far as I can tell it seems to be rooted in what I wrote above, but I > don't see why. CMUCL groks ((lambda (x) (+ x 1)) 1) for me just like > a Scheme would, it doesn't only accept (funcall (lambda (x) (+ x 1)) > 1). Is that a liberty taken by CMUCL authors to make it more friendly > for Schemers, or is that in accordance with CL specs?
ignore scheme for a moment.
let's look at LAMBDA in common-lisp
i did this in clisp
[1]> ((lambda (x) (+ x 3)) 4) 7 [2]> (#'(lambda (x) (+ x 3)) 4)
*** - EVAL: #'(LAMBDA (X) (+ X 3)) is not a function name
[3]> (funcall #'(lambda (x) (+ x 3)) 4) 7
the function object #'(lambda (x) (+ x 3)) does not _name_ a function, it _is_ a function. apparently, by contrast, (lambda (x) (+ x 3)) is, in itself, a function _name_.
i gather this not so much from myoptically parsing the words in the error message but condensing other people's posts around me. the error message just happened to be very accurate and straightforward for this purpose.
all this is somewhat obscured by the macro overloading that lambda has. plain (lambda (x) (+ x 3)) will magically expand to #'(lambda (x) (+ x 3)) in the appropriate place (like as an argument to mapcar). and thus you have
[4]> (funcall (lambda (x) (+ x 3)) 4) 7
this is just the LAMBDA side. but i hope it helps.
> Thanks a lot, > -- > Jordan Katz <k...@underlevel.net> | Mind the gap
-- J o h a n K u l l s t a m [kulls...@ne.mediaone.net] sysengr
On 19 Mar 2002 09:19:22 -0500, Johan Kullstam wrote:
> i did this in clisp > [1]> ((lambda (x) (+ x 3)) 4) > 7 > [2]> (#'(lambda (x) (+ x 3)) 4) > *** - EVAL: #'(LAMBDA (X) (+ X 3)) is not a function name > [3]> (funcall #'(lambda (x) (+ x 3)) 4) > 7 > the function object #'(lambda (x) (+ x 3)) does not _name_ a function, > it _is_ a function. apparently, by contrast, (lambda (x) (+ x 3)) is, > in itself, a function _name_.
#'(lambda (x) (+ x 3)) here is not a function, it's a list. If evaluated, the result would be a function, but the operator position is not evaluated, so it's just a list of (function (lambda ...)). If it /was/ evaluated, ((lambda ...) 4) would be the same thing.
If you want to put a function object there, you'll have to type (#.#'(lambda ...) 4) [or just (#.(lambda ...) 4)]
-- " ... I told my doctor I got all the exercise I needed being a pallbearer for all my friends who run and do exercises!" -- Winston Churchill (setq reply-to (concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz>"))