Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
(newbie?) Question about map car and funcall
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  15 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Luca Antonelli  
View profile  
 More options Oct 14 2012, 9:38 am
Newsgroups: comp.lang.lisp
From: Luca Antonelli <luke.a...@gmail.com>
Date: Sun, 14 Oct 2012 06:38:10 -0700 (PDT)
Local: Sun, Oct 14 2012 9:38 am
Subject: (newbie?) Question about map car and funcall
Hi, I have a list of functions in Common Lisp, say (1+ 1-), and apply them to a list of arguments, say (2 5), to obtain (3 4).

(mapcar #'funcall '(1+ 1-) '(2 5)) does the trick, but, if I try to substitute 1+ with a lambda expression, such as

(mapcar #'funcall '((lambda (x) (1+ x)) 1-) '(2 5))

it raises an error: "FUNCALL: argument (LAMBDA (X) (1+ X)) is not a function."

(mapcar #'funcall '(#'(lambda (x) (1+ x)) 1-) '(2 5))
also doesn't work and returns "FUNCALL: #'(LAMBDA (X) (1+ X)) is not a function name; try using a symbol instead"

What's the difference between the lambda and 1+ ?

I've also noticed that if I use funcall without mapcar I have to use the function operator:
(funcall #'1+ 3) ==> 4
(funcall #'(lambda (x) (1+ x)) 3) ==> 4
all of them return no exceptions.

I  think there is some relation with my problem, but I have no other clue. I tried some Internet research, but found no example similar to my case.

Luca


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Marco Antoniotti  
View profile  
 More options Oct 14 2012, 9:55 am
Newsgroups: comp.lang.lisp
From: Marco Antoniotti <marc...@gmail.com>
Date: Sun, 14 Oct 2012 06:55:30 -0700 (PDT)
Local: Sun, Oct 14 2012 9:55 am
Subject: Re: (newbie?) Question about map car and funcall

LIST not QUOTE.

cl-prompt> (mapcar #'funcall (list '1+ '1+ (lambda (x) (+ x 42))) '(1 2 3))
(2 1 45)

--
MA


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Petter Gustad  
View profile  
 More options Oct 14 2012, 9:55 am
Newsgroups: comp.lang.lisp
From: Petter Gustad <newsmailco...@gustad.com>
Date: Sun, 14 Oct 2012 15:55:35 +0200
Local: Sun, Oct 14 2012 9:55 am
Subject: Re: (newbie?) Question about map car and funcall

Luca Antonelli <luke.a...@gmail.com> writes:

Consult the documentation on the macro quote (') which you use to
build the list:

'((lambda (x) (1+ x)) 1-) ->
((LAMBDA (X) (1+ X)) 1-)

vs:

(list #'(lambda (x) (1+ x)) #'1-) ->
(#<FUNCTION (LAMBDA #) {10053159EB}> #<FUNCTION 1->)

The following will work:

(mapcar #'funcall (list #'(lambda (x) (1+ x)) #'1-) '(2 5))

But you can also use ` and ,

(mapcar #'funcall `(,#'(lambda (x) (1+ x)) ,#'1-) '(2 5))

//Petter

--
.sig removed by request.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nils M Holm  
View profile  
 More options Oct 14 2012, 10:11 am
Newsgroups: comp.lang.lisp
From: Nils M Holm <news2...@t3x.org>
Date: 14 Oct 2012 14:11:31 GMT
Local: Sun, Oct 14 2012 10:11 am
Subject: Re: (newbie?) Question about map car and funcall

Luca Antonelli <luke.a...@gmail.com> wrote:
> (mapcar #'funcall '((lambda (x) (1+ x)) 1-) '(2 5))

> it raises an error: "FUNCALL: argument (LAMBDA (X) (1+ X)) is not
> a function."

That's because (LAMBDA (X) (1+ X)) is a function, but
              '(LAMBDA (X) (1+ X)) is a list.

You may try

(mapcar #'funcall `(,(lambda (x) (1+ x)) 1-) '(2 5))

instead. (Note: backquote instead of quote.)

--
Nils M Holm  < n m h @ t 3 x . o r g >  www.t3x.org


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luca Antonelli  
View profile  
 More options Oct 14 2012, 10:14 am
Newsgroups: comp.lang.lisp
From: Luca Antonelli <luke.a...@gmail.com>
Date: Sun, 14 Oct 2012 07:14:14 -0700 (PDT)
Local: Sun, Oct 14 2012 10:14 am
Subject: Re: (newbie?) Question about map car and funcall
Thank you, it works (and, more important, I understood the error).

Luca

Il giorno domenica 14 ottobre 2012 15:55:36 UTC+2, Petter Gustad ha scritto:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Norbert_Paul  
View profile  
 More options Oct 14 2012, 10:21 am
Newsgroups: comp.lang.lisp
From: Norbert_Paul <norbertpauls_spam...@yahoo.com>
Date: Sun, 14 Oct 2012 16:21:50 +0200
Local: Sun, Oct 14 2012 10:21 am
Subject: Re: (newbie?) Question about map car and funcall
Luca Antonelli wrote:
> Hi, I have a list of functions in Common Lisp, say (1+ 1-), and apply them to a list of arguments, say (2 5), to obtain (3 4).

> (mapcar #'funcall '(1+ 1-) '(2 5)) does the trick, but, if I try to substitute 1+ with a lambda expression, such as

> (mapcar #'funcall '((lambda (x) (1+ x)) 1-) '(2 5))

> it raises an error: "FUNCALL: argument (LAMBDA (X) (1+ X)) is not a function."

That is true. The first element of '((lambda (x) (1+ x)) 1-) is simply the list (lambda (x) (1+ x)) and not
a function (just af if you had written (list 'lambda '(x) '(1+ x)) ).
Note that 'foo is a shorthand for writing (quote foo). Quote is not a function but a special operator thaat does not
evaluate its arguments.

> (mapcar #'funcall '(#'(lambda (x) (1+ x)) 1-) '(2 5))
> also doesn't work and returns "FUNCALL: #'(LAMBDA (X) (1+ X)) is not a function name; try using a symbol instead"

Here the first element of your list is the list  (function (lambda (x) (1+ x))). Then notation "#'foo" is only a shorthand
for writing "(function foo)" (just like "'foo" is a shorthand for writing "(quote foo)").

> What's the difference between the lambda and 1+ ?

1+ is just a symbol that is fbound to a function. When you do "(apply some-symbol some-arguments)" then  the
function definition of that symbol (in the "global" lexical environment) is used.
Neither the list (function (lambda (x) (1+ x))) nor (lambda (x) (1+ x)) are functions.
However, when either list is evaluated it /produces/ a function.

> I've also noticed that if I use funcall without mapcar I have to use the function operator:
> (funcall #'1+ 3) ==>  4
> (funcall #'(lambda (x) (1+ x)) 3) ==>  4
> all of them return no exceptions.

FUNCALL itself is a function that /evaluates/ all of its arguments, in particular  #'(lambda (x) (1+ x)) which
then produces a function.
Try (mapcar #'funcall (list (lambda (x) (1+ x)) '1-) '(2 5))
or  (mapcar #'funcall (list #'(lambda (x) (1+ x)) #'1-) '(2 5)) and variants.
The function LIST also evaluates the lambda form and produces a function object that can be applied.

Try also the followig on the REPL:

          '(lambda (x) (1+ x))            ; Just a list that starts with LAMBDA.
         '(lambada (x) (1+ x))           ; Just a list that starts not with LAMBDA.
         '(salsa (x) (1+ x))             ; A variant of the above
         '(merengue (x) (1+ x))          ; Ya variant of the above
          '#'(lambda (x) (1+ x))          ; Just a list that starts with FUNCTION ...
          (car '#'(lambda (x) (1 + x)))  ; ... as you can see here.
          '(function (lambda (x) (1+ x))) ; Just a List that starts with FUNCTION might be printed as "#'(LAMBDA (X) (1+ X))
           (lambda (x) (1+ x))            ; The LAMBDA macro expands to #'(lambda (x) (1+ x))
           (lambada (x) (1+ x))           ; Signals an error unless you have defined LAMBADA.
           (function (lambda (x) (1+ x))) ; Evaluation of #'(lambda (x)...) on the REPL
          #'(lambda (x) (1+ x))          ; Same as the above
           (defmacro LAMBADA (args &rest body) ; you may also use SALSA or MERENGUE
              (list 'FUNCTION (list* 'LAMBDA args body)))
           (lambada (x) (1+ x))           ; No more error (unless you used SALSA or MERENGUE.

This should give you a feeling of the differences.

Norbert


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Oct 14 2012, 12:42 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Sun, 14 Oct 2012 16:42:22 +0000 (UTC)
Local: Sun, Oct 14 2012 12:42 pm
Subject: Re: (newbie?) Question about map car and funcall
On 2012-10-14, Luca Antonelli <luke.a...@gmail.com> wrote:

> Hi, I have a list of functions in Common Lisp, say (1+ 1-), and apply them to a list of arguments, say (2 5), to obtain (3 4).

> (mapcar #'funcall '(1+ 1-) '(2 5)) does the trick, but, if I try to substitute 1+ with a lambda expression, such as

> (mapcar #'funcall '((lambda (x) (1+ x)) 1-) '(2 5))

This is as small inconsistency in Common Lisp. A lambda expression serves as a
function name, allowing you to use it in the first position of the list:

  (1+ 3) ;; straight named call

  ((lambda (x) (1+ x)) 3) ;; analogous

But, funcall and other applicators do not support this. Although they accept a
name (i.e. symbol) they don't accept a lambda expression:

  (funcall '1+ 3) ;; works

  (funcall '(lambda (x) (1+ x)) 3) ;; does not

The function operator, however takes both names and lambda expressions and
converts them function objects that can be called:

  (funcall (function 1+) 3)

  (funcall (function (lambda (x) (1+ x))) args ...) ;; analogous, again

Unfortunately, funcall is an operator, so if we have a name or lambda
expression in a variable fname, we would have to (eval `(function ,fname)).
Do we need to reach for eval? We do not, because, fortunately, there is a
function which can do this job, and that is the coerce function:

  (funcall (coerce '1+ 'function) 3)

  (funcall (coerce '(lambda (x) (1+ x)) 'function) 3)

coerce takes a value and a type, converting the value to the given type.

So if you have a list containing a mixture of function names and lambda
expressions, you can apply arguments to those functions like this:

 (mapcar (lambda (fname &rest args)
           (apply (coerce fname 'function) args))
         '(1+ 1- (lambda (x) (+ 10 x)))
         '(1 1 1))

Now for some philosophical notes. The funcall oprator could easily have this
coerce behavior built in, but it doesn't. That's probably for efficiency
reasons.

Note how I went out of my way to avoid eval, but actually that is irrational.

** This is because coercing a piece of data representing source code to a
** function IS a form of run-time evaluation!

That is to say, there is hardly anything better about (coerce x 'function) than
(eval `(function ,x)) when x holds a lambda expression. In both cases the lambda
syntax contained in x has to be parsed at run time and converted to a function
object.

So this is probably why the support for run-time lambdas as function names is
not so consistent: good Lisp hackers instinctively avoid this sort of run-time
evaluation, unless the problem really calls for it (which generally happens
when functions need to be produced from run-time inputs to the program).

We usually want to present a lambda expression to the Lisp system as program
code, rather than a datum.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Oct 14 2012, 12:54 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Sun, 14 Oct 2012 16:54:36 +0000 (UTC)
Local: Sun, Oct 14 2012 12:54 pm
Subject: Re: (newbie?) Question about map car and funcall
On 2012-10-14, Kaz Kylheku <k...@kylheku.com> wrote:

That's actually false. Funcall has to work somewhat like this.
(Imagine that system::builtin-apply is a built-in function applicator
which only understands function objects.)

 (defun funcall (fspec &rest args)
   (typecase (fspec)
     ;; fspec is a function object: just apply args to it
     (function (system::builtin-apply fspec args))
     ;; fspec is a symbol: try to retrieve the associated function and apply
     (symbol (system::builtin-apply (symbol-function func-or-name) args))))

Adding another case doesn't really hurt anything, since funcall already
has to check whether the input is a symbol or function.

 (defun funcall (fspec &rest args)
   (typecase (fspec)
     ;; fspec is a function object: just apply args to it
     (function (system::builtin-apply fspec args))
     ;; fspec is a symbol: try to retrieve the associated function and apply
     (symbol (system::builtin-apply (symbol-function func-or-name) args))
     ;; fspec might be a nonempty list, possibly a lambda form
     (cons (system::builtin-apply (coerce fspec 'function) args))))

I would argue for that to be supported in a new revision of Common Lisp.

Then of course, everyone in this thread will have to reverse his silly
position.

"No wait, (lambda ...) IS a function, after all, quoted or not!"


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christophe Rhodes  
View profile  
 More options Oct 14 2012, 5:00 pm
Newsgroups: comp.lang.lisp
From: Christophe Rhodes <cs...@cantab.net>
Date: Sun, 14 Oct 2012 22:00:56 +0100
Local: Sun, Oct 14 2012 5:00 pm
Subject: Re: (newbie?) Question about map car and funcall

Kaz Kylheku <k...@kylheku.com> writes:
> Adding another case doesn't really hurt anything, since funcall already
> has to check whether the input is a symbol or function.

>  (defun funcall (fspec &rest args)
>    (typecase (fspec)
>      ;; fspec is a function object: just apply args to it
>      (function (system::builtin-apply fspec args))
>      ;; fspec is a symbol: try to retrieve the associated function and apply
>      (symbol (system::builtin-apply (symbol-function func-or-name) args))
>      ;; fspec might be a nonempty list, possibly a lambda form
>      (cons (system::builtin-apply (coerce fspec 'function) args))))

> I would argue for that to be supported in a new revision of Common Lisp.

With what semantics for the lookup of variables in the function not
present in the lambda list?  

(By strict analogy with the function position, you might want lexical
lookup; however, that strategy would impose a very high cost on
implementations, requiring a reified lexical environment present at
runtime.)

Christophe


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Oct 14 2012, 7:42 pm
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Sun, 14 Oct 2012 23:42:36 +0000 (UTC)
Local: Sun, Oct 14 2012 7:42 pm
Subject: Re: (newbie?) Question about map car and funcall
On 2012-10-14, Christophe Rhodes <cs...@cantab.net> wrote:

From a lambda expression that is just a datum? No way.

> (By strict analogy with the function position, you might want lexical
> lookup; however, that strategy would impose a very high cost on
> implementations, requiring a reified lexical environment present at
> runtime.)

Worse than that, it means that (funcall x a b c) allows the list-datum stored
in x to make lexical references, which seems like nonsense. (Unless perhaps
your surname is Majorinc.)

funcall is a function which knows nothing about the caller's lexical
environment.  If it did, it would be problematic. If someone wraps funcall, the
wrapper doesn't behave like funcall. (Unless we introduce an &environment
parameter to functions.)

Anyway, a closure should capture in the environment where it is made.
Arguably, the closure in this case is made inside funcall, not inside the
caller, where it is still just a piece of source code. So should it not capture
funcall's internal variables? :)


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Margolin  
View profile  
 More options Oct 14 2012, 10:17 pm
Newsgroups: comp.lang.lisp
From: Barry Margolin <bar...@alum.mit.edu>
Date: Sun, 14 Oct 2012 22:17:15 -0400
Local: Sun, Oct 14 2012 10:17 pm
Subject: Re: (newbie?) Question about map car and funcall
In article <20121014094616...@kylheku.com>,
 Kaz Kylheku <k...@kylheku.com> wrote:

> Adding another case doesn't really hurt anything, since funcall already
> has to check whether the input is a symbol or function.

>  (defun funcall (fspec &rest args)
>    (typecase (fspec)
>      ;; fspec is a function object: just apply args to it
>      (function (system::builtin-apply fspec args))
>      ;; fspec is a symbol: try to retrieve the associated function and apply
>      (symbol (system::builtin-apply (symbol-function func-or-name) args))
>      ;; fspec might be a nonempty list, possibly a lambda form
>      (cons (system::builtin-apply (coerce fspec 'function) args))))

> I would argue for that to be supported in a new revision of Common Lisp.

CLtL1 allowed this, but it was intentionally removed in ANSI Common
Lisp.  Why would we put it back?

Allowing FUNCALL and APPLY to take a symbol is useful: you can put the
name of a function in a data structure, and if you redefine the function
it will use the updated definition.

What do you gain by being able to FUNCALL/APPLY a lambda expression,
that you can't do just as well by passing the function that you get by
actually evaluating the lambda expression?

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Kaz Kylheku  
View profile  
 More options Oct 15 2012, 2:36 am
Newsgroups: comp.lang.lisp
From: Kaz Kylheku <k...@kylheku.com>
Date: Mon, 15 Oct 2012 06:36:31 +0000 (UTC)
Local: Mon, Oct 15 2012 2:36 am
Subject: Re: (newbie?) Question about map car and funcall
On 2012-10-15, Barry Margolin <bar...@alum.mit.edu> wrote:

To create a retro feeling, like wearing bell-bottom jeans.

> Allowing FUNCALL and APPLY to take a symbol is useful: you can put the
> name of a function in a data structure, and if you redefine the function
> it will use the updated definition.
> What do you gain by being able to FUNCALL/APPLY a lambda expression,
> that you can't do just as well by passing the function that you get by
> actually evaluating the lambda expression?

Optimization. If the function is never called, we didn't waste any time
processing the lambda expression.

We also gain pessimization. If the function is called more than once, we can
waste time parsing the lambda more than once, and then we can gloat about how
we don't care because it's the programmer time that is more valuable.

But mostly we gain increased newsgroup silence. Less of "gee, why doesn't this
just work".


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Margolin  
View profile  
 More options Oct 15 2012, 10:38 am
Newsgroups: comp.lang.lisp
From: Barry Margolin <bar...@alum.mit.edu>
Date: Mon, 15 Oct 2012 10:38:07 -0400
Local: Mon, Oct 15 2012 10:38 am
Subject: Re: (newbie?) Question about map car and funcall
In article <20121014232734....@kylheku.com>,
 Kaz Kylheku <k...@kylheku.com> wrote:

The processing all takes place at compile time, so it shouldn't be
significant.

> But mostly we gain increased newsgroup silence. Less of "gee, why doesn't
> this
> just work".

I knew there was something we were leaving out of our design criteria in
X3J13. :)

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Pascal J. Bourguignon  
View profile  
 More options Oct 19 2012, 8:24 am
Newsgroups: comp.lang.lisp
From: Pascal J. Bourguignon <p...@informatimago.com>
Date: 19 Oct 2012 12:24:45 GMT
Local: Fri, Oct 19 2012 8:24 am
Subject: Re: (newbie?) Question about map car and funcall
Nils M Holm <news2...@t3x.org> wrote:

> Luca Antonelli <luke.a...@gmail.com> wrote:
>> (mapcar #'funcall '((lambda (x) (1+ x)) 1-) '(2 5))

>> it raises an error: "FUNCALL: argument (LAMBDA (X) (1+ X)) is not
>> a function."

> That's because (LAMBDA (X) (1+ X)) is a function, but
>               '(LAMBDA (X) (1+ X)) is a list.

Let me argue that this formulation is the cause of this  newbies problem.

(LAMBDA (X) (1+ X)) is NOT a function, but a list. (that is what funcall is
saying above!)
'(LAMBDA (X) (1+ X)) is indeed a list, of two elements: cl:quote and
(LAMBDA (X) (1+ X)).

WHEN Evaluated,
(LAMBDA (X) (1+ X)) RETURNS a function, and
'(LAMBDA (X) (1+ X)) RETURNS a list.

 And that is the whole point of the OP question: quote prevented the
evaluation of its argument containing the lambda expression, therefore it
was left as a list, not evaluated to a function, hence the funcall
complain.

> You may try

> (mapcar #'funcall `(,(lambda (x) (1+ x)) 1-) '(2 5))

> instead. (Note: backquote instead of quote.)

--
__Pascal J. Bourguignon__

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Nils M Holm  
View profile  
 More options Oct 19 2012, 11:08 am
Newsgroups: comp.lang.lisp
From: Nils M Holm <news2...@t3x.org>
Date: 19 Oct 2012 15:08:19 GMT
Local: Fri, Oct 19 2012 11:08 am
Subject: Re: (newbie?) Question about map car and funcall
Pascal J. Bourguignon <p...@informatimago.com> wrote:

> Nils M Holm <news2...@t3x.org> wrote:
> > That's because (LAMBDA (X) (1+ X)) is a function, but
> >               '(LAMBDA (X) (1+ X)) is a list.

> Let me argue that this formulation is the cause of this  newbies problem.

> (LAMBDA (X) (1+ X)) is NOT a function, but a list. (that is what funcall is
> saying above!)
> '(LAMBDA (X) (1+ X)) is indeed a list, of two elements: cl:quote and
> (LAMBDA (X) (1+ X)).

> WHEN Evaluated,
> (LAMBDA (X) (1+ X)) RETURNS a function, and
> '(LAMBDA (X) (1+ X)) RETURNS a list.

Good point! I should have written

That's because (LAMBDA (X) (1+ X)) evaluates to a function, but
              '(LAMBDA (X) (1+ X)) evaluates to a list.

--
Nils M Holm  < n m h @ t 3 x . o r g >  www.t3x.org


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »