Я новичок в программировании на Схеме и пытаюсь понять поток управления программами, в которых есть вызов с текущим продолжением. Чтобы быть более конкретным, я хочу знать, когда вызывается вызов любого продолжения, где передается управление и что происходит после этого. Было бы очень полезно, если для объяснения рассматривается нижеприведенная программа.
(define call/cc call-with-current-continuation)
(define amb-exit '())
(define amb
(lambda ()
(call/cc
(lambda (m)
(call/cc
(lambda (f1)
(set! amb-exit (lambda () (f1 'exit)))
(m 1)))
(call/cc
(lambda (f2)
(set! amb-exit (lambda () (f2 'exit)))
(m 2)))
(call/cc
(lambda (f3)
(set! amb-exit (lambda () (f3 'exit)))
(m 3)))))))
(define back (lambda () (amb-exit)))
Теперь я пытаюсь запустить код таким образом (define a (amb))
, а затем получаю значение в терминале, как это ;Value: a
. Затем в терминале я проверяю значение a
, которое возвращает мне ;Value: 1
. Затем я звоню (back)
Я получаю a
с новым значением ;Value: 2
. Так далее ...
Я знаю, что когда я выполняю (define a (amb)
, продолжение f1
вызывается в выражении (set! amb-exit (lambda () (f1 'exit)))
, которое передает управление обратно на первый внутренний call/cc
, а продолжение f1
возвращает exit
.
Я не могу понять, почему ;Value: a
равен ;Value: 1
вместо значения exit
, которое возвращается f1
?
В момент выполнения этой части (f1 'exit)
управление возвращается к первому внутреннему вызову / cc, отказываясь от чего-либо (в данном случае (m 1)
) после него.
Таким образом, эта часть (m 1)
никогда не должна вызываться, потому что первое внутреннее продолжение, то есть f1
, возвращается с exit
даже до нажатия (m 1)
.
Будем также благодарны за любые полезные комментарии, касающиеся продолжения звонка с током в Схеме.
Примечание: Использование схемы MIT / GNU