【问题标题】:Transform coroutine in continuation passing style以延续传递方式转换协程
【发布时间】:2018-01-27 21:54:52
【问题描述】:

我有这个协程示例

(define p1
  (lambda (continuation)
    (display "1")
    (newline)
    (p1 (call/cc continuation))))

(define p2
  (lambda (continuation)
  (display "2")
  (newline)
  (p2 (call/cc continuation))))

(p1 p2)

我想在 CPS 中更改它,以便我可以使用 CPS 调用/cc:

(define (call/cc-cps f continuation)
  (define (exit value actual-continuation)
    (continuation value))
  (f exit continuation))

我知道要在 CPS 中转换一个函数,我需要在函数中添加一个延续,但我很困惑,我真的不知道该怎么做。

我认为它看起来像这样:

 (define p1
   (lambda (continuation)
   (display "2")
   (newline)
   (call/cc-cps
     (lambda (continuation actual-continuation)
       continuation) ;; or actual-continuation ?
     (lambda (value)
       (p1 value)))))

(p1 p2)

但这可能是错误的。有人可以帮我理解如何正确地做到这一点吗?

谢谢

【问题讨论】:

    标签: scheme coroutine continuations callcc


    【解决方案1】:

    如果您在 CPS 中执行某项操作,则在每个函数的尾部位置只进行一次计算。这是解释器评估代码的一种方式:

    (define (hyp a b)
      (sqrt (+ (square a) (square b))))
    

    关键是 CPS 会按照需要的顺序进行计算,并且一次不会做超过一件事。这在 CPS 中变为:

    (define (hyp& a b cont)
      (define (cont-square-a sqa)
        (define (cont-square-b sqb)
          (define (cont-sum sum)
            (sqrt& sum cont))          
          (+& sqa sqb cont-sum))        
        (square& b cont-square-b))      
      (square& a cont-square-a))
    

    或者,如果您更喜欢匿名延续:

    (define (hyp& a b cont)      
      (square& a
               (lambda (sqa)
                 (square& b
                          (lambda (sqb)          
                            (+& sqa
                                sqb
                                (lambda (sum)
                                  (sqrt& sum cont))))))))
    

    所有 & 函数只是实际函数的 CPS 版本,因此除了原始函数之外,它们还有一个延续参数。 p1 看起来像这样:

    (define (p1& continuation& cont)
      (define (cont-display-2 undefined-value-1)
        (define (cont-newline undefined-value-2)
          (define (cont-call-cc-continuation& continuation-value)
            (p1& continuation-value cont))
          (call/cc& continuation& cont-call-cc-continuation&))
        (newline& cont-newline))
       (display& "2" cont-display-2))
    

    您可能对Matt Might的文章感兴趣。围绕相关的延续和编译进行掠夺。我还建议观看SICP videos 并尝试解决SICP book 中的练习。到您制作解释器和编译器时,您应该像在公园里散步制作生成器一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      相关资源
      最近更新 更多