使用eval,R5RS从列表中评估我自己的函数

时间:2018-03-02 12:58:55

标签: scheme lisp r5rs

我遇到了这个问题

e.g。我有

(define (mypow x) (* x x))

我需要从给定列表中评估表达式。 (我正在编写一个模拟器,我在列表中得到一系列命令作为参数)

我已经读过R5RS标准需要包含在函数eval中作为第二个arg(scheme-report-environment 5),但我仍然遇到这个问题。

这适用(使用标准功能):

(eval '(sqrt 5) (scheme-report-environment 5))

但这不是:

(eval '(mypow 5) (scheme-report-environment 5))

它说:

  

../../../../../../ usr / share / racket / collectcts / racket / private / kw.rkt:923:25:mypow:undefined;    不能引用未定义的标识符

尽管在提示返回时简单地调用了mypow:

#<procedure:mypow>

请问有什么建议吗? (顺便说一下,我需要使用R5RS)

1 个答案:

答案 0 :(得分:1)

false返回R5RS Scheme标准中定义的所有绑定,而不是任何用户定义的绑定。这是设计的。您将从不能够使用此作为(scheme-report-environment 5)的第二个参数执行您想要的操作。

该报告提到eval 可选。因此,您无法保证实现具有它,但它将具有(interaction-environment)

的所有绑定

为了完整性,(scheme-report-environment 5)只有语法绑定。例如。 (null-environment 5)有效,但(eval '(lambda (v) "constan) (null-environment 5))不会,因为(eval '(lambda (v) (+ 5 v)) (null-environment 5))不在最终的程序关闭中。

完成任务的其他方法

通常你可以在不使用+的情况下逃脱。几乎所有费用都应该避免eval。在过去的16年里,我曾两次在生产代码中故意使用eval

使用eval代替数据:

thunk

现在假设你有一个你想做的操作列表:

(define todo 
  (lambda () ; a thunk is just a procedure that takes no arguments
    (mypow 5))

(todo) ; ==> result from mypow