Frage

Das folgende Verfahren ist in beiden Schemata R6RS und Racket gilt:

;; create a list of all the numbers from 1 to n
(define (make-nums n)
  (do [(x n (- x 1)) (lst (list) (cons x lst))]
    ((= x 0)
     lst)))

habe ich es für beide R6RS und Schläger getestet und es funktioniert einwandfrei, aber ich weiß nur, dass sicher für DrRacket.

Meine Frage ist, wenn es ist garantiert , dass der Schritt Ausdrücke ((- x 1) und (cons x lst) in diesem Fall) wird in der Reihenfolge ausgewertet werden. Wenn es nicht garantiert ist, dann ist mein Verfahren ist nicht sehr stabil.

Ich habe nichts sehen dies in den Standards für die beiden Sprachen angibt, aber ich frage hier, weil, wenn ich es getestet, um evaulated wurde.

War es hilfreich?

Lösung

Sie sind garantiert im Allgemeinen nicht, um zu bewerten, aber das Ergebnis wird immer noch die gleiche sein. Dies ist, weil es keine Nebenwirkungen sind hier -. Die Schleife nicht x oder lst ändern, es erneut bindet sie nur auf neue Werte, so dass die Reihenfolge, in der die beiden Schritten Ausdrücke ausgewertet werden, ist irrelevant

Um dies zu sehen, mit einer saubereren aussehenden Version des Codes zu starten:

(define (make-nums n)
  (do ([x n (- x 1)] [lst null (cons x lst)])
      [(zero? x) lst]))

übersetzen zu einem benannten-let:

(define (make-nums n)
  (let loop ([x n] [lst null])
    (if (zero? x)
      lst
      (loop (- x 1) (cons x lst)))))

und übersetzen weiter, dass auf eine Hilfsfunktion (was ein Named-let wirklich ist):

(define (make-nums n)
  (define (loop x lst)
    (if (zero? x)
      lst
      (loop (- x 1) (cons x lst))))
  (loop n null))

Es sollte nun klar sein, dass die Reihenfolge der beiden Ausdrücke in der rekursiven loop Aufruf der Auswertung macht es nicht etwas anderes tun.

Schließlich ist zu beachten, dass in Racket Auswertung ist garantiert von links nach rechts zu. Dies ist wichtig, wenn es Nebenwirkungen - Racket bevorzugt ein vorhersagbares Verhalten, während andere sie widersprechen, behaupten, dass dies führt Menschen zu Code, der implizit auf diesem angewiesen ist. Ein gemeinsames kleines Beispiel, das zeigt der Unterschied ist:

(list (read-line) (read-line))

, die in Racket ist garantiert eine Liste der ersten Zeile Lese zurückzukehren, und dann die zweite. Andere Implementierungen können die beiden Linien in einer anderen Reihenfolge zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top