gpt4 book ai didi

racket - 有人可以用简单的话解释 call/cc 吗?

转载 作者:行者123 更新时间:2023-12-04 05:12:33 26 4
gpt4 key购买 nike

我正在研究语言 Racket 并试图掌握 call/cc 的实际用途。有人可以用简单的话解释一下并举一两个例子吗?谢谢。

最佳答案

如果你有一个表达式 (+ (* 2 3) (/ 10 2))方案系统不会同时评估所有内容,而是部分评估。 Scheme中没有指定顺序,但让我们想象一下它是从左到右的(我认为Racket总是从左到右):

你做(* 2 3) , 继续计算 (/ 10 2) ,然后 (+ result1 result2) . Scheme 系统可以做到这一点的方法是将您的代码转换为 Continuation passing style在执行之前。上面的表达式变成了这样:

 (lambda (k)
(*& 2
3
(lambda (result1)
(/& 10
2
(lambda (result2)
(+& result1 result2 k))))))

现在,带有 &的程序最后与 Scheme 中的相同,只是它的最后一个参数需要一个延续。其中之一的示例: (define (+& a b k) (k (+ a b))) .所有其他的都是这样完成的,并且被认为是原语。

如果你应用它并通过 displayvalues它将显示或评估为 11。
但是,如果您使用 call/cc你可以覆盖它。想象一下这个变体:

(call/cc (lambda (k) (+ (* 2 3) (/ 10 (if (zero? a) (k +inf.0) a))

在 Scheme 中,除以零时会出现错误,如果发生这种情况,您想取消其余的计算并说结果是无限的。上面的代码就是这样做的,如果 a为零,它不会将前两次计算的结果相加。它实际上充当 GOTO。该代码的 CPS 版本如下所示:

(lambda (k)
(*& 2
3
(lambda (result1)
(zero?& a
(lambda (azero?)
(if azero?
(k +inf.0) ; continuation used here
(/& 10
a
(lambda (result2)
(+& result1 result2 k))))))))) ; and here

那么 call/cc 是什么意思?做?好吧,它可以让您以通常的方式编写代码,而不是像计算机如何进行实际计算那样的 CPS,但是您可以通过掌握延续来获得两个世界的最佳结果,这样您就可以像在 CPS 中编写它一样执行相同的操作。

现在,想象一下这个代码块:

(let* ((c 10)
(r (call/cc (lambda (exit) exit))))
(display "Hello\n")
(cond ((zero? c) 'done)
(else (set! c (- c 1))
(r r))))

在这里,您看到我将继续返回为 r .继续是从设置 r 开始的其余计算。 ,然后做 display ...这实际上显示了 11 次“hello\n”,因为当您在底部调用延续时,它会再次执行相同的操作。

就像 eval我确实尝试将其保持在绝对最小值,当我这样做时,我通常这样做是为了从正在进行的计算中中止。例如。

(define (lstadd1 lst)
(call/cc (lambda (exit)
(let loop ((lst lst))
(cond ((pair? lst) (cons (add1 (car lst)) (loop (cdr lst))))
((null? lst) '())
(else (exit #f))))))) ; not proper

(lstadd1 '(1 2 3)) ; ==> (2 3 4)
(lstadd1 '(1 2 . 3)) ; ==> #f

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

关于racket - 有人可以用简单的话解释 call/cc 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22888722/

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