Схема, чем отличается стек вызовов

(define d
  (append '(a) (call/cc
          (lambda (k) (k (append '(b) '(c)))))))

(define e
  (append '(a) (append '(b) '(c))))

В чем разница в стеке вызовов между d и e?


person Community    schedule 25.07.2012    source источник
comment
Поскольку первое можно свести ко второму, они тождественны. Сокращение (call/cc (lambda (k) (k v))) => v.   -  person Dan D.    schedule 26.07.2012
comment
В какой момент вы хотите изучить стек вызовов? Стеки вызовов при выполнении этих двух функций в определенные моменты будут различаться.   -  person Nate C-K    schedule 26.07.2012
comment
Поскольку вы используете call/cc, вам нужно использовать термин вызов дерево, а не стек вызовов. :-)   -  person soegaard    schedule 26.07.2012
comment
Итак, каковы преимущества/недостатки использования одного или другого? Какая разница в дереве? Только что в первой сделана еще одна ветка, отличная от второй?   -  person    schedule 26.07.2012


Ответы (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, он станет '(ab ...), но если вы не предоставите ему список (например, вы напишете 5), он будет использовать продолжение (прекращение) для возврата #f вместо того, чтобы позволить добавить сделать это вещь. Этот пример можно было бы написать без call/cc (сначала выполнив read и if part, но в некоторых случаях альтернативой продолжению является завершение вычислений, о которых вы наполовину знаете, что они будут отброшены.

call/cc похож на goto в других языках и может использоваться для создания исключений, совместной многозадачности, итераций, ++. См. продолжения Мэтта Майта на примере< /а>

person Sylwester    schedule 06.08.2012