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

Scheme 使用eval,R5RS从列表中评估我自己的函数,scheme,lisp,r5rs,Scheme,Lisp,R5rs,我对此有问题 e、 我有 (define (mypow x) (* x x)) 我需要从给定的列表中计算表达式。(我正在编写一个模拟器,我在列表中得到一系列命令作为参数) 我已经读到R5RS标准需要在函数eval中包含第二个arg(scheme report environment 5),但我仍然对此有问题 这项工作(具有标准功能): 但这并不是: (eval '(mypow 5) (scheme-report-environment 5)) 它说: ../../../../../usr/s

我对此有问题

e、 我有

(define (mypow x) (* x x))
我需要从给定的列表中计算表达式。(我正在编写一个模拟器,我在列表中得到一系列命令作为参数)

我已经读到R5RS标准需要在函数eval中包含第二个arg(scheme report environment 5),但我仍然对此有问题

这项工作(具有标准功能):

但这并不是:

(eval '(mypow 5) (scheme-report-environment 5))
它说:

../../../../../usr/share/racket/collects/racket/private/kw.rkt:923:25:mypow:未定义; 无法引用未定义的标识符

Eventhough只是在提示返回中调用mypow:

#<procedure:mypow>
#
有什么建议吗?(顺便说一句,我需要使用R5RS)

(scheme report environment 5)
返回R5RS方案标准中定义的所有绑定,而不是任何用户定义的绑定。这是故意的。使用此参数作为
eval
的第二个参数,您将永远无法执行所需操作

报告提到了
(交互环境)
,这是可选的。因此,您不能保证实现具有它,但它将具有来自
(scheme report environment 5)

为了完整性起见,有一个
(null环境5)
,它只有语法的绑定。例如,
(eval'(lambda(v)“constan)(空环境5))
起作用,但
(eval'(lambda(v)(+5 v))(空环境5))
不起作用,因为
+
不在结果过程中

完成事情的其他方法

通常,您不必同时使用
eval
就可以逃脱。应该不惜一切代价避免使用
eval
。在过去16年中,我在生产代码中故意使用了两次
eval

使用
thunk
代替数据:

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

(todo) ; ==> result from mypow
现在,假设您有一个要执行的操作列表:

(define ops
  `((inc . ,(lambda (v) (+ v 1)))      ; notice I'm unquoting. 
    (dec . ,(lambda (v) (- v 1)))      ; eg. need the result of the
    (square . ,(lambda (v) (* v v))))) ; evaluation

(define todo '(inc square dec))
(define with 5)

;; not standard, but often present as either fold or foldl
;; if not fetch from SRFI-1 https://srfi.schemers.org/srfi-1/srfi-1.html
(fold (lambda (e a)
         ((cdr (assq e ops)) a))
       with
       todo)
; ==> 35 ((5+1)^2)-1

对这个已经相当精确的答案的一个重要补充是,当使用
(交互环境)
时,您还可以向环境中添加定义,这在使用
(方案报告环境5)
时似乎是不可能的。例如:
(eval'(define x 1)(交互环境))
会将绑定到1的
x
添加到您当前的交互环境中。@KimMens是的,但与
方案报告环境不同
您不能保证
交互环境
作为一个存在。是的,谢谢您在回答中明确提到了这一点
(define ops
  `((inc . ,(lambda (v) (+ v 1)))      ; notice I'm unquoting. 
    (dec . ,(lambda (v) (- v 1)))      ; eg. need the result of the
    (square . ,(lambda (v) (* v v))))) ; evaluation

(define todo '(inc square dec))
(define with 5)

;; not standard, but often present as either fold or foldl
;; if not fetch from SRFI-1 https://srfi.schemers.org/srfi-1/srfi-1.html
(fold (lambda (e a)
         ((cdr (assq e ops)) a))
       with
       todo)
; ==> 35 ((5+1)^2)-1