Reputation: 2382
I've been recently dealing with some lisp, I am writing a function, which returns combinations of elements. It works nice, but it still throws me a warning error > Argument Y is not a NUMBER: NIL
my CODE:
(defun printo (x y z)
(if (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)
))
(defun getDiff (x y)
(return-from getDiff (abs (- x y))))
(defun distcalc (lista)
(loop for k from 0 to (list-length lista)
do (loop for j from 0 to (list-length lista)
do (let ((pivot (nth k lista))(base (nth j lista)))
(if (nth j lista)(printo pivot base (abs (- base pivot))
))
))
))
(distcalc '(1 10 20 25 13))
As I am a beginner in this, I think I might have missed some error handling somewhere, but slime throwing me on that error screen is really annoying!
Thanks for any help.
Upvotes: 2
Views: 762
Reputation: 51501
Please use standard formatting and naming:
(defun printo (x y z)
(if (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)))
(defun get-diff (x y)
(return-from get-diff (abs (- x y))))
(defun distcalc (lista)
(loop for k from 0 to (list-length lista)
do (loop for j from 0 to (list-length lista)
do (let ((pivot (nth k lista))
(base (nth j lista)))
(if (nth j lista)
(printo pivot base (abs (- base pivot))))))))
(distcalc '(1 10 20 25 13))
If you do not need the alternative in an if
, use when
:
(defun printo (x y z)
(when (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)))
(defun get-diff (x y)
(return-from get-diff (abs (- x y))))
(defun distcalc (lista)
(loop for k from 0 to (list-length lista)
do (loop for j from 0 to (list-length lista)
do (let ((pivot (nth k lista))
(base (nth j lista)))
(when (nth j lista)
(printo pivot base (abs (- base pivot))))))))
(distcalc '(1 10 20 25 13))
You do not need to return
or return-from
; a function body returns the
values of the last form. I guess that you want to use your get-diff
:
(defun printo (x y z)
(when (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)))
(defun get-diff (x y)
(abs (- x y)))
(defun distcalc (lista)
(loop for k from 0 to (list-length lista)
do (loop for j from 0 to (list-length lista)
do (let ((pivot (nth k lista))
(base (nth j lista)))
(when (nth j lista)
(printo pivot base (get-diff base pivot)))))))
(distcalc '(1 10 20 25 13))
The error is that looping to
includes the end; you want below
:
(defun printo (x y z)
(when (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)))
(defun get-diff (x y)
(abs (- x y)))
(defun distcalc (lista)
(loop for k from 0 below (list-length lista)
do (loop for j from 0 below (list-length lista)
do (let ((pivot (nth k lista))
(base (nth j lista)))
(when (nth j lista)
(printo pivot base (get-diff base pivot)))))))
(distcalc '(1 10 20 25 13))
However, you do not need the indices at all, so you can simply loop over the list:
(defun printo (x y z)
(when (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)))
(defun get-diff (x y)
(abs (- x y)))
(defun distcalc (lista)
(loop for pivot in lista
do (loop for base in lista
when base
do (printo pivot base (get-diff base pivot)))))
(distcalc '(1 10 20 25 13))
We can now perhaps better see that any nil
s in lista
would also be a
problem in the outer loop:
(defun printo (x y z)
(when (and x y z)
(format t "~a and ~a difference: ~a ~%" x y z)))
(defun get-diff (x y)
(abs (- x y)))
(defun distcalc (lista)
(loop for pivot in lista
when pivot
do (loop for base in lista
when base
do (printo pivot base (get-diff base pivot)))))
(distcalc '(1 10 20 25 13))
Upvotes: 7
Reputation: 48745
Your error is that (loop for k from 0 to (list-length lista))
will give you k
0-5
, not 0-4
. (nth 5 '(1 10 20 25 13))
will give you nil
and (- 1 nil)
the same error. doing nth
every time is not good. you should perhaps instead do:
(defun distcalc (lista)
(loop :for pivot :in lista
:do (loop :for base :in lista
:if base
:do (printo pivot base (abs (- base pivot))))))
Upvotes: 3