2013-10-04 11 views
6

In clojure gilt dies:Warum ist kein gültiges wiederkehrendes Ziel?

(loop [a 5] 
    (if (= a 0) 
    "done" 
    (recur (dec a)))) 

Dies ist jedoch nicht:

(let [a 5] 
    (if (= a 0) 
    "done" 
    (recur (dec a)))) 

Also ich frage mich: warum Schleife sind und lassen getrennt, angesichts der Tatsache, dass sie beide (zumindest konzeptionell) lexikalische Bindungen einführen? Das heißt, warum ist Schleife ein wiederkehrendes Ziel, während nicht?

EDIT: ursprünglich geschrieben "Loop-Ziel", die ich bemerkte, ist falsch.

Antwort

5

Betrachten Sie das folgende Beispiel:

(defn pascal-step [v n] 
    (if (pos? n) 
     (let [l (concat v [0]) 
      r (cons 0 v)] 
     (recur (map + l r) (dec n))) 
     v)) 

Diese Funktion berechnet n+m te Zeile von pascal Dreieck gegeben m ten Zeile.

Nun stellen Sie sich vor, dass let ein recur Ziel ist. In diesem Fall kann ich die Funktion pascal-step von let Bindung mit recur Operator nicht rekursiv aufrufen.

Nun wollen wir dieses Beispiel machen ein wenig komplexer:

(defn pascal-line [n] 
    (loop [v [1] 
     i n] 
    (if (pos? i) 
     (let [l (concat v [0]) 
       r (cons 0 v)] 
      (recur (map + l r) (dec i))) 
     v))) 

Jetzt sind wir n ten Zeile eines pascal Dreiecks zu berechnen. Wie Sie sehen können, brauche ich hier sowohl loop als auch let.

Dieses Beispiel ist ziemlich einfach, Sie können also vorschlagen, let Bindung mit (concat v [0]) und (cons 0 v) direkt zu entfernen, aber ich zeige Ihnen nur das Konzept. Es kann komplexere Beispiele geben, bei denen in einem loop unvermeidlich ist.

+1

Ok, ich verstehe Ihren Standpunkt. Warum, warum dann nicht wiederholen, haben eine zusätzliche optionale Arg, die angibt, welches Ziel zu springen? Oder würde das zu sehr in Richtung Goto gehen (und wir alle wissen, was Dijkstra über Gotos gesagt hat)? – jjpe

+4

@jjpe Let ist kein wiederkehrendes Ziel, weil Schleife ist. Wenn let ein wiederkehrendes Ziel wäre, würde loop nicht existieren. Schleife ist genau das Gleiche wie lassen, außer dass es auch als ein wiederkehrendes Ziel fungiert. Siehe http://clojure.org/special_forms#loop –

Verwandte Themen