【发布时间】:2021-02-08 16:31:35
【问题描述】:
我只是在 REPL 中构建一个函数,然后遇到了这个问题。
我定义了一个符号 S 并给它一个值:
(def S '(FRUIT COLORS (YELLOW GREEN) SKIN (EDIBLE INEDIBLE)))
最终,我想要一个函数,它采用参数列表中的第一个条目以及任何和所有后续参数对并将它们应用于第一个条目。我的编码从来没有那么远。我想使用循环/递归构造(应该我?),这是我在 REPL 中的进展:
(loop [KV# (rest S)]
(if (empty? KV#)
nil
(
(pprint S, (first KV#), (second KV#))
(recur (rest (rest KV#)))
)
)
)
我收到“只能从尾部位置重复”编译器错误。
在查看了这方面的所有内容(包括 Stack Overflow 中的 7 或 8 篇文章)之后,我只能问:嗯?!
我是新来的。如果 recur 不在尾部位置,有人可以向我解释为什么吗?
与“if”语句语法有关吗?啊! Clojure 不适合弱者!谢谢。
【问题讨论】:
-
我的 Clojure 生锈了,但这段代码看起来会在运行时失败。您需要在
()中使用do来包装对pprint和recur((do (pprint S, (first KV#), (second KV#)) (recur (rest (rest KV#))))的调用,否则您将尝试将pprint的返回视为可调用。这可能会修复问题也是。目前,recur是函数的参数,这意味着它不会是函数中执行的最后一件事(使用它的值的函数将是)。 -
请查看此文档列表:github.com/io-tupelo/clj-template#documentation 可能从“Brave Clojure”和“Getting Clojure”开始。这个问题对于 StackOverflow 来说实在是太笼统了。
-
以更熟悉的方式考虑以下内容:
factorial(n) { if (n == 1) { return 1; } return n * factorial(n - 1); }。尾部位置的意思是“完成的最后一件事”,递归调用是函数体中的最后一个元素,在尾部位置吗?不!最后完成的是n 的乘法和递归调用。如果它是像阶乘示例或聚合return [a, b, someRecursiveCall(c)];这样的表达式的一部分,则它不是尾调用。目前尚不清楚您要在通话中做什么,但 recur 显然嵌套在其他内容中。 -
@AlanThompson:这可以被引用为 this question 或 this question 的重复,但因为它实际上不是尾部位置问题,而是一个轻微但常见的语法错误,我发布了一个回答。
-
独立于尾调用问题:大多数情况下,您可以通过使用 coljure 的序列操作函数来避免循环/重复。
(doseq [[k v] (partition 2 (rest S))] (println S k v))会做同样的事情,同时保留代码简洁且不易出错。
标签: intellij-idea clojure cursive