Using apply
on lists that can be long is a bit dangerous. If the list is longer than call-arguments-limit
, then (apply '+ list)
won't work. Now, call-arguments-limit
is typically pretty big in modern Lisps, but it's allowed to be as small as 50. For more information about this, see:
I think your best bet would be to use reduce '+ list
with a key function that takes each number to itself and each non-number to 0
. (This key function is what abiessu mentioned in a comment.)
(reduce '+ list :key (lambda (x) (if (numberp x) x 0)))
CL-USER> (let ((list '(cheese 12 dog 8 shoe 5)))
(reduce '+ list :key (lambda (x) (if (numberp x) x 0))))
25
CL-USER> (let ((list '()))
(reduce '+ list :key (lambda (x) (if (numberp x) x 0))))
0
Instead of using a more complex key function, you could also use (remove-if-not 'numberp list)
to get rid of the non-numbers (or (remove-if (complement 'numberp) list)
):
CL-USER> (let ((list '(cheese 12 dog 8 shoe 5)))
(reduce '+ (remove-if-not 'numberp list)))
25
CL-USER> (let ((list '()))
(reduce '+ (remove-if-not 'numberp list)))
0