From: David Steuber
Subject: My Patented Lambda Substitute
Date: 
Message-ID: <871xcb5uq3.fsf@david-steuber.com>
OK, I haven't actually applied for a patent...

I was looking for a way to understand lambda better.  After looking
through the CLHS and still puzzling a bit over the (lambda ...) =>
#'(lambda ...) expansion, I came up with this:

CL-USER> (defmacro my-lambda (args &body forms)
           (let ((anon (gensym)))
             `(flet ((,anon ,args ,@forms)) (function ,anon))))
MY-LAMBDA
CL-USER> (mapcar (my-lambda (x) (* 2 x)) '(1 2 3 4 5))
(2 4 6 8 10)
CL-USER> (mapcar (my-lambda (x) (* x x)) '(1 2 3 4 5))
(1 4 9 16 25)
CL-USER> (mapcar #'(my-lambda (x) (* x x)) '(1 2 3 4 5))
; Evaluation aborted

The key wasn't so much lambda the macro vs lambda the symbol.  It
really turned out to be the fact that function is a special form.
When function is passed a list who's car is lambda, it returns an
anonymous function that takes arguments matching the lambda-list.

The real lesson is that I don't need lambda to make an anonymous
function or to create a closure but I do need function.  Lambda
expands into function.  To me, lambda used to look like a recursive
macro.

How's my understanding?

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1

From: Steven M. Haflich
Subject: Re: My Patented Lambda Substitute
Date: 
Message-ID: <41F5F3BE.1060606@alum.mit.edu>
David Steuber wrote:

> How's my understanding?

The symbol cl:lambda has two meanings within the ANS.

One is that it names a macro, approximately:

   (defmacro lambda (&rest r) `(function (lambda ,@r)))

The other is as a syntactic marker denoting a lambda expression
that denotes a function:

   ((lambda (x y) (cons y x)) 1 2) ==> (2 . 1)

You can recode an alternative lambda macro in a variety of
equivalent ways, but there is no way you can implement the
syntactic marker.  It is built into the interpreter, compiler,
and whatever else the implementation implements.  This is
similar to the several syntactic markers known as lambda-list
keywords; there is no way you can redefine these without
reimplementing a huge amount of the language.
From: David Steuber
Subject: Re: My Patented Lambda Substitute
Date: 
Message-ID: <87is5l487p.fsf@david-steuber.com>
"Steven M. Haflich" <·················@alum.mit.edu> writes:

> The symbol cl:lambda has two meanings within the ANS.
> 
> One is that it names a macro, approximately:
> 
>    (defmacro lambda (&rest r) `(function (lambda ,@r)))

I got this one down I think.  What had me confused before is that, on
the surface, it looks like a recursive macro.  Of course it's not, but
it was looking that way to me.

> The other is as a syntactic marker denoting a lambda expression
> that denotes a function:
> 
>    ((lambda (x y) (cons y x)) 1 2) ==> (2 . 1)

I forgot about this case.  MY-LAMBDA can not be used that way as you
said.  The closest I can come is this:

CL-USER> (funcall (my-lambda (x y) (cons y x)) 1 2)
(2 . 1)

> You can recode an alternative lambda macro in a variety of
> equivalent ways, but there is no way you can implement the
> syntactic marker.  It is built into the interpreter, compiler,
> and whatever else the implementation implements.  This is
> similar to the several syntactic markers known as lambda-list
> keywords; there is no way you can redefine these without
> reimplementing a huge amount of the language.

Unless I did this wrong, I can see how the syntactic marker is
available beyond just FUNCTION:

CL-USER> (macroexpand '((lambda (x y) (cons y x)) 1 2))
((LAMBDA (X Y) (CONS Y X)) 1 2)
NIL

LAMBDA is not a special operator but forms with LAMBDA still seem to
be treated specially.

-- 
An ideal world is left as an excercise to the reader.
   --- Paul Graham, On Lisp 8.1
From: Brian Downing
Subject: Re: My Patented Lambda Substitute
Date: 
Message-ID: <NPPJd.22089$P04.13248@attbi_s03>
In article <··············@david-steuber.com>,
David Steuber  <·····@david-steuber.com> wrote:
> Unless I did this wrong, I can see how the syntactic marker is
> available beyond just FUNCTION:
> 
> CL-USER> (macroexpand '((lambda (x y) (cons y x)) 1 2))
> ((LAMBDA (X Y) (CONS Y X)) 1 2)
> NIL
> 
> LAMBDA is not a special operator but forms with LAMBDA still seem to
> be treated specially.

See CLHS 3.1.2.1.2.4:

    3.1.2.1.2.4 Lambda Forms

    A lambda form is similar to a function form, except that the
    function name is replaced by a lambda expression.

    A lambda form is equivalent to using funcall of a lexical closure of
    the lambda expression on the given arguments. (In practice, some
    compilers are more likely to produce inline code for a lambda form
    than for an arbitrary named function that has been declared inline;
    however, such a difference is not semantic.)

    For further information, see Section 3.1.3 (Lambda Expressions).

The behavior is built into the evaluation model - it's the fourth way to
evaluate a cons form (the first three being the cases where the car is a
special operator, macro, or function).

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