2016-10-24 3 views
2

Ich habe vor kurzem mit etwas Lisp beschäftigt, ich schreibe eine Funktion, die Kombinationen von Elementen zurückgibt. Es funktioniert gut, aber es wirft mich immer noch eine Warnung Fehler> Argument Y ist keine Zahl: NILlisp error handling - überprüfen, ob Variable

mein 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)) 

Da ich ein Anfänger in diesem bin, ich glaube, ich habe einige vielleicht verpasst Fehlerbehandlung irgendwo, aber Schleim wirft mich auf diesen Fehler Bildschirm ist wirklich nervig!

Danke für jede Hilfe.

Antwort

7

Bitte verwenden Sie Standardformatierung und Benennung:

Wenn Sie die Alternative in einer if nicht benötigen, verwenden 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)) 

Sie tun nicht brauchen return oder return-from; Ein Funktionskörper gibt die Werte des letzten Formulars zurück. Ich denke, dass Sie Ihre get-diff verwenden möchten:

(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)) 

Der Fehler ist, dass Looping to das Ende enthält; Sie wollen 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)) 

Allerdings müssen Sie die Indizes überhaupt nicht benötigen, so können Sie einfach Schleife über die Liste:

(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)) 

können wir jetzt vielleicht besser sehen, dass alle nil s in lista wäre auch ein Problem in der äußeren Schleife sein:

(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)) 
+0

Darn, danke für die ausführliche Antwort, das hilft sicherlich mit meinem Lisp! –

+0

Es tut mir leid, wieder zu schreiben, aber wenn ich versuche, die Unterschiede zu sammeln, gibt der Befehl collect keine Liste aus. Was könnte hier falsch sein? –

+0

@sdgawerzswer vielleicht eine neue Frage stellen, mit dem aktualisierten Code und dem neuen Problem? –

3

Ihr Fehler ist, dass (loop for k from 0 to (list-length lista)) Ihnen k gibt, nicht 0-4. (nth 5 '(1 10 20 25 13)) gibt Ihnen nil und (- 1 nil) den gleichen Fehler. tun nth jedes Mal ist nicht gut. Sie sollten vielleicht stattdessen tun:

(defun distcalc (lista) 
    (loop :for pivot :in lista 
     :do (loop :for base :in lista 
        :if base 
        :do (printo pivot base (abs (- base pivot)))))) 
Verwandte Themen