将clojure`defn`重构为`fn`会导致ClassCastException

Hen*_*all 1 refactoring clojure anonymous-function

我正在研究4clojure的Prime Numbers kata.我的解决方案在我的本地机器上运行得非常好(如果效率低下),但它依赖defn于4clojure 上的禁止.

(defn factors [n]
  (->> n
       range
       (map inc)
       (filter #(zero? (mod n %)))))

(defn prime? [n]
  (->> (factors n)
       (count)
       (= 2)))

(defn n-primes [n]
  (->> (range)
       (filter prime?)
       (take n)))
Run Code Online (Sandbox Code Playgroud)

我试图重构它只使用匿名函数,但它爆炸了.

(fn x-primes [count]
  (let [x-factors (fn factors [n] (->> n range (map inc) (filter #(zero? (mod n %)))))
         x-prime? (fn [n] (->> (x-factors n) (count) (= 2)))]
        (->> (range)
             (filter x-prime?)
             (take count))))
Run Code Online (Sandbox Code Playgroud)

抛出以下错误(在本地和4clojure的编辑器中运行时)

ClassCastException java.lang.Long无法强制转换为clojure.lang.IFn

我在重构代码时做错了什么?

撇开,为什么你认为4clojure禁令defdefn

Car*_*ate 6

您正在count使用参数名称隐藏该函数.(count some-num)抛出一个错误,因为在这个范围内,count是一个数字,而不是一个函数.

将参数名称更改count为其他名称.


另外,在4Clojure的帮助页面中,有以下行:

出于安全原因,禁止某些操作.例如,您将无法使用"def"或切换命名空间.

因为defn它只是一个def包装宏,所以它也是禁止的.如何导致安全问题超出我的范围.