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