delta
delta

Reputation: 3818

how to deal with `&rest` args in common lisp

I am new to common lisp, when I see &rest in function arguments declaration, I thought it is similar to *args in ruby. And I started to write a function sumit to do the same thing as +.

(defun sumit (&rest args)
  (if (null args)
      0
      (+ (car args) (sumit (cdr args)))))

but when I invoke (sumit 1 2 3) it gets segmentation fault, the recursion never ends. (sumit) works though.

So my suspect is (null args) part, but after changing something like (eql nil args) or something similar does not work.

So what is the right way to decompose &rest args? What is the right way to check nil?

Upvotes: 3

Views: 634

Answers (1)

sds
sds

Reputation: 60064

(sumit (cdr args)) calls sumit on a single argument - a list. You need to use apply:

(defun sumit (&rest args)
  (if args
      (+ (car args) (apply #'sumit (cdr args)))
      0))

Notes:

  1. This implementation is not tail-recursive (while ANSI CL does not require tail call optimization, many implementations do provide it).
  2. Take a look at call-arguments-limit and lambda-parameters-limit.
  3. To sum elements of a list one can use (apply #'+ list-of-numbers), but, due to the above two variables, (reduce #'+ list-of-numbers) is a far better approach.

Upvotes: 3

Related Questions