Поток управления в программе Scheme с продолжением вызова с током - PullRequest
0 голосов
/ 28 октября 2018

Я новичок в программировании на Схеме и пытаюсь понять поток управления программами, в которых есть вызов с текущим продолжением. Чтобы быть более конкретным, я хочу знать, когда вызывается вызов любого продолжения, где передается управление и что происходит после этого. Было бы очень полезно, если для объяснения рассматривается нижеприведенная программа.

(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

1 Ответ

0 голосов
/ 28 октября 2018

Нет, когда вы делаете (define a (amb)), продолжение f1 не вызывается, потому что оно позади (то есть внутри) a lambda.

Нет, (set! amb-exit (lambda () (f1 'exit))) устанавливает amb-exit налямбда-функция, а затем управление переходит к (m 1), который вызывает продолжение m.Который возвращает 1 из (amb) в (define a (amb)), который, таким образом, устанавливает a в 1.

Когда вы позже наберете (back), он вызывает (amb-exit), который в этот момент вызывает f1 продолжение с (f1 'exit), которое возвращает значение 'exit из формы (call/cc (lambda (f1) ...)).Это значение отбрасывается, и управление переходит в форму (call/cc (lambda (f2) ...)) с аналогичными эффектами.

...