scheme - 如何在 CPS 中编写 `(if (null?x) (quote ()) (cdr x))`?
问题描述
方案编程语言说
因此,在任何表达式的求值过程中的任何时候,都有一个延续准备完成,或者至少继续,从那个点开始计算。让我们假设
x
具有值(a b c)
。我们可以在评估的过程中隔离六个延续(if (null? x) (quote ()) (cdr x))
——等待的延续
- 的值
(if (null? x) (quote ()) (cdr x))
,- 的值
(null? x)
,- 的值
null?
,- 的值
x
,- 的值
cdr
,和x
(再次) 的价值。的继续
(cdr x)
没有列出,因为它与等待的相同(if (null? x) (quote ()) (cdr x))
。
我想知道如何(if (null? x) (quote ()) (cdr x))
在CPS中编写?
只能在 CPS 中重写过程调用吗?
解决方案
挑战(if (null? x) (quote ()) (cdr x))
在于它真的什么也没做。例如。如果我把它放在一个 R6RS 程序中并运行它,什么都不会发生。因此我建议我们写它:
(display (if (null? x) (quote ()) (cdr x)))
并假设这是除x
已定义之外的整个程序。现在if
需要知道 的值(null? x)
来确定它是结果还是替代。例如。
(null?& x
continuation)
延续需要确定它是否为真并执行以下两个延续之一:
(null?& x
(lambda (xn)
(if& xn
continuation-consequent
continuation-alternative)))
如果xn
为真,则应显示继续'()
,但如果不是,则应显示以下cdr
内容x
:
(null?& x
(lambda (xn) ; 201
(if& xn
(lambda () ; 202
(display& '() halt)
(lambda () ; 203
(cdr& x (lambda (cdrx) ; 204
(display& cdrx halt)))))))
halt
停止程序。现在让我们想象一下我们将其翻译为 Algol,例如。JS。我将切换顺序,以便继续始终是第一个参数。所有的过程都只是得到一个数字 id,所以实现语言根本不需要过程。
const undef = "BaNaNa";
const x = [1, 2, 3]; // change this
const stack = [200];
main:
while (true) {
const cont = stack.pop();
const cont2 = cont < 200 ? stack.pop() : undef;
switch (cont) {
case 1: // null?&
stack.push(stack.pop().length === 0, cont2);
break;
case 2: // display&
console.log(stack.pop());
stack.push(undef, cont2);
break;
case 3: // cdr&
stack.push(stack.pop().splice(1), cont2);
break;
case 4: // if&
const cont3 = stack.pop();
if (stack.pop()) {
stack.push(cont2);
} else {
stack.push(cont3);
}
break;
// continuations
case 200:
stack.push(x, 201, 1);
break;
case 201:
stack.push(203, 202, 4);
break;
case 202:
stack.push([], 1337, 2);
break;
case 203:
stack.push(x, 204, 3);
break;
case 204:
stack.push(1337, 2);
break;
// halt
case 1337:
break main;
}
}
现在我们确实错过了用户指定的过程和闭包约定,这两者都会使这个示例稍微复杂一些。有一些缺失的类型检查一个正确的方案会完成,我使用数组而不是真正的对。
推荐阅读
- python - 如何让 pygame 沿着 2 点之间的线上的所有点绘制?
- java - 如何让我的程序循环浏览 wav 文件列表?
- ios - 如何将 UIImage 发送到 Firestore?
- node.js - 在端口 80 上设置时,pm2 多次重启
- android - Markdown 库不支持 android 中的单个 \n
- python - 无法使用 conda 设置 keras
- javascript - React无法使用选项元素读取未定义的属性“值”
- swift - 如何解决 Swift 编译器错误“错误:总线错误:10”?
- javascript - 使用 Laravel Passport 时难以在 React JS 中显示验证错误
- r - 结合公式和整洁的评估(情节)