From: Anticomuna
Subject: Help with lambda form in CL
Date: 
Message-ID: <a5834590-fa64-423d-9837-359d4330953d@13g2000hsb.googlegroups.com>
Hi,

When evaluating forms in scheme if we have a lambda in the function
position like in the example:

((lambda (x y) (+ x y)) 1 2)

We can evaluate it as a "let" instead of creating the closure and
invoking it later. But in Common Lisp the lambda can't be evaluated in
a any meaningful way, we must always use the special operator function
or #' together with it. Then when calling the function we need to use
funcall, right? So, there's no way of having this optimization in
Common Lisp?

From: Brian
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <84eb01d5-1bd1-478a-bac0-8bb6bccb1f27@f63g2000hsf.googlegroups.com>
Anticomuna wrote:
> Hi,
>
> When evaluating forms in scheme if we have a lambda in the function
> position like in the example:
>
> ((lambda (x y) (+ x y)) 1 2)
>
> We can evaluate it as a "let" instead of creating the closure and
> invoking it later. But in Common Lisp the lambda can't be evaluated in
> a any meaningful way, we must always use the special operator function
> or #' together with it.
Actually:

[1]> ((lambda (x y) (+ x y)) 1 2)
3

(this only works for lambda though)
> Then when calling the function we need to use funcall, right? So,
> there's no way of having this optimization in Common Lisp?
A lisp-2 has its advantages and disadvantages.
From: Kaz Kylheku
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <c6dda904-1d8d-4ed1-8ec9-b4b25f23d7b7@u69g2000hse.googlegroups.com>
On Mar 10, 3:34 pm, Anticomuna <············@uol.com.br> wrote:
> Hi,
>
> When evaluating forms in scheme if we have a lambda in the function
> position like in the example:
>
> ((lambda (x y) (+ x y)) 1 2)

This is valid Common Lisp.

> We can evaluate it as a "let" instead of creating the closure and
> invoking it later. But in Common Lisp the lambda can't be evaluated in
> a any meaningful way, we must always use the special operator function
> or #' together with it.

Hence this is false. Neither FUNCTION nor FUNCALL are required; it
just works.

> So, there's no way of having this optimization in
> Common Lisp?

FUNCTION and FUNCALL should not be barriers against the optimization
of certain closure situations.

