Помогите с динамическим ветром и звоните / сс - PullRequest
4 голосов
/ 13 июня 2010

У меня возникли проблемы с пониманием поведения следующей программы Scheme:

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

Как я понимаю, c будет связан с продолжением, созданным непосредственно перед "(отобразить 'X)".

Но использование c, кажется, меняет себя!Определение выше печатает (как я и ожидал) IN, X и OUT:

IN
X
OUT

И это процедура:

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

Теперь я ожидал бы, что когда он вызывается снова, X будет напечатан, а это не так!

#;3> (c)
IN
OUT

А теперь c больше не процедура, и второе обращение к c не будет работать!

#;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)    <--

Iожидал, что каждый вызов (c) будет делать то же самое - печатать IN, X и OUT.Чего мне не хватает?

1 Ответ

8 голосов
/ 13 июня 2010

Выполнение этого в Racket немного более полезно:

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

Обратите особое внимание, что c привязывается к значению продолжения - потому что ваше выражение возвращает k в качестве значения. И k сам по себе является продолжением выражения значения, что означает, что это продолжение ожидает получения значения, которое будет привязано к c. Поэтому для его вызова требуется одно значение, как того требует Racket, что помогает прояснить, что здесь происходит (схема MIT, похоже, молча рассматривает его как неопределенное). В любом случае, применение этого продолжения к 99 означает, что возвращаемое значение из этого выражения равно 99 - поэтому вы возвращаетесь обратно в контекст (печатая IN) и возвращаете 99 , чтобы быть привязанными к c, и напечатайте OUT на выходе. Теперь вы изменили c, чтобы вместо него было 99, поэтому вы не можете вызвать его в третий раз.

...