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.
On Sunday, October 14, 2012 9:38:11 AM UTC-4, 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
> 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.
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:
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:
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.
> 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
> 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:
> 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:
> 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.
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!"
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.)
>> 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?
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? :)
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 ***
> 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?
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".
> On 2012-10-15, Barry Margolin <bar...@alum.mit.edu> wrote:
> > 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?
> 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.
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 ***
>> 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.
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