我正试图在4clojure.com解决计数序列练习.练习是在不使用该count功能的情况下计算集合中元素的数量.
我以为我可以通过递归,通过使用来做到这一点rest.如果我得到的不是空的,我会回来1 + recur on the sequence rest returned.问题是,我最终得到了
java.security.PrivilegedActionException: java.lang.UnsupportedOperationException:
Can only recur from tail position
Run Code Online (Sandbox Code Playgroud)
即使我称之为recur最后一个声明.
(fn [coll] (let [tail (rest coll)]
(if (empty tail)
1
(+ 1 (recur tail)))))
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?
在下面(Clojure)SO问题:我自己的插入功能作为练习
接受的答案说:
用recur调用替换你的递归调用,因为写入它会遇到堆栈溢出
(defn foo [stuff]
(dostuff ... )
(foo (rest stuff)))
Run Code Online (Sandbox Code Playgroud)
变为:
(defn foo [stuff]
(dostuff ...)
(recur (rest stuff)))
Run Code Online (Sandbox Code Playgroud)
避免吹栈.
这可能是一个愚蠢的问题,但我想知道为什么递归调用foo不会被recur自动替换?
此外,我采取了另一个SO示例并写了这个(没有故意使用cond,只是为了尝试一下):
(defn is-member [elem ilist]
(if (empty? ilist)
false
(if (= elem (first ilist))
true
(is-member elem (rest ilist)))))
Run Code Online (Sandbox Code Playgroud)
而且我想知道我是否应该用recur替换对is-member的调用(这似乎也有效).
是否存在递归的情况,特别是不应该使用复发?
我只是在 REPL 上构建一个函数并遇到了这个问题。
我定义了一个符号 S 并给它一个值:
(def S '(FRUIT COLORS (YELLOW GREEN) SKIN (EDIBLE INEDIBLE)))
Run Code Online (Sandbox Code Playgroud)
我最终想要一个函数,它接受参数列表中的第一个条目以及任何和所有后续参数对,并将它们应用于第一个条目。我的编码从来没有那么远。我想使用循环/recur 构造(我应该这样做吗?),这是我在 REPL 中得到的程度:
(loop [KV# (rest S)]
(if (empty? KV#)
nil
(
(pprint S, (first KV#), (second KV#))
(recur (rest (rest KV#)))
)
)
)
Run Code Online (Sandbox Code Playgroud)
我得到一个“只能从尾部位置重复”编译器错误。
在 Stack Overflow 上到处找了包括 7 或 8 篇文章之后,我只能问:嗯?!
我是新手。如果 recur 不在尾部位置,有人可以向我解释为什么吗?
与'if'语句语法有关吗?啊!Clojure 不适合弱者!谢谢你。