嵌套匿名函数是否合法?我为4clojure的problem #107写了以下内容:
(fn [n] #(reduce * (repeat n %)))
通过了所有3个测试,但是当我在repl中尝试使用测试3时,我得到一个IllegalStateException,说不允许嵌套#():
IllegalStateException Nested #()s are not allowed
clojure.lang.LispReader$FnReader.invoke (LispReader.java:628)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: n
in this context, compiling:(NO_SOURCE_PATH:1:44)
RuntimeException Unmatched delimiter: )
clojure.lang.Util.runtimeException (Util.java:221)
RuntimeException Unmatched delimiter: )
clojure.lang.Util.runtimeException (Util.java:221)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: %
in this context, compiling:(NO_SOURCE_PATH:0:0)
RuntimeException Unmatched delimiter: )
clojure.lang.Util.runtimeException (Util.java:221)
RuntimeException Unmatched delimiter: )
clojure.lang.Util.runtimeException (Util.java:221)
RuntimeException Unmatched delimiter: )
clojure.lang.Util.runtimeException (Util.java:221)
RuntimeException Unmatched delimiter: )
clojure.lang.Util.runtimeException (Util.java:221)
为什么这个不能在repl上传递,而是在4clojure上传递?
答案 0 :(得分:13)
嵌套的匿名函数完全可以。但你不能嵌套#()读取器宏,因为它没有很好地定义 - 我们不知道程序员是否通过%1
表示外部函数文字的第一个参数或内部的第一个参数函数文字。
如果要评估整个测试表单,则需要输出“longhand”内部函数(使用fn
)。
(fn [n]
(fn [m]
(reduce * (repeat n m))))
在4Clojure上工作可能是因为他们在将表单插入测试表单之前会对您提供的表单进行评估。因此,在评估测试表单时,#()宏已经扩展(到fn*
)。