Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lisp error handling - check if variable nil

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.

like image 654
sdgaw erzswer Avatar asked Mar 24 '26 15:03

sdgaw erzswer


1 Answers

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 nils 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))
like image 67
Svante Avatar answered Mar 26 '26 14:03

Svante



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!