Reputation: 11
I am having the following trouble: when trying to use APPLY function with a MAPCAR call, the lambda function passed to APPLY, which contains only one parameter, the list returned by MAPCAR, gives the following error :
*** - EVAL/APPLY: too many arguments given to :LAMBDA
The following code identifies if a heterogenous list has the last atom at any level a numerical atom.
(DEFUN hasLastNumeric (L)
(COND
((NUMBERP L) T)
((ATOM L) NIL)
((LISTP L)
(APPLY #'(LAMBDA (Lst)
(COND ((EQ (LAST Lst) T) T)
(T NIL)))
(MAPCAR 'hasLastNumeric L)))))
(WRITE (hasLastNumeric '(1 2 5)))
Upvotes: 0
Views: 1139
Reputation: 48745
If you call a function eg. (#'(lambda (a b) (+ a b)) 2 3)
there is a requirement that the number of arguments fits the number of provided arguments. When using apply
the requirements are the same so (apply #'(lambda (one) ...) lst)
require that lst
is only one element list like '(a)
, but it cannot be '()
or '(a b)
. The only way to support variable number of arguments you need to use &rest
arguments eg. (apply #'(lambda (&rest lst) ...) '(a b))
Looking at the logic I don't understand it. You want to return t
when you have encountered a list with the last element as a number but also searched list elements on the way and returned early had you found them. It should be possible without the use of last
at each step. eg.
(defun has-a-last-numeric (lst)
(labels ((helper (lst)
(loop :for (e . rest) :on lst
:if (and (null rest) (numberp e))
:do (return-from has-a-last-numeric t)
:if (listp e)
:do (helper e))))
(helper lst)))
Upvotes: 2
Reputation: 139251
You don't need APPLY. Why would you use it? Remember: APPLY calls a function and uses the provided list as the list of arguments.
MAPCAR returns a list.
(let ((foo (mapcar #'1+ '(1 2 3 4))))
(cond ((eql (last foo) ...) ...)
...))
Check also what last
actually returns...
Upvotes: 4