在Clojure中循环/返回。什么是“尾巴”位置?

我只是在 REPL 上构建一个函数并遇到了这个问题。
我定义了一个符号 S 并给它一个值:

(def S '(FRUIT COLORS (YELLOW GREEN) SKIN (EDIBLE INEDIBLE)))

我最终想要一个函数,它接受参数列表中的第一个条目以及任何和所有后续参数对,并将它们应用于第一个条目。我的编码从来没有那么远。我想使用循环/recur 构造(我应该这样做吗?),这是我在 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 ...)表单将表单组合在一起,如下所示:

(loop [KV# (rest S)]
    (if (empty? KV#)
        nil  ; then
        (do  ; else
          (pprint S, (first KV#), (second KV#))
          (recur (rest (rest KV#)))
        )
    )
)

这摆脱了“不在尾部位置复发”的问题,但仍然失败 - 一个arity异常pprint- 但我会把它留给你解决。

我是怎么发现这个的?我的规则是,每当我发现两个左父母在一起时,我都会立即认为我犯了一个错误,我需要弄清楚我做错了什么。在这种情况下,它有点难以发现,因为左括号被中间的空白隔开——但是,从词法扫描仪的角度来看,它们仍然是彼此相邻的。所以你只需要学会像词汇扫描器一样思考。:-)


以上是在Clojure中循环/返回。什么是“尾巴”位置?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>