From: Nils Goesche
Subject: basic question on lambda
Date: 
Message-ID: <lkitqibjit.fsf@pc022.xcs.local>
Hi!

I seem to lack some basic understanding about the evaluation/parsing
of lambda-expressions or macros.  Out of curiosity, I defined

(defmacro curry (f &rest args)
  `(lambda (&rest x) (apply ,f ,@args x)))

Now, the following happens (on CMUCL):

* (pprint (macroexpand-1 '(curry #'+ 2)))

(LAMBDA (&REST X) (APPLY #'+ 2 X))
* (mapcar #'(LAMBDA (&REST X) (APPLY #'+ 2 X)) '(0 1 2 3))

(2 3 4 5)
* (mapcar #'(curry #'+ 2) '(0 1 2 3))

In: FUNCTION (CURRY #'+ 2)
  #'(CURRY #'+ 2)
Error: Illegal function name: (CURRY #'+ 2)
[snip]

On the other hand, this works:

* (mapcar (curry #'+ 2) '(0 1 2 3))

(2 3 4 5)

But also this works:

* (mapcar (lambda (&rest x) (apply #'+ 2 X)) '(0 1 2 3))

(2 3 4 5)

What is this all about?  Why do all Lisp books put #' in front of a
lambda expression?  And why does it work with #' and a lambda
expression but not with #' and a ``curry'' expression?  BTW, if it has
to do with `read macros', note that I don't know what a read macro
actually is :-(
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

From: Rainer Joswig
Subject: Re: basic question on lambda
Date: 
Message-ID: <joswig-306D36.16235024102000@news.is-europe.net>
In article <··············@pc022.xcs.local>, Nils Goesche 
<············@anylinx.de> wrote:

> * (mapcar #'(curry #'+ 2) '(0 1 2 3))
> 
> In: FUNCTION (CURRY #'+ 2)
>   #'(CURRY #'+ 2)
> Error: Illegal function name: (CURRY #'+ 2)
> [snip]
> 
> On the other hand, this works:
> 
> * (mapcar (curry #'+ 2) '(0 1 2 3))

This is how it is supposed to be.

> (2 3 4 5)
> 
> But also this works:
> 
> * (mapcar (lambda (&rest x) (apply #'+ 2 X)) '(0 1 2 3))

In ANSI CL, LAMBDA is a macro. So 

(lambda (foo) foo)

is short for

(function (lambda (foo) foo))

which usually is written as

#'(lambda (foo) foo)

> What is this all about?  Why do all Lisp books put #' in front of a
> lambda expression?  And why does it work with #' and a lambda
> expression but not with #' and a ``curry'' expression?

Common Lisp has namespaces for functions and for other values.
This is different from most other programming languages.
So you can write:

(defparameter my-house (make-house))

and

(defun my-house ()
   (make-house))

If you evaluate MY-HOUSE, the evaluator returns
the value - in this case set by DEFPARAMETER.
If you want to get the function, you need
to do:  (FUNCTION MY-HOUSE) . Or shorter
#'MY-HOUSE .
If you want to pass functional values as parameters, you have
to get the functions first - using FUNCTION (or something similar).

The LAMBDA macro is another shorthand notation.

>  BTW, if it has
> to do with `read macros', note that I don't know what a read macro
> actually is :-(

So you might want to continue reading some introductory
Lisp books. :-)

READ reads Lisp data from a stream. If it sees a # (sharpsign)
the next character determines a function that does the
parsing. So # is being used to implement some special
surface syntax like:

#(1 2 3)  -> a vector
#*10101   -> a bit vector
#c(3 3)   -> a complex number
#'foo     -> (function foo)
#\space   -> the space character

etc.

Actually this is a general mechanism that does not
only work for the # character. Read something
about the Lisp "reader", to get some understanding of it.

-- 
Rainer Joswig, Hamburg, Germany
Email: ·············@corporate-world.lisp.de
Web: http://corporate-world.lisp.de/
From: Nils Goesche
Subject: Re: basic question on lambda
Date: 
Message-ID: <lkg0lmb2qo.fsf@pc022.xcs.local>
Rainer Joswig <······@corporate-world.lisp.de> writes:

Thanks for the explanation!  Still some questions, though :-)

> In article <··············@pc022.xcs.local>, Nils Goesche 
> <············@anylinx.de> wrote:
> 
> > * (mapcar #'(curry #'+ 2) '(0 1 2 3))
> > 
> > In: FUNCTION (CURRY #'+ 2)
> >   #'(CURRY #'+ 2)
> > Error: Illegal function name: (CURRY #'+ 2)
> > [snip]
> > 
> > On the other hand, this works:
> > 
> > * (mapcar (curry #'+ 2) '(0 1 2 3))
> 
> This is how it is supposed to be.
> 
> > (2 3 4 5)
> > 
> > But also this works:
> > 
> > * (mapcar (lambda (&rest x) (apply #'+ 2 X)) '(0 1 2 3))
> 
> In ANSI CL, LAMBDA is a macro. So 
> 
> (lambda (foo) foo)
> 
> is short for
> 
> (function (lambda (foo) foo))

Ah, hehe.  In CMUCL I get

* (macroexpand-1 '(lambda (foo) foo))

#'(LAMBDA (FOO) FOO)

Funny.

> which usually is written as
> 
> #'(lambda (foo) foo)
> 
> > What is this all about?  Why do all Lisp books put #' in front of a
> > lambda expression?  And why does it work with #' and a lambda
> > expression but not with #' and a ``curry'' expression?
> 
> Common Lisp has namespaces for functions and for other values.

In fact, I was aware of that, but I knew only SYMBOL-FUNCTION, not
FUNCTION.

[snip]

> >  BTW, if it has
> > to do with `read macros', note that I don't know what a read macro
> > actually is :-(
> 
> So you might want to continue reading some introductory
> Lisp books. :-)

Yeah.  I skipped the boring and unimportant part about read macros :-)

> READ reads Lisp data from a stream. If it sees a # (sharpsign)
> the next character determines a function that does the
> parsing. So # is being used to implement some special
> surface syntax like:
> 
> #(1 2 3)  -> a vector
> #*10101   -> a bit vector
> #c(3 3)   -> a complex number
> #'foo     -> (function foo)
> #\space   -> the space character
> 
> etc.

Hm.  So the reader reads #'(curry #'+ 2) and does _not_ macroexpand
that thing but immediately makes (function (curry #'+ 2)) out of that,
which is a special form that can turn something like (function blark)
into (symbol-function 'blark) and somehow by some magic understands
(function (lambda (x) x)), but it still won't macroexpand and
understand my (curry #'+ 2) expression, right?

> Actually this is a general mechanism that does not
> only work for the # character. Read something
> about the Lisp "reader", to get some understanding of it.

I will now :-)  Thanks again.
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
From: Pierre R. Mai
Subject: Re: basic question on lambda
Date: 
Message-ID: <87wvexzt4c.fsf@orion.bln.pmsf.de>
Nils Goesche <············@anylinx.de> writes:

> Hm.  So the reader reads #'(curry #'+ 2) and does _not_ macroexpand
> that thing but immediately makes (function (curry #'+ 2)) out of that,
> which is a special form that can turn something like (function blark)
> into (symbol-function 'blark) and somehow by some magic understands

It doesn't in general turn 

(function blark) 

into

(symbol-function 'blark)

just like blark doesn't mean the same as (symbol-value 'blark)

For example the following will fail:

(flet ((blark (x) x)) (symbol-function 'blark))

> (function (lambda (x) x)), but it still won't macroexpand and
> understand my (curry #'+ 2) expression, right?

Since function doesn't evaluate its argument, it doesn't macroexpand
it either (macroexpansion usually happens only on things which are
evaluated at some time).

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: ······@corporate-world.lisp.de
Subject: Re: basic question on lambda
Date: 
Message-ID: <8t5tdp$jto$1@nnrp1.deja.com>
In article <··············@pc022.xcs.local>,
  Nils Goesche <············@anylinx.de> wrote:

> > (function (lambda (foo) foo))
>
> Ah, hehe.  In CMUCL I get
>
> * (macroexpand-1 '(lambda (foo) foo))
>
> #'(LAMBDA (FOO) FOO)

Then enter: '(FUNCTION (LAMBDA (FOO) FOO))

You see, it is the same.

> > Common Lisp has namespaces for functions and for other values.
>
> In fact, I was aware of that, but I knew only SYMBOL-FUNCTION, not
> FUNCTION.

SYMBOL-FUNCTION gets the global (!!!) function value of a symbol.

> Hm.  So the reader reads #'(curry #'+ 2) and does _not_ macroexpand

The reader does not macroexpand. Macroexpansion is done by
MACROEXPAND. Reading is done by READ.

> that thing but immediately makes (function (curry #'+ 2)) out of that,

Yes - and this form is not making sense.

> which is a special form that can turn something like (function blark)
> into (symbol-function 'blark)

The special form does not do that. FUNCTION is something
like a built-in functionality. It can access local function
bindings, for example - which SYMBOL-FUNCTION can't.

> and somehow by some magic understands
> (function (lambda (x) x)), but it still won't macroexpand and
> understand my (curry #'+ 2) expression, right?

You need to look at the definition of FUNCTION.


Sent via Deja.com http://www.deja.com/
Before you buy.
From: Erik Naggum
Subject: Re: basic question on lambda
Date: 
Message-ID: <3181390601712381@naggum.net>
* Nils Goesche <············@anylinx.de>
| What is this all about?  Why do all Lisp books put #' in front of a
| lambda expression?  And why does it work with #' and a lambda
| expression but not with #' and a ``curry'' expression?

  #'x is actually short for (function x), which quotes x in a
  functional context, like 'x is short for (quote x), which quotes x
  in data/variable context.  Look up the special operator function and
  quote in your friendly standard reference material for the whole
  story.

  Specifically, (function (lambda ...)) causes interpretation of the
  (lambda ...) as a function (which means it may be funcalled, and
  will be compiled), which (quote (lambda ...)) does not.

  Why would you want to quote (curry ...) in a functional context?

| BTW, if it has to do with `read macros', note that I don't know what
| a read macro actually is :-(

  It has nothing to do with reader macros.  A reader macro is a
  function called by the reader to return a Lisp object from parsing
  or otherwise processing the input stream.  There's a reader macro
  for the character ( which causes the elements up to the matching )
  to be returned as a list, for instance.  The reader macro for '
  returns a list with quote as the first element and the next element
  taken directly from the input stream.  #' does the same, only with
  function instead of quote.  Lack of understanding of reader macros
  should not impact your appreciation of the full form they return.
  If you are not comfortable with reader macros, write things out in
  full, instead, thus encouraging your appreciation of the shorthand
  when you understand exactly what it does.  In other words: Write
  (function x) where your textbooks write #'x.

  Note that you don't need to write (function (lambda ...)) because
  (lambda ...) is a macro that expands to (function (lambda ...)).  I
  think it helps understanding Common Lisp's evaluation to think of
  lambda as returning an anonymous function, and to disregard the
  sometimes confusing #' or function special form.  Consequently, I
  never quote lambda forms and consider it redundant to do so.

#:Erik
-- 
  I agree with everything you say, but I would
  attack to death your right to say it.
				-- Tom Stoppard
From: Lyman Taylor
Subject: Re: basic question on lambda
Date: 
Message-ID: <39F5CA34.CE8BBC1@mindspring.com.no.spam>
Erik Naggum wrote:
> 
> * Nils Goesche <············@anylinx.de>
> | What is this all about?  Why do all Lisp books put #' in front of a
> | lambda expression?  
...
>   Note that you don't need to write (function (lambda ...)) because
>   (lambda ...) is a macro that expands to (function (lambda ...)).

  Didn't that change come with ANSI Common Lisp?  CLtL2 required
  the #'(lambda... ) if I recall correctly.  I'm sure I'll get 
  corrected if I'm wrong. :-) 

  I know folks should write ANSI Common Lisp now. However, textbooks
  often have to stradle time. Or were written in a perious "age". 
  Furthermore, I suspect most modern lisp implementations will take
either.  
  Perhaps there is some hackery that the #' reader macro does when it 
  encounters "(lambda". 

  As for the curry macro example:

  >> * (mapcar #'(LAMBDA (&REST X) (APPLY #'+ 2 X)) '(0 1 2 3))
  >>   (2 3 4 5)

  It is highly likely that following works also. [ I don't have CMULISP,
  but from experience with MCL, Allegro, and Lispworks. ]

     * (mapcar  (lambda (&rest x) (apply #'+ 2 X)) '(0 1 2 3 )) 
       (2 3 4 5) 

  which is why   (mapcar (curry .. ) ... )  works. 

  In general  #' should only be utilized on symbols. The execption is 
  (lambda .... ). Which is treated as in a special way which is backward
  compatible with the old versions.  In fact, the following works also
  ( which I personally think is a bad idea).

  (mapcar (list 'lambda '(&rest x) '(apply (function +) 2 x)) '(0 1 2 3 ))
   (2 3 4 5)

  A list that begins with the symbol LAMBDA has magical connotations in   
  certain contexts. 

Lyman                       "The Borg -- Party poopers of the Galaxy" 
                                  EMH Star Trek Voyager.
From: Tim Bradshaw
Subject: Re: basic question on lambda
Date: 
Message-ID: <nkjg0lm2k95.fsf@tfeb.org>
Lyman Taylor <············@mindspring.com.no.spam> writes:

> 
>   Didn't that change come with ANSI Common Lisp?  CLtL2 required
>   the #'(lambda... ) if I recall correctly.  I'm sure I'll get 
>   corrected if I'm wrong. :-) 
> 
>   I know folks should write ANSI Common Lisp now. However, textbooks
>   often have to stradle time. Or were written in a perious "age". 
>   Furthermore, I suspect most modern lisp implementations will take
> either.  
>   Perhaps there is some hackery that the #' reader macro does when it 
>   encounters "(lambda". 
> 

The change was post-CLtL2 I am almost sure.  The macro version of LAMBDA is
defined to expand to (FUNCTION (LAMBDA ...)) so there should be no
difference.  `Modern' (ANSI-conforming) CLs obviously have to take both.

(I still write #'(lambda ...) but I'm not sure why).

--tim
From: Erik Naggum
Subject: Re: basic question on lambda
Date: 
Message-ID: <3181405391206326@naggum.net>
* Lyman Taylor <············@mindspring.com.no.spam>
| Didn't that change come with ANSI Common Lisp?  CLtL2 required
| the #'(lambda... ) if I recall correctly.  I'm sure I'll get 
| corrected if I'm wrong. :-) 

  CLtL2 is in no position to require anything.  The second edition is
  an informational work bridghing CLtL, a standards document, and ANSI
  Common Lisp (which I sometimes call CLtS), obviously a standards
  document.

  CLtL didn't require the #' if you added the lambda macro yourself.
  What specifically changed was that quoted lambda forms were OK for
  funcall and the like.  They aren't, any longer.

| I know folks should write ANSI Common Lisp now.  However, textbooks
| often have to stradle time.  Or were written in a perious "age".
| Furthermore, I suspect most modern lisp implementations will take
| either.

  All the more reason to update people here, don't you think?

| Perhaps there is some hackery that the #' reader macro does when it
| encounters "(lambda".

  What kind of hackery would that be?

| A list that begins with the symbol LAMBDA has magical connotations in   
| certain contexts. 

  No.  This is what vanished between CLtL and CLtS.

  If you're trying to help, please make sure that you don't nonsense,
  and check your facts whenever you include them.  Thank you.

#:Erik
-- 
  I agree with everything you say, but I would
  attack to death your right to say it.
				-- Tom Stoppard
From: Duane Rettig
Subject: Re: basic question on lambda
Date: 
Message-ID: <4itqi7zv7.fsf@beta.franz.com>
Lyman Taylor <············@mindspring.com.no.spam> writes:

> Erik Naggum wrote:
> > 
> > * Nils Goesche <············@anylinx.de>
> > | What is this all about?  Why do all Lisp books put #' in front of a
> > | lambda expression?  
> ...
> >   Note that you don't need to write (function (lambda ...)) because
> >   (lambda ...) is a macro that expands to (function (lambda ...)).
> 
>   Didn't that change come with ANSI Common Lisp?  CLtL2 required
>   the #'(lambda... ) if I recall correctly.  I'm sure I'll get 
>   corrected if I'm wrong. :-) 

You're not wrong.

>   I know folks should write ANSI Common Lisp now. However, textbooks
>   often have to stradle time. Or were written in a perious "age". 

I believe that this is why x3J13/ANSI added the macro definition.  There was
still a lot of legacy code out there at the time functionp was redefined
for cltl2, and I think there were probably a lot of complaints.  We always
supported funcall of the car of a lambda form as an extension, so it was
not an issue with us.  But portable code had to change for cltl2, until
it was no longer necessary because of the addition of the macro definition.

>   Furthermore, I suspect most modern lisp implementations will take either.  
>   Perhaps there is some hackery that the #' reader macro does when it 
>   encounters "(lambda". 

No, there's no hackery.  At least, there shouldn't be; a list with 'lambda
as the car should be precisely that: a list with lambda as the car.  If it
is seen within a (function ...) [ i.e. #' ] then it is up to the function
special-operator to perform any transformations on the list to turn it into
a functionp object.

>   As for the curry macro example:
> 
>   >> * (mapcar #'(LAMBDA (&REST X) (APPLY #'+ 2 X)) '(0 1 2 3))
>   >>   (2 3 4 5)
> 
>   It is highly likely that following works also. [ I don't have CMULISP,
>   but from experience with MCL, Allegro, and Lispworks. ]
> 
>      * (mapcar  (lambda (&rest x) (apply #'+ 2 X)) '(0 1 2 3 )) 
>        (2 3 4 5) 
> 
>   which is why   (mapcar (curry .. ) ... )  works. 
> 
>   In general  #' should only be utilized on symbols. The execption is 
>   (lambda .... ).

Not quite true.  The function special operator is defined for function names
and lambda expressions. This also includes function names of the form
(setf ...).  Allegro CL extends this concept of a list-function-name; we call
it a function-spec.  Thus, you can identify such objects as #'(flet foo bar),
which is the compiled function object identified by bar below:

(defun foo ()
   (flet ((bar () ...

> Which is treated as in a special way which is backward
>   compatible with the old versions.

Not true; #'(lambda ...) [or (function (lambda ...)) ] is well-defined.

>  In fact, the following works also
>   ( which I personally think is a bad idea).
> 
>   (mapcar (list 'lambda '(&rest x) '(apply (function +) 2 x)) '(0 1 2 3 ))
>    (2 3 4 5)
> 
>   A list that begins with the symbol LAMBDA has magical connotations in   
>   certain contexts. 

This is true, and an extension to the spec.  We have considered removing it
from Allegro CL, but are afraid that legacy code which builds a lambda list
like you do above would then break.  It really doesn't hurt anything, either,
although it is much slower to call than a real function object.  However, if
you are dealing with interpreted code, the interpretation time washes out the
extra call time.

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Nils Goesche
Subject: Re: basic question on lambda
Date: 
Message-ID: <lkd7gpb17u.fsf@pc022.xcs.local>
Erik Naggum <····@naggum.net> writes:

> * Nils Goesche <············@anylinx.de>
> | What is this all about?  Why do all Lisp books put #' in front of a
> | lambda expression?  And why does it work with #' and a lambda
> | expression but not with #' and a ``curry'' expression?
> 
>   #'x is actually short for (function x), which quotes x in a
>   functional context, like 'x is short for (quote x), which quotes x
>   in data/variable context.  Look up the special operator function and
>   quote in your friendly standard reference material for the whole
>   story.
> 
>   Specifically, (function (lambda ...)) causes interpretation of the
>   (lambda ...) as a function (which means it may be funcalled, and
>   will be compiled), which (quote (lambda ...)) does not.
> 
>   Why would you want to quote (curry ...) in a functional context?

Actually, I disliked having to quote it and was glad it worked without
quotes.  But I wanted CURRY to be used the same way as LAMBDA, so it
won't be hard to remember how to use it.

[snip]

>   Note that you don't need to write (function (lambda ...)) because
>   (lambda ...) is a macro that expands to (function (lambda ...)).
>   I think it helps understanding Common Lisp's evaluation to think
>   of lambda as returning an anonymous function, and to disregard the
>   sometimes confusing #' or function special form.  Consequently, I
>   never quote lambda forms and consider it redundant to do so.

I found that #' in front of lambda confusing anyway, and I will gladly
omit it in the future :-)
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."