Even if you express it this way:

 (funcall #'(lambda (x y) (+ x y)) 1 2)

it is still optimizeable. FUNCALL is a standard Lisp function, and
FUNCTION is a standard special operator. The compiler can recognize
both.

Here, it is obvious that a closure is created which is immediately fed
to funcall. This can be transliterated to a LET at the source code
level, without any deep analysis, i.e. as fairly trivial DEFINE-
COMPILER-MACRO over FUNCALL.
From: Kent M Pitman
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <uod9m86c4.fsf@nhplace.com>
Anticomuna <············@uol.com.br> writes:

> Hi,

Ol�.
 
> When evaluating forms in scheme if we have a lambda in the function
> position like in the example:
> 
> ((lambda (x y) (+ x y)) 1 2)
> 
> We can evaluate it as a "let" instead of creating the closure and
> invoking it later.

I'm not sure what you mean here.  In CL you can certainly write

 (let ((x 1) (y 2)) (+ x y))

to get the above.  If you mean you can bind the function to a variable,
there's an example of that below.

> But in Common Lisp the lambda can't be evaluated in a any meaningful way,

I don't know where you got this idea, but it's not really right, or
perhaps you're not expressing yourself clearly.

It's true you cannot put an arbitrary form in the car of a list, but you
can put a lambda.

 ((lambda (x y) (+ x y)) 1 2)

 (funcall (lambda (x y) (+ x y)) 1 2)

 (funcall #'(lambda (x y) (+ x y)) 1 2)

are all valid forms.  The middle one works because LAMBDA is a macro in CL
such that (lambda (x y) (+ x y)) expands into #'(lambda (x y) (+ x y)).

> we must always use the special operator function or #' together with it.

Yes, except that it's special-cased in the car of a form and in other
places the macro suffices, so actually you can use it pretty much the
same as in Scheme.

What you CANNOT do is 

 (let ((f (lambda (x y) (+ x y))))
   (f 1 2))

For that you must write

 (let ((f (lambda (x y) (+ x y))))
   (funcall f 1 2))

> Then when calling the function we need to use funcall, right?

This has nothing to do with lambda and everything to do with name-evaluation
in the car of a form.  The car of a form is evaluated in a different namespace
than the other argument positions, so if you want something to evaluate to
a function you have to do it as an argument to some function, which is usually
FUNCALL (though APPLY, the mapping functions, and others are also higher-order
functions).

> So, there's no way of having this optimization in Common Lisp?

In CL, we use the term optimization to refer to speed, and this has nothing
to do with speed.  If by optimization, you mean "syntactic shorthand", then
what you want is not directly possible; CL means you to write:

 (flet ((f (x y) (+ x y)))
   (f 1 2))

where FLET will bind the name f in the function namespace rather than the
variable namespace, allowing you to use it in the car of the form.  If the
function needs to be recursive (or mutually recursive), use LABELS instead
of FLET.  LABELS corresponds [approximately] to letrec in Scheme.
From: Anticomuna
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <bc339e92-332e-4a3b-9b3d-4b2f327a59c6@13g2000hsb.googlegroups.com>
On 10 mar, 21:14, Kent M Pitman <······@nhplace.com> wrote:
> I'm not sure what you mean here.  In CL you can certainly write
>
>  (let ((x 1) (y 2)) (+ x y))
>
> to get the above.  If you mean you can bind the function to a variable,
> there's an example of that below.

I was referring to interpreter and compiler optimization, to turn
lambdas in the car of a list into let instead of creating a closure
just to invoke it later.

> I don't know where you got this idea, but it's not really right, or
> perhaps you're not expressing yourself clearly.
>
> It's true you cannot put an arbitrary form in the car of a list, but you
> can put a lambda.
>
>  ((lambda (x y) (+ x y)) 1 2)
>
>  (funcall (lambda (x y) (+ x y)) 1 2)
>
>  (funcall #'(lambda (x y) (+ x y)) 1 2)
>
> are all valid forms.  The middle one works because LAMBDA is a macro in CL
> such that (lambda (x y) (+ x y)) expands into #'(lambda (x y) (+ x y)).

I remembered of common lisp as having to use the #'. But why does it
exit? If they are interchangeable then what's the point? Is there any
situation where I have to use #'?

Thanks for the explanation.
From: Anticomuna
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <fb936d5a-d0d9-4346-9aec-88deb3c003c4@8g2000hse.googlegroups.com>
On 11 mar, 22:02, Anticomuna <············@uol.com.br> wrote:
> I remembered of common lisp as having to use the #'. But why does it
> exit? If they are interchangeable then what's the point? Is there any
> situation where I have to use #'?

I meant to say, "exist" and not "exit".
From: Kent M Pitman
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <u4pbcii24.fsf@nhplace.com>
Anticomuna <············@uol.com.br> writes:

> > It's true you cannot put an arbitrary form in the car of a list, but you
> > can put a lambda.
> >
> > �((lambda (x y) (+ x y)) 1 2)
> >
> > �(funcall (lambda (x y) (+ x y)) 1 2)
> >
> > �(funcall #'(lambda (x y) (+ x y)) 1 2)
> >
> > are all valid forms. �The middle one works because LAMBDA is a macro in CL
> > such that (lambda (x y) (+ x y)) expands into #'(lambda (x y) (+ x y)).
> 
> I remembered of common lisp as having to use the #'. But why does it
> exist? If they are interchangeable then what's the point? Is there any
> situation where I have to use #'?

CL is evolved from earlier dialects and has tried to remain compatible
with older dialects in some places.  This is one.

Historically, the symbol LAMBDA in the car of a list was literally the
indicator of a function.  As recently as CLTL (1984) but also going back
to MACLISP, you could do

 (funcall '(lambda (x y) (+ x y)) 1 2)

and it would succeed.  And there was no LAMBDA macro.  In that dialect,

 (function (lambda (x y) (+ x y))) ; same as  #'(lambda (x y) (+ x y))

was a way of saying "yes, I'm quoting this list, but really if you're
the compiler, you should go ahead and compile it, because all I'm going
to do is funcall it anyway".  But, in fact, you could have used QUOTE.
(The other subtle detail is that by using QUOTE, you were meaning that
EVAL would get called [with the null lexical environment], and that means 

;; THIS USED TO WORK IN CLTL1, BUT SHOULDN'T WORK NOW
(let ((v 1))                    ; Special V
  (declare (special v))
  (let ((v 2))                  ; Lexical V
    (funcall '(lambda () v))))

would return 1, not 2, because the list that was funcalled would not 
have the lexical environment along with it.  After all, it would be
equivalent to:

;; THIS USED TO WORK IN CLTL1, BUT SHOULDN'T WORK NOW
(let ((exp '(lambda () v)))
  (let ((v 1))                    ; Special V
    (declare (special v))
    (let ((v 2))                  ; Lexical V
      (funcall exp))))

But within forms, ((lambda ...) ...) was traditionally handled
specially and NEVER creates a closure (well, ok, it may in some
implementation, but I claim it's probably rare and certainly not
intended) because exactly because of the fact that the car of the form
is not evaluated, it is special-cased.  It's not like Scheme where you
always evaluate the car of the form first and then call the result.
In CL, the mere presence of the lambda means to do something very
primitive, usually sub-primitive to LET.  No closure.

Similarly, (FUNCTION (LAMBDA ...)) was treated specially.  Ordinarily,
function took the name of a function, but LAMBDA was recognized
specially, again by its being a list whose care was LAMBDA, rather
than (FUNCTION FOO) which just took a symbol.  In the case of
FUNCTION, the CL compiler was able to capture the lexical environment,
so that works ok. But really it was FUNCTION, originally, not LAMBDA
that was where the magic was.  LAMBDA in this case was just the "name"
of an anonymous function, given by describing rather than naming that
function.

During ANSI CL standardization, I had reviewed ISLISP and noted that there
were a few minor problems making compatibility within CL.  One of them
was the absence of DEFINE-SYMBOL-MACRO (needed as a way of implementing
some ISLISP special forms).  The other was that users who didn't like
writing #' couldn't portably do what many had come to do, which was to
do
 (defmacro lambda (lambda-list &body body) `#'(lambda ,lambda-list ,@body))
not because we couldn't write it but because CL was defined to give you an
error if you tried to redefine a system symbol.  LAMBDA was a system symbol,
just not one that had a definition. Giving it a definition broke things,
even though everyone was trying to give it this same definition.  So,
for ISLISP and Scheme cultural compatibility, we added the lambda macro
as a way of reducing the cultural difference between Scheme and CL.

In effect, #'(lambda...) is the primitive form.  And some (myself
included) still use it some of the time. (I often prefer it.)  But the
other style expands into it, so a lot of people leave out the #'.

That was as close as we could get to Scheme without giving up
something that our customer community would notice and care about.  It
had no observable negative impact, so it seemed like the right thing
to do.
From: Pascal Costanza
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <63paa8F290ojtU2@mid.individual.net>
Anticomuna wrote:
> On 10 mar, 21:14, Kent M Pitman <······@nhplace.com> wrote:
>> I'm not sure what you mean here.  In CL you can certainly write
>>
>>  (let ((x 1) (y 2)) (+ x y))
>>
>> to get the above.  If you mean you can bind the function to a variable,
>> there's an example of that below.
> 
> I was referring to interpreter and compiler optimization, to turn
> lambdas in the car of a list into let instead of creating a closure
> just to invoke it later.
> 
>> I don't know where you got this idea, but it's not really right, or
>> perhaps you're not expressing yourself clearly.
>>
>> It's true you cannot put an arbitrary form in the car of a list, but you
>> can put a lambda.
>>
>>  ((lambda (x y) (+ x y)) 1 2)
>>
>>  (funcall (lambda (x y) (+ x y)) 1 2)
>>
>>  (funcall #'(lambda (x y) (+ x y)) 1 2)
>>
>> are all valid forms.  The middle one works because LAMBDA is a macro in CL
>> such that (lambda (x y) (+ x y)) expands into #'(lambda (x y) (+ x y)).
> 
> I remembered of common lisp as having to use the #'. But why does it
> exit? If they are interchangeable then what's the point? Is there any
> situation where I have to use #'?

The variations exist for historical reasons. The lambda macro was added 
to ANSI Common Lisp relatively late in the game, to ensure some form of 
compatibility with other Lisp dialects.


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: viper-2
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <e336ab4a-861f-4905-947e-5c5795e98f1b@s37g2000prg.googlegroups.com>
On Mar 12, 1:08 am, Pascal Costanza <····@p-cos.net> wrote:
> Anticomuna wrote:
> > On 10 mar, 21:14, Kent M Pitman <······@nhplace.com> wrote:
> >> I'm not sure what you mean here.  In CL you can certainly write
>
> >>  (let ((x 1) (y 2)) (+ x y))
>
> >> to get the above.  If you mean you can bind the function to a variable,
> >> there's an example of that below.
>
> > I was referring to interpreter and compiler optimization, to turn
> > lambdas in the car of a list into let instead of creating a closure
> > just to invoke it later.
>
> >> I don't know where you got this idea, but it's not really right, or
> >> perhaps you're not expressing yourself clearly.
>
> >> It's true you cannot put an arbitrary form in the car of a list, but you
> >> can put a lambda.
>
> >>  ((lambda (x y) (+ x y)) 1 2)
>
> >>  (funcall (lambda (x y) (+ x y)) 1 2)
>
> >>  (funcall #'(lambda (x y) (+ x y)) 1 2)
>
> >> are all valid forms.  The middle one works because LAMBDA is a macro in CL
> >> such that (lambda (x y) (+ x y)) expands into #'(lambda (x y) (+ x y)).
>
> > I remembered of common lisp as having to use the #'. But why does it
> > exit? If they are interchangeable then what's the point? Is there any
> > situation where I have to use #'?
>
> The variations exist for historical reasons. The lambda macro was added
> to ANSI Common Lisp relatively late in the game, to ensure some form of
> compatibility with other Lisp dialects.
>
> Pascal

The history cleared up a few cobwebs. I wasn't sure what Anticomuna
was asking since the Let form was obviously syntactic sugar for the
applied lambda expression.

If LET had been implemented as a macro one could use MACROEXPAND to
view the code into which it expands. Is it possible to view the code
for which a special form, such as LET, is syntactic shorthand?

agt
From: Stanisław Halik
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <fr8th4$mfa$3@news2.task.gda.pl>
thus spoke viper-2 <········@mail.infochan.com>:

> If LET had been implemented as a macro one could use MACROEXPAND to
> view the code into which it expands. Is it possible to view the code
> for which a special form, such as LET, is syntactic shorthand?

Yes, to some extent :) See DISASSEMBLE.

-- 
Nawet świnka wejdzie na drzewo kiedy ją chwalą.
From: Pascal J. Bourguignon
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <7cbq5kq885.fsf@pbourguignon.anevia.com>
viper-2 <········@mail.infochan.com> writes:
> The history cleared up a few cobwebs. I wasn't sure what Anticomuna
> was asking since the Let form was obviously syntactic sugar for the
> applied lambda expression.
>
> If LET had been implemented as a macro one could use MACROEXPAND to
> view the code into which it expands. Is it possible to view the code
> for which a special form, such as LET, is syntactic shorthand?

Yes.  Just groups.google for "defmacro let":

http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/d5f8896cb9e2d00b/c2fe7c7445d4b3d1?lnk=st&q=%22defmacro+let%22#c2fe7c7445d4b3d1

http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/de9d0c9066b28649/ea1c216ac8fb54bb?lnk=st&q=%22defmacro+let%22#ea1c216ac8fb54bb

etc...

-- 
__Pascal Bourguignon__
From: Tobias C. Rittweiler
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <877ig7lx80.fsf@freebits.de>
···@informatimago.com (Pascal J. Bourguignon) writes:

> viper-2 <········@mail.infochan.com> writes:
> 
> > If LET had been implemented as a macro one could use MACROEXPAND to
> > view the code into which it expands. Is it possible to view the code
> > for which a special form, such as LET, is syntactic shorthand?
>
> Yes.  Just groups.google for "defmacro let":
>
> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/d5f8896cb9e2d00b/c2fe7c7445d4b3d1?lnk=st&q=%22defmacro+let%22#c2fe7c7445d4b3d1
>
> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/de9d0c9066b28649/ea1c216ac8fb54bb?lnk=st&q=%22defmacro+let%22#ea1c216ac8fb54bb
>
> etc...

Notice that both your LET and LET* definitions are broken.

In fact, I don't think that LET can be implemented via LAMBDA in
presence of /lambda list keywords/ and LAMBDA-PARAMETERS-LIMIT.

E.g.

  (let ((&key 42)) &key)

LET* cannot straightforwardly be implemented with nested LETs (as in
your example) because of missing declaration shuffling. 

It can, however, be approximated via LAMBDA and &AUX variables:

    (let* ((&key 42) (&optional (1+ &key))
      (values &key &optional))

    ==

    ((lambda (&aux (&key 42) (&optional (1+ &key))) 
       (values &key &optional)))

(With the argumentation that &AUX "parameters" aren't actually real
parameters, and hence not contrained by LAMBDA-PARAMETERS-LIMIT.)

However even that breaks because LAMBDA takes a documentation string and
LET/LET* don't.

  -T.
From: Pascal Costanza
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <63qdp3F28atgkU1@mid.individual.net>
viper-2 wrote:

>> The variations exist for historical reasons. The lambda macro was added
>> to ANSI Common Lisp relatively late in the game, to ensure some form of
>> compatibility with other Lisp dialects.
>>
>> Pascal
> 
> The history cleared up a few cobwebs. I wasn't sure what Anticomuna
> was asking since the Let form was obviously syntactic sugar for the
> applied lambda expression.
> 
> If LET had been implemented as a macro one could use MACROEXPAND to
> view the code into which it expands. Is it possible to view the code
> for which a special form, such as LET, is syntactic shorthand?

No. A Common Lisp implementation is not required to provide macro 
definitions that have the same semantics as the corresponding special 
forms (but it is allowed to do so).

However, in the general case, it's not possible. For the "ground" 
special forms, there are no expansions into even more "ground" special 
forms. Macroexpansion has to stop at some level, and there always have 
to be a number of forms that need to be provided by the implementation 
as "atomic units". Otherwise, Lisp wouldn't be well-defined.

See http://home.pipeline.com/~hbaker1/MetaCircular.html though. 
(Metacircular semantics are a different case, but related...)


Pascal

-- 
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/

My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: viper-2
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <b5eb6fbc-a1ca-4ba0-9810-158488570530@d4g2000prg.googlegroups.com>
On Mar 12, 11:13 am, Pascal Costanza <····@p-cos.net> wrote:

> No. A Common Lisp implementation is not required to provide macro
> definitions that have the same semantics as the corresponding special
> forms (but it is allowed to do so).
>
> However, in the general case, it's not possible. For the "ground"
> special forms, there are no expansions into even more "ground" special
> forms. Macroexpansion has to stop at some level, and there always have
> to be a number of forms that need to be provided by the implementation
> as "atomic units". Otherwise, Lisp wouldn't be well-defined.

Thanks, you're right:

>(disassemble 'let)
can't disassemble LET

This is with GCL. CLISP gives an equivalent message.

agt
From: Pascal Bourguignon
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <87y78nwxxn.fsf@thalassa.informatimago.com>
viper-2 <········@mail.infochan.com> writes:
>>(disassemble 'let)
> can't disassemble LET

Obviously, you have to macroexpand it.

(defun disassemble-form (form)
  (disassemble (compile nil `(lambda nil ,form))))


C/USER[240]> (disassemble-form '(let ((a 1) (b 2)) (+ a b)))

Disassembly of function NIL
(CONST 0) = 1
(CONST 1) = 2
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (CONST&PUSH 0)                      ; 1
1     (CONST&PUSH 1)                      ; 2
2     (CALLSR 2 53)                       ; +
5     (SKIP&RET 1)
NIL

C/USER[241]> (disassemble-form '((lambda (a b) (+ a b)) 1 2))

Disassembly of function NIL
(CONST 0) = 1
(CONST 1) = 2
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (CONST&PUSH 0)                      ; 1
1     (CONST&PUSH 1)                      ; 2
2     (CALLSR 2 53)                       ; +
5     (SKIP&RET 1)
NIL
-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Small brave carnivores
Kill pine cones and mosquitoes
Fear vacuum cleaner
From: viper-2
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <eeca4135-530b-487d-a33a-8c6fbb7c45f2@i29g2000prf.googlegroups.com>
On Mar 12, 2:21 pm, Pascal Bourguignon <····@informatimago.com> wrote:
> viper-2 <········@mail.infochan.com> writes:
> >>(disassemble 'let)
> > can't disassemble LET
>
> Obviously, you have to macroexpand it.

I thought there might have been some sort of assembly-language-looking
output nevertheless corresponding to calling a LET with no parameters
or body.

This is why I asked the question. Perhaps we should refer to this as
disassembly as opposed to macroexpansion?

Clisp interprets the call to the anonymous procedure a little
differently:

[2]> (defun Pascal-disassemble (form)
  (disassemble (compile nil `(lambda nil ,form))))
PASCAL-DISASSEMBLE

[3]> (pascal-disassemble '(let ((a 1) (b 2)) (+ a b)))


Disassembly of function NIL
(CONST 0) = 1
(CONST 1) = 2
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
0     (CONST&PUSH 0)                      ; 1
1     (CONST&PUSH 1)                      ; 2
2     (CALLSR 2 54)                       ; +
5     (SKIP&RET 1)
#<COMPILED-CLOSURE NIL>



[4]> (pascal-disassemble '((lambda (a b) (+ a b) 1 2)))

Disassembly of function NIL
(CONST 0) = #<COMPILED-CLOSURE COMMON-LISP::NIL-1>
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
0     (CONST&PUSH 0)                      ; #<COMPILED-CLOSURE COMMON-
LISP::NIL-1>
1     (FUNCALL 0)
3     (SKIP&RET 1)
#<COMPILED-CLOSURE NIL>
[5]>


Thanks to you and Stanislaw, I've just been introduced to
DISASSEMBLE!!

agt
From: Pascal Bourguignon
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <87y78nv8jp.fsf@thalassa.informatimago.com>
viper-2 <········@mail.infochan.com> writes:

> On Mar 12, 2:21 pm, Pascal Bourguignon <····@informatimago.com> wrote:
>> viper-2 <········@mail.infochan.com> writes:
>> >>(disassemble 'let)
>> > can't disassemble LET
>>
>> Obviously, you have to macroexpand it.
>
> I thought there might have been some sort of assembly-language-looking
> output nevertheless corresponding to calling a LET with no parameters
> or body.
>
> This is why I asked the question. Perhaps we should refer to this as
> disassembly as opposed to macroexpansion?
>
> Clisp interprets the call to the anonymous procedure a little
> differently:
>
> [2]> (defun Pascal-disassemble (form)
>   (disassemble (compile nil `(lambda nil ,form))))
> PASCAL-DISASSEMBLE
>
> [3]> (pascal-disassemble '(let ((a 1) (b 2)) (+ a b)))
>
>
> Disassembly of function NIL
> (CONST 0) = 1
> (CONST 1) = 2
> 0 required arguments
> 0 optional arguments
> No rest parameter
> No keyword parameters
> 0     (CONST&PUSH 0)                      ; 1
> 1     (CONST&PUSH 1)                      ; 2
> 2     (CALLSR 2 54)                       ; +
> 5     (SKIP&RET 1)
> #<COMPILED-CLOSURE NIL>
>
>
>
> [4]> (pascal-disassemble '((lambda (a b) (+ a b) 1 2)))
>
> Disassembly of function NIL
> (CONST 0) = #<COMPILED-CLOSURE COMMON-LISP::NIL-1>
> 0 required arguments
> 0 optional arguments
> No rest parameter
> No keyword parameters
> 0     (CONST&PUSH 0)                      ; #<COMPILED-CLOSURE COMMON-
> LISP::NIL-1>
> 1     (FUNCALL 0)
> 3     (SKIP&RET 1)
> #<COMPILED-CLOSURE NIL>
> [5]>

This is different because the forms are NOT equivalent. The first returns 3, the later 2.

>
> Thanks to you and Stanislaw, I've just been introduced to
> DISASSEMBLE!!
>
> agt

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.
From: viper-2
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <ead5e9e0-d30a-43a4-8018-183b720b2e64@u10g2000prn.googlegroups.com>
On Mar 12, 6:15 pm, Pascal Bourguignon <····@informatimago.com> wrote:
>
> This is different because the forms are NOT equivalent. The first returns 3, the later 2.

Forgive me; I'm a little off my game today. I missed a closing paren
in the lambda form. Here we go:

1. Break [3]> (pascal-disassemble '((lambda (a b) (+ a b)) 1 2))


Disassembly of function NIL
(CONST 0) = 1
(CONST 1) = 2
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
0     (CONST&PUSH 0)                      ; 1
1     (CONST&PUSH 1)                      ; 2
2     (CALLSR 2 54)                       ; +
5     (SKIP&RET 1)
#<COMPILED-CLOSURE NIL>


agt
From: Thomas A. Russ
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <ymiy78ng85m.fsf@blackcat.isi.edu>
Anticomuna <············@uol.com.br> writes:

> On 10 mar, 21:14, Kent M Pitman <······@nhplace.com> wrote:
> > I'm not sure what you mean here. �In CL you can certainly write
> >
> > �(let ((x 1) (y 2)) (+ x y))
> >
> > to get the above. �If you mean you can bind the function to a variable,
> > there's an example of that below.
> 
> I was referring to interpreter and compiler optimization, to turn
> lambdas in the car of a list into let instead of creating a closure
> just to invoke it later.

Well, a lot of compilers only create a true closure if there are unbound
variables in the body of the function.  So, a lambda expression without
unbound variables will end up being compiles as an anonymous function
without any closure mechanism added.

On the other hand, I believe it will still be treated as a function
invocation, instead of being unrolled into in-line code.  But function
call overhead should be relatively small.

[Snip discussion of LAMBDA macro and dropping the need to use #' in
 front of lambda expressions]

> I remembered of common lisp as having to use the #'. But why does it
> exit? If they are interchangeable then what's the point? Is there any
> situation where I have to use #'?

It largely about namespace management.

There are situations where you need to use #', but they don't involve
the lambda macro.  You need them to force the interpretation of the
following form in the function namespace rather than in the value
namespace.  As an example, look at the following examples:

(defun foo () (print "Global Function"))

(flet ((foo () (print "Local Function")))
  (let ((foo (lambda () (print "Let bound value"))))
    (funcall foo)
    (funcall 'foo)
    (funcall (symbol-function 'foo))
    (funcall #'foo)
    t))


Note that using just 'foo is the same as invoking
 (symbol-function 'foo), which only gets the global name.


-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: Help with lambda form in CL
Date: 
Message-ID: <87ve3uxgml.fsf@thalassa.informatimago.com>
Anticomuna <············@uol.com.br> writes:

> Hi,
>
> When evaluating forms in scheme if we have a lambda in the function
> position like in the example:
>
> ((lambda (x y) (+ x y)) 1 2)
>
> We can evaluate it as a "let" instead of creating the closure and
> invoking it later. But in Common Lisp the lambda can't be evaluated in
> a any meaningful way, we must always use the special operator function
> or #' together with it. Then when calling the function we need to use
> funcall, right? So, there's no way of having this optimization in
> Common Lisp?

In what universe?

In mine:

C/USER[235]>  ((lambda (x y) (+ x y)) 1 2)
3
C/USER[236]> (disassemble (compile nil (lambda ()  ((lambda (x y) (+ x y)) 1 2))))

Disassembly of function NIL
(CONST 0) = 1
(CONST 1) = 2
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (CONST&PUSH 0)                      ; 1
1     (CONST&PUSH 1)                      ; 2
2     (CALLSR 2 53)                       ; +
5     (SKIP&RET 1)
NIL
C/USER[237]> (symbol-package 'lambda)
#<PACKAGE COMMON-LISP>
C/USER[238]> 

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.