Reputation: 15
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
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
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
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
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