Turabs
Turabs

Reputation: 15

Summing a list by using dolist macro

I was trying to sum a list by using dolist macro. But, I couldn't do it. It always returns the last element of the list. Thanks in advance.

(defun sumlist2 (l)
  ;;this function computes total of a list by using dolist macro
  (let ((summ 0))
    (dolist (obj l)
      (setf summ (+ obj)))
    summ))

Upvotes: 1

Views: 495

Answers (4)

Simeon Ikudabo
Simeon Ikudabo

Reputation: 2190

Below I have an example of a function that can work for you, and then will explain your error:

(defun sum-list(lst)
  (let((sum 0))
    (dolist(l lst)
      (setf sum (+ sum l)))
     sum))

Instead of:

(setf sum (+ obj))

We add the sum of the list that we already acquired in the previous iteration to the number in the list that we are currently iterating through:

(sum-list ‘(1 2 3 4 5 6 7))
28

Below we can pass a list of the integers 1-7 which will return a value of 28.

Upvotes: 0

Ehvince
Ehvince

Reputation: 18375

FYI with loop:

(loop for i in '(1 2 3) sum i)
;; 6

also

(reduce #'+ '(1 2 3))

see more: https://lispcookbook.github.io/cl-cookbook/iteration.html#summation

Upvotes: 2

coredump
coredump

Reputation: 38799

The + function in Lisp is immutable, it just computes a new value:

(+)         is zero
(+ x)       is just x
(+ x y ...) is the sum of x, y, etc.

In your code, you setf the local summ variable with each values taken from the list. Eventually, it contains only the last value of the list. If you want to update summ, you need to do:

(setf summ (+ summ obj))

Or, simply:

(incf summ obj)

Upvotes: 5

Renzo
Renzo

Reputation: 27424

In the body of dolist, you do not sum a value to the variable summ, but assign to it the value of the element of the list, since (+ obj) sums obj with no other value and so returns obj itself. In other words, instead of:

(setf summ (+ obj))

you should write:

(setf summ (+ summ obj))

or, even better:

(incf summ obj)

which performs the addition.

Finally note that you can produce a result directly from dolist, like in:

(defun sumlist2 (l)
  ;;this function computes total of a list by using dolist macro
  (let ((summ 0))
    (dolist (obj l summ)
      (incf summ obj))))

Upvotes: 7

Related Questions