【问题标题】:How to write analyzer/evaluator functions like `eval-if` in CPS form?如何以 CPS 形式编写分析器/评估器函数,如“eval-if”?
【发布时间】:2012-02-15 05:37:25
【问题描述】:

我正在尝试基于 SICP 中的元循环评估器编写一个玩具 python Scheme 解释器。由于 python 只支持有限深度的调用栈,所以我必须消除尾调用。我阅读了蹦床并用它实现了解析器。

但我不知道如何以连续传递风格编写分析器/评估器函数以将它们与蹦床一起使用。比如eval-if函数:

(define (eval-if expr env)
    (if (is-true? (eval (if-predicate expr) env))
        (eval (if-consequent expr) env)
        (eval (if-alternate expr) env)))

在python中:

def eval_if(expr, env):
    if is_true(eval(if_predicate(expr), env)):
        return eval(if_consequent(expr), env)
    else:
        return eval(if_alternate(expr), env)

当我想检查谓词是否为真时,我必须在其上调用新一轮的eval。这种CPS形式的递归调用应该怎么写?

【问题讨论】:

    标签: scheme sicp continuation-passing trampolines


    【解决方案1】:

    在scheme/Racket中,你可以将这个函数的CPSed形式写成:

    ;; evaluate an 'if':
    (define (eval-if expr env k)
      (eval (if-predicate expr) env
            (lambda (testval)
              (if (is-true? testval)
                  (eval (if-consequent expr) env k)
                  (eval (if-alternate expr) env k)))))
    

    请注意,这假设您的“eval”也是用 CPS 编写的。在 Python 中,如果 Guido 允许,您大概可以使用“lambda”;否则,我相信您可以为此定义一个内部函数。

    【讨论】:

    • 谢谢:) 我跟着this paper 实现了pogo_stick 蹦床调度程序。我在用 python 编写这些函数时遇到了困难,因为它将包含很多内部函数。如果我考虑将分析器与eval 分开,情况会更糟。要评估(set! var expr),应首先分析expr,然后执行,这两个步骤都将包含在pogo_stick调度程序中。也许我应该考虑其他方法来优化尾调用?抱歉有点含糊。
    • 是的。您遵循的计划类似于我对 PyScheme 实施所做的计划 (hkn.eecs.berkeley.edu/~dyoo/python/pyscheme) 祝您实施顺利!
    • @dyoo,我已经阅读了您的一些 PyScheme 代码,当我感到困惑时,它对我很有帮助:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2018-10-18
    • 2017-01-25
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    相关资源
    最近更新 更多