执行以下call/cc表达式 [英] Execute the following call/cc expression

查看:95
本文介绍了执行以下call/cc表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用球拍,下面的简单代码得到了结果4:

I use racket and I got the result 4 for following simple code:

(let/cc done
  ((let/cc esc
     (done (+ 1 (let/cc k
                  (esc k)))))
   3))

我将逐步执行此代码.

首先,我将第一个let/cc更改为call/cc的形式,如下所示:

First, I changed the first let/cc into the form of call/cc like below:

(call/cc (λ (done)
           ((let/cc esc
              (done (+ 1 (let/cc k
                           (esc k)))))
            3)))

当然,这也会产生4.

第二,因为我在call/cc的机制="nofollow noreferrer">互联网,其中说call/cc执行以下4个步骤:

Second, since I found the mechanism of call/cc in the internet which says call/cc do following 4 steps:

  1. 捕获当前的延续.
  2. 构造一个具有一个参数的函数C,并使用该参数值应用当前的延续.
  3. 将此函数作为参数传递给expr ---即,它调用(expr C).
  4. 返回评估(expr C)的结果,除非expr调用C,在这种情况下,将返回传递给C的值.
  1. Captures the current continuation.
  2. Constructs a function C that takes one argument, and applies the current continuation with that argument value.
  3. Passes this function as an argument to expr --- i.e., it invokes (expr C).
  4. Returns the result of evaluating (expr C), unless expr calls C, in which case the value that is passed to C is returned.

因此,对于第一个call/cc,我按照上述步骤操作:

Thus, I followed above steps for the first call/cc like:

  1. 当前延续是一种身份.
  2. C是指(λ (x) x).
  3. 由于expr(λ (done) ((let/cc esc (done (+ 1 (let/cc k (esc k))))) 3)),所以(expr C)是:

  1. Current continuation is an identity.
  2. C refers (λ (x) x).
  3. Since expr is (λ (done) ((let/cc esc (done (+ 1 (let/cc k (esc k))))) 3)), (expr C) is:

((λ (done)
   ((let/cc esc
      (done (+ 1 (let/cc k
                   (esc k)))))
    3))
 (λ (x) x))

  • 要返回上述代码的结果值,我在球拍中执行以上操作.

  • To return the result value of above code, I execute above in racket.

    但是,上面的代码(由我修改)未执行并产生错误:

    But, above code (modified by me) is not executed and produces an error:

    > application: not a procedure;
    >
    > expected a procedure that can be applied to arguments
    >
    >  given: 4
    >
    >  arguments...:
    >
    >   3
    

    请我做错了.我混淆了延续的概念.谢谢.

    Please what I did wrong. I'm confusing the concept of continuation. Thanks.

    推荐答案

    延续不仅是闭包(函数).他们还执行 jump 到其在代码中的定义位置.您必须完全执行CPS转换,才能尝试在Scheme解释器中评估结果表达式.该表达式将仅包含lambda,并且不包含任何延续(在call/cc (1) 的意义上).

    Continuations are not just closures (functions). They also perform a jump to their defining location in code. You have to perform the CPS transformation in full to try evaluating the resulting expression in Scheme interpreter. That expression will only contain lambdas and no continuations (in the sense of call/cc (1)).

    您尝试过的表达式将它们混合在一起-将done定义为简单的lambda定义的函数,但仍在嵌套上下文中用作延续.

    The expression that you tried mixes them both - it defines done as simple lambda-defined function, but it is still used in the nested context as a continuation.

    (1)(另一个引起混淆的原因是以连续传递方式将函数参数称为"continuations".它们是 not 真正的"延续;它们是在这种或那种情况下被调用"的简单函数,因此通俗地说,它们也被称为延续",尽管意外情况"甚至处理者"可能会更好.)

    (1) (another source of confusion is calling the function arguments in the continuation-passing style "continuations". they are not "true" continuations; they are simple functions "to be called" in this or that eventuality, so colloquially they are also referred to as "continuations" although "contingencies" or even "handlers" could be better.)

    另请参见呼叫/cc代码翻译的另一个示例.

    按照这种方法,将您的Scheme代码转换为Common Lisp,我们得到:

    Following that approach, translating your Scheme code into Common Lisp, we get:

    ;; (let/cc done
    ;;   ((let/cc esc
    ;;      (done (+ 1 (let/cc k
    ;;                   (esc k)))))
    ;;    3)) 
    (prog  (retval done arg1 func esc arg2 k arg3 arg4)
        (setq done (lambda (x) (setq retval x) (go DONE)))    ; 3
         (setq arg1 3)                                        ; 5
          (setq esc  (lambda (x) (setq func x) (go ESC)))     ; 8
           (setq arg3 1)                                      ; 10
            (setq k  (lambda (x) (setq arg4 x) (go K)))       ; 12
            (setq arg4 (funcall esc k))                       ; 13
      K                                                       ; 11  continuation K
           (setq arg2 (+ arg3 arg4))                          ; 9
          (setq func (funcall done arg2))                     ; 7
      ESC                                                     ; 6   continuation ESC
         (setq retval (funcall func arg1))                    ; 4
      DONE                                                    ; 2   continuation DONE
        (return retval))                                      ; 1
    

    实际上是返回4 (在翻译过程中,代码行按编写时的顺序编号).

    which indeed returns 4 (the lines of code are numbered in order as they are written, during the translation).

    这篇关于执行以下call/cc表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