【问题标题】:Why does this expression evaluate to 4 (call/cc)为什么这个表达式的计算结果为 4 (call/cc)
【发布时间】:2020-04-10 01:24:20
【问题描述】:

抱歉,这个简单的延续示例的计算结果为 4,但我不知道为什么:

(call/cc
  (lambda (k)
    (* 5 (k 4)))) 

Chez 方案 9.5.3

【问题讨论】:

    标签: scheme chez-scheme


    【解决方案1】:

    call/cc 让您获得延续传递风格的优势,而无需编写延续传递风格。例如。

    (define (cars lsts)
      (define (cars lsts k)
        (cond ((null? lsts) (k '()))
              ((null? (car lsts)) '())
              (else (cars (cdr lsts)
                          (lambda (r) 
                            (k (cons (caar lsts) r)))))))
      (cars lsts values))
    
    ;; eg
    (cars '())            ; ==> ()
    (cars '((1) (2) (3))) ; ==> (1 2 3)
    (cars '((1) (2) ()))  ; ==> ()
    

    可以这样写:

    (define (cars lsts)
      (call/cc 
       (lambda (bail)
         (define (cars lsts)
           (cond ((null? lsts) '())
                 ((null? (car lsts)) (bail '()))
                 (else (cons (caar lsts) (cars (cdr lsts))))))
         (cars lsts))))
    

    call/cc& 在 CPS 中看起来像这样:

    (define (call/cc& proc k)
      (define (exit& v ignored-k)
        (k v))
      (proc exit& k))
    

    您的简单示例可以很容易地重写为继续传递样式:

    (call/cc& (lambda (k& real-k)
                (k& 4 (lambda (res)
                        (*& 5 res real-k))))
              display)
    

    所以看看ignore-k 被忽略,4 被传递给call/cc& 的延续,我已经把display 放在了4 中,然后在repl 中显示4

    【讨论】:

      【解决方案2】:

      我将通过使用 CPS 编写具有相同语义的代码来向您解释。

      ((lambda (k)
         (k 4
            (lambda (v)
              (* 5 v))))
       (lambda (result stack)
         ;; this continuation will drop the stack
         result))
      

      在调用延续 K 之后,您还使用剩余的堆栈调用它,但堆栈被丢弃。

      如果您考虑到您将拥有的剩余堆栈:

      ((lambda (k)
         (k 4
            (lambda (v)
              (* 5 v))))
       (lambda (result stack)
         ;; this continuation will consider the stacked computation
         (stack result)))
      

      在这种情况下,结果应该是 20。

      但在您的代码语义中,通过调用延续,您丢弃了堆栈,即未完成的计算。

      【讨论】:

        【解决方案3】:

        延续将返回传递给它的值(k 4),所以4是返回值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多