为什么下面一句代码在racket的Interactions窗口上运行正常,而在Definitions窗口中运行报错呢?见图
解决方案就是,在定义区的开头,#lang racket
后面加上这个过程定义:
(define ns (make-base-namespace))
然后,在需要使用eval
动态求值的地方,在该表达式里面加上这个过程作为参数:
((eval `+ ns) 2 1)
然后就可以看到结果了~
具体原因如下:
在被调用的时候,
eval
不能看到当前绑定的命名空间,所以可以动态的绑定命名空间来求值。实际上,
eval
总是会绑定到当前命名空间这种东西,而其绑定的命名空间可以用可选的参数current namespace
决定。在交互区,当前命名空间就是交互区用来求值的命名空间,会先导入模块racket;然而在定义区运行模块的时候不是这样。
结果就是,交互区的命名空间一开始就不是空的;而定义区,由于模块是直接运行的,所以命名空间一开始为空。
为此,在定义区需要显式地绑定命名空间到
eval
上,也就是定义的ns
。
所以,实际上在这个时候是不推荐使用eval
的。如果不明白的话,可以看参考资料,我有些东西并没有提到,因为我也不怎么理解……
下面是我写出这个答案参考的内容(实际上就是抄的~)
对表达式求值
错误:define: unbound identifier; also, no #%app syntax transformer is bound in: define
指南15.1.1命名空间