Схема, какая разница в стеке вызовов
(define d
(append '(a) (call/cc
(lambda (k) (k (append '(b) '(c)))))))
(define e
(append '(a) (append '(b) '(c))))
Какая разница в стеке вызовов между d и e?
1 ответ
Вы забыли один:
(define d
(append '(a) (call/cc
(lambda (k) (append '(b) '(c))))))
Ваши примеры и приведенный выше показывает варианты одного и того же кода. Компилятор сведет их к точно таким же выражениям.
Как и в случае с eval, вы не должны использовать call/cc, если можете избежать этого. Представьте, что вы принимаете один из этих списков в качестве ввода от пользователя:
Представьте себе этот пример:
(define d
(call/cc
(lambda (abort)
(append '(a)
'(b)
(let ((c (read)))
(if (list? c)
c
(abort #f)))))))
Здесь, если вы введете список, d станет '(a b ...), но если вы не предоставите ему список (например, вы пишете 5), он будет использовать продолжение (abort), чтобы вернуть #f вместо того, чтобы добавь, сделай это. Этот пример может быть написан без вызова / cc (выполняя read и если сначала часть, но при некоторых обстоятельствах альтернативой продолжению является выполнение вычисления, которое, как вы знаете, на полпути будет отброшено.
call/cc похож на goto в других языках и может использоваться для создания исключений, совместной многозадачности, итераций, ++. См . Продолжения Мэтта Мейта на примере