gpt4 book ai didi

scheme - Scheme 中的 call/cc 与 Python 和 JavaScript 中的 yield 是一回事吗?

转载 作者:行者123 更新时间:2023-12-02 09:18:44 28 4
gpt4 key购买 nike

Scheme 中的 call/cc 与 Python 和 JavaScript 中的 yield 是一回事吗?

我不清楚生成器。在我看来,yield 使语言能够轻松生成迭代器。但我不确定我是否正确。

Scheme中的call/cc有没有和其他语言的yield相关的东西?如果是,它们是同一事物,还是有什么区别?

谢谢!

最佳答案

call/cc 是一种比生成器更通用的语言功能。因此,您可以使用 call/cc 创建生成器,但不能使用生成器创建 call/cc

如果您有一个计算值并在其他地方使用这些值的程序,它基本上是一个步进机。人们可能会认为它是一个程序,每个步骤都有一个函数,其余步骤有一个延续。因此:

(+ (* 3 4) (* 5 6))

可以解释为:

((lambda (k)
(k* 3 4 (lambda (v34)
(k* 5 6 (lambda (v56)
(k+ v34 v56 k)))))
halt)

k 前缀只是表明它是原语的 CPS 版本。因此,他们将最后一个参数称为带有结果的函数。另请注意,在 Scheme 中未定义的计算顺序实际上是在此重写中选择的。在这种美丽的语言中,call/cc 就是这样的:

(define (kcall/cc kfn k)
(kfn (lambda (value ignored-continuation)
(k value))
k))

所以当你这样做的时候:

(+ (* 3 4) (call/cc (lambda (exit) (* 5 (exit 6))))) 
; ==> 18

在引擎盖下发生了这种情况:

((lambda (k)
(k* 3 4 (lambda (v34)
(kcall/cc (lambda (exit k)
(exit 6 (lambda (v6)
(k* 5 v6 k)))
k))))
halt)

通过使用替换,我们可以证明这实际上完全符合预期。由于调用了退出函数,因此从不调用原始延续,因此取消了计算。与 call/cc 相比,它为我们提供了这种看似不明显的延续,这在 CPS 中并不神奇。因此,call/cc 的大部分魔力都在编译阶段。

(define (make-generator procedure)
(define last-return values)
(define last-value #f)
(define (last-continuation _)
(let ((result (procedure yield)))
(last-return result)))

(define (yield value)
(call/cc (lambda (continuation)
(set! last-continuation continuation)
(set! last-value value)
(last-return value))))

(lambda args
(call/cc (lambda (return)
(set! last-return return)
(if (null? args)
(last-continuation last-value)
(apply last-continuation args))))))

(define test
(make-generator
(lambda (collect)
(collect 1)
(collect 5)
(collect 10)
#f)))

(test) ; ==> 1
(test) ; ==> 5
(test) ; ==> 10
(test) ; ==> #f (procedure finished)

一个人可能 make a macro to make the syntax more similar ,但这只是最重要的糖分。

更多例子I love Matt Mights page有很多关于如何使用延续的例子。

关于scheme - Scheme 中的 call/cc 与 Python 和 JavaScript 中的 yield 是一回事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44514890/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com