Where is the tail position in my Clojure loop?

后端 未结 2 1545
梦如初夏
梦如初夏 2021-01-23 20:33

Clojure is saying that I can\'t call recur from a non-tail-position.

Is this not the tail position?

What is the tail position in my loop th

相关标签:
2条回答
  • 2021-01-23 20:53

    Further to @JohnBaker's answer, any recur refers to the (nearest) enclosing loop or fn (which may be dressed as a letfn or a defn). There is no such thing in your snippet. So there is nothing for the recur to be in tail position to.

    But just replace the for with loop, and you get

    (loop [i 20]
      (loop [x 1]
        (if (zero? (rem i x))
          i
          (recur (+ i 1)))))
    

    ... which evaluates to 20,no doubt what you intended.

    However, the outer loop is never recurred to, so might at well be a let:

    (let [i 20]
      (loop [x 1]
        (if (zero? (rem i x))
          i
          (recur (+ i 1)))))
    

    The recur is in tail position because there is nothing left to do in that control path through the loop form: the recur form is the returned value. Both arms of an if have their own tail position.

    There are some other disguised ifs that have their own tail position: ors and ands are such.

    0 讨论(0)
  • 2021-01-23 21:10

    for does not do what you think it does; it is not an imperative loop. It is a list comprehension, or sequence-generator. Therefore, there is not a return or iterate call at its end, so you cannot place recur there.

    It would seem you probably do not need either loop or recur in this expression at all; the for is all you need to build a sequence, but it's not clear to me exactly what sequence you wish to build.

    0 讨论(0)
提交回复
热议问题