(define d
(append '(a) (call/cc
(lambda (k) (k (append '(b) '(c)))))))
(define e
(append '(a) (append '(b) '(c))))
В чем разница в стеке вызовов между d и e?
(define d
(append '(a) (call/cc
(lambda (k) (k (append '(b) '(c)))))))
(define e
(append '(a) (append '(b) '(c))))
В чем разница в стеке вызовов между d и e?
Вы забыли одно:
(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, он станет '(ab ...), но если вы не предоставите ему список (например, вы напишете 5), он будет использовать продолжение (прекращение) для возврата #f вместо того, чтобы позволить добавить сделать это вещь. Этот пример можно было бы написать без call/cc (сначала выполнив read и if part, но в некоторых случаях альтернативой продолжению является завершение вычислений, о которых вы наполовину знаете, что они будут отброшены.
call/cc похож на goto в других языках и может использоваться для создания исключений, совместной многозадачности, итераций, ++. См. продолжения Мэтта Майта на примере< /а>
(call/cc (lambda (k) (k v)))
=>v
. - person Dan D.   schedule 26.07.2012call/cc
, вам нужно использовать термин вызов дерево, а не стек вызовов. :-) - person soegaard   schedule 26.07.2012