(defun suma (L)
(setq var 0)
(do
((i 0 (+ i 1)))
((= i (length L)))
(+ var (nth i L)))
var)
Why does it always returns 0?
Shouldn't it return sum of list L?
(defun suma (L)
(setq var 0)
(do
((i 0 (+ i 1)))
((= i (length L)))
(+ var (nth i L)))
var)
Why does it always returns 0?
Shouldn't it return sum of list L?
+
does not modify its arguments, so, since you never modifyvar
, its initial value of 0 is returned.You need to replace
(+ var (nth i L))
with(incf var (nth i L))
, of, equivalently,(setq var (+ var (nth i L)))
.See
incf
.Note that you should bind
var
withlet
instead of making it global withsetq
.Most importantly, note that your algorithm is quadratic in the length of the list argument (because
nth
scans your list every time from the start).Here are some better implementations:
Here is a bad implementation:
The problem with
sum-4
is that it will fail if the length of the supplied list is larger thancall-arguments-limit
.I thought this would be a comment for the full learning experience, but I was not able to put code in the comment.
There is a way to do sums without modifying any argument, and that is by doing it recursively:
This version can be tail call optimized by the compiler, and as fast as a loop:
What you are trying to do could be done with
do
like this:But we don't usually do anything in
do
s body, so it's like this then:But
nth
andlength
are slow, so better do it this way:This one is without the
*
indo
, and returns 0 on empty list:But my favorite is the
reduce
version from @sds which also can return 0 on empty list with :initial-value 0EDIT: recsum2 did not return anything, so it needed a fix.