2010-06-28 29 views
6

Ich habe mich entschieden, heute LISP zu lernen, und habe damit ein bisschen herumgespielt. Ich schrieb eine einfache Babyfunktion, nur um mein Verständnis zu testen, und verstehe jetzt, dass mein Verständnis nicht so viel versteht, wie ich es verstanden habe. : DEinfache LISP-Funktion funktioniert nicht

Wie auch immer, hier ist die Funktion. Die Idee ist, dass, wenn es aufgerufen wird, z.B. (esexp base x) sollte die Wertbasis^x zurückgeben. So (esexp 3 4) = 3^4 = 81.

(ich bin mit der CMU Implementierung von Common Lisp, wenn es ankommt.)

(defun esexp (base x) 
    (if (= x 0) 
     1 
     (if (< x 0) 
      (/ esexp (base (+ x 1)) base) 
      (* esexp (base (+ x 1)) base)))) 

Das funktioniert nicht. Ich bekomme Fehler, die aussehen (Warnung: Diese Variable ist undefiniert: SLBEXP) und (Fehler in KERNEL :: UNBOUND-SYMBOL-ERROR-HANDLER: die Variable SLBEXP ist nicht gebunden.) So. Was mache ich falsch? UND würde es eine bessere (oder mehr LISP-ish-Weise) geben, diese Funktion zu schreiben?

ETA

Corrected Code:

(defun esexp (base x) 
    (if (= x 0) 
     1 
     (if (< x 0) 
      (/ (esexp base (+ x 1)) base) 
      (* (esexp base (- x 1)) base)))) 

Antwort

11

esexp(base (+ x 1))

sollte

sein

(esexp base (+ x 1))

esexp eine Funktion wie + ist. Die Syntax zum Aufrufen einer Funktion lautet

(function-name arg1 arg2 ...) 
+0

Ah duh. Vielen Dank. – Asker

0

Nur eine Anmerkung über den Code. Ich glaube, es sollte

sein
(defun esexp (base x) 
     (if (= x 0) 
       1 
       (if (< x 0) 
         (/ (esexp(base (+ x 1)) base)) 
         (* (esexp(base (- x 1)) base)))) 

Andernfalls wird die Funktion nie beendet. (Sie hatte (* (esexp(base (+ x 1)) base)))))

+0

Auch danke. Das war ein Fehler in der Transkription. – Asker

5

Die technische Erklärung des Fehlers: der Compiler wurde Parsen der Code:

(/ esexp(base (+ x 1)) base) 

wie folgt aus:

(/ esexp (base (+ x 1)) base) 

die sagt:

  • zuerst , addiere 1 zum Parameter x
  • rufen Sie dann eine Funktion namens base mit dem obigen Ergebnis auf.
  • teilen Sie den Wert einer Variablen genannt esexp durch das obige Ergebnis.
  • dann teilen Sie das Ergebnis durch den Parameter base. (Der Divisionsoperator in Common Lisp kann mehr als zwei Argumente haben.)

Sie sehen den Trick? Wenn ein Wort als erstes Element in einem S-Ausdruck angezeigt wird (und dieser S-Ausdruck nicht in Anführungszeichen steht), wird es normalerweise als Name einer Funktion behandelt, die Sie aufrufen möchten. Andernfalls wird es als Name einer Variablen behandelt, deren Wert Sie abrufen möchten.Ferner kann in Common Lisp ein Symbol wie esexp gleichzeitig an einen Wert Wert und einen Wert gebunden werden; Kontext oder spezielle Ausdrücke wie #'esexp (was die Funktion bedeutet) werden verwendet, um herauszufinden, welche Sie meinen.

Die Compiler Ihnen wurde zu sagen, dass, obwohl esexp auf eine Funktion mit defun Aussage gebunden war, hatte es noch nicht zu einem Variable Wert gebunden worden ist, und daher nicht als solche verwendet werden könnte. Daher der Fehler.

Verwandte Themen