Macros Clojure riddle:eval、宏和名称空间
在clojure中,宏赋予程序员巨大的能力<代码>评估也非常强大。两者之间存在一些细微的差别。我希望这个谜语能对这个话题有所启发Macros Clojure riddle:eval、宏和名称空间,macros,clojure,eval,Macros,Clojure,Eval,在clojure中,宏赋予程序员巨大的能力评估也非常强大。两者之间存在一些细微的差别。我希望这个谜语能对这个话题有所启发 (ns hello) (defmacro my-eval [x] `~(read-string x)) (defn hello[] "Hello") (defn run-stuff [] (println (hello)) (println (my-eval "(hello)")) (println (eval (read-string "(hello)"))))
(ns hello)
(defmacro my-eval [x] `~(read-string x))
(defn hello[] "Hello")
(defn run-stuff []
(println (hello))
(println (my-eval "(hello)"))
(println (eval (read-string "(hello)"))))
(ns main)
(try (hello/run-stuff)
(catch Exception e (println e)))
在run stuff
正文中的3条语句中,哪一条会导致异常,为什么其他语句不会
在对这个美丽的问题进行调查之后,我得出了下面的谜语。感谢@Matthias Benkard的澄清(println(hello))
和(println(my eval)(hello)”)
是完全相同的语句——唯一的区别是会让编辑更加困惑<代码>我的评估与真实的评估
不可比。不同之处在于my eval
的参数在编译时需要是一个字符串——下面的错误是因为符号x
不能转换为字符串
(def x "(hello)")
(my-eval x)
这使得my eval
毫无意义-您可以“eval”一个文本字符串,也可以删除引号和my eval
,并具有相同的功能代码(您的编辑器将理解)
另一方面,Realeval
,尝试在运行时编译代码。在这里,它失败了,因为它是从main
名称空间运行的,而不是@Matthias Benkard指出的hello
名称空间。(println(hello))
和(println(my eval)(hello)”)
是完全相同的语句,唯一的区别是它们会让编辑器更加困惑<代码>我的评估与真实的评估
不可比。不同之处在于my eval
的参数在编译时需要是一个字符串——下面的错误是因为符号x
不能转换为字符串
(def x "(hello)")
(my-eval x)
这使得my eval
毫无意义-您可以“eval”一个文本字符串,也可以删除引号和my eval
,并具有相同的功能代码(您的编辑器将理解)
另一方面,Realeval
,尝试在运行时编译代码。在这里,它失败了,因为它是从main
名称空间运行的,而不是@Matthias Benkard指出的hello
名称空间