Frage

Ich habe einige Mühe, das Verhalten des folgenden Verständnis Scheme Programm:

(define c
  (dynamic-wind
    (lambda () (display 'IN)(newline))
    (lambda () (call/cc (lambda (k)
                     (display 'X)(newline)
                     k)))
    (lambda () (display 'OUT)(newline))))

Wie ich verstehe, c wird die continution Recht vor erstellt gebunden "(Anzeige‚X)".

Aber c verwenden scheint sich zu ändern! Die Definition oben druckt (wie erwartet) IN, X und OUT:

IN
X
OUT

Und es ist ein Verfahren:

#;2> c
#<procedure (a9869 . results1678)>

Nun, ich würde erwarten, dass, wenn es wieder genannt wird, X gedruckt werden würde, und es ist nicht!

#;3> (c)
IN
OUT

Und jetzt c ist kein Verfahren mehr, und eine zweite Invokation von c wird nicht funktionieren!

#;4> c    ;; the REPL doesn't answer this, so there are no values returned
#;5> (c)

Error: call of non-procedure: #<unspecified>

        Call history:

        <syntax>            (c)
        <eval>              (c)    <--

Ich habe erwartet, dass jede Invokation bis (c) würde das Gleiche tun - IN, X drucken, und OUT. Was bin ich?

War es hilfreich?

Lösung

Ausführen dieses in Racket ist ein wenig hilfreich:

-> (define c
     (dynamic-wind
       (lambda () (display 'IN)(newline))
       (lambda () (call/cc (lambda (k)
                             (display 'X)(newline)
                             k)))
       (lambda () (display 'OUT)(newline))))
IN
X
OUT
-> c
#<continuation>
-> (c)
IN
OUT
define-values: context (defining "c") expected 1 value, received 0 values
-> (c 99)
IN
OUT
-> c
99

Beachten Sie insbesondere, dass c auf eine Fortsetzung Wert gebunden wird - weil Ihr Ausdruck kehrt als Wert k. Und k selbst ist die Fortsetzung des Wertausdruck, was bedeutet, dass diese Fortsetzung der eine wartet einen Wert zu erhalten, c gebunden zu sein. So Aufrufen es einen einzigen Wert erfordert, als Racket erfordert, was dazu beiträgt, die Klärung, was hier geschieht (MIT Schema scheint still zu behandeln es als nicht spezifiziert). Wie auch immer, auf 99 Mittel, um diese Fortsetzung der Anwendung, dass der Rückgabewert aus diesem Ausdruck ist 99 - so dass Sie wieder in den Kontext springen (Druck IN) und zurück 99 zu c gebunden werden, und drucken OUT auf Ihr Weg aus. Sie haben jetzt geändert c, dass 99 statt zu haben, so dass Sie es nicht ein drittes Mal aufrufen können.

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