10

There already at least one answered question regarding recur on exception. My question is why this recur is not accepted by Clojure compiler

(loop []
  (try
    (catch Exception _ex
      (recur))))

with error "Can only recur from tail position".

According to control flow this recur is in tail position since code does nothing after recur inside loop form.

Petr Gladkikh
  • 1,906
  • 2
  • 18
  • 31
  • Apparently `recur` is not allowed in the `finally` clause either. `(loop [] (try (catch Exception _) (finally (recur))))` causes the same compilation error. – ez121sl Jun 23 '17 at 13:39

1 Answers1

1

If in asking "Why is this so?", you are asking for the history, you may get a better answer posting this question to the Clojure mailing list at clojure@googlegroups.com. I suspect the reason is that the the compiler authors never considered this use-case.

You can simulate your desired behavior easily enough as this example shows. It does not use macros like most of the answers from the previous question linked:

    (loop [count 5]
      (newline)
      (println "top of loop; count=" count)
      (let [caught-ex (try
                        (println "in try")
                        (/ 1 0)
                        false
                        (catch Exception ex
                          (println "   in catch; count=" count "   cause:  " (.getMessage ex))
                          true))]
           (when (and caught-ex
                   (pos? count))
             (recur (dec count)))))

with result:

top of loop; count= 5
in try
   in catch; count= 5    cause:   Divide by zero

top of loop; count= 4
in try
   in catch; count= 4    cause:   Divide by zero

top of loop; count= 3
in try
   in catch; count= 3    cause:   Divide by zero

top of loop; count= 2
in try
   in catch; count= 2    cause:   Divide by zero

top of loop; count= 1
in try
   in catch; count= 1    cause:   Divide by zero

top of loop; count= 0
in try
   in catch; count= 0    cause:   Divide by zero
Alan Thompson
  • 29,276
  • 6
  • 41
  • 48
  • 5
    This use case was certainly considered, and has been discussed before. See https://groups.google.com/forum/#!topic/clojure/0A32oPAyeoY and https://dev.clojure.org/jira/browse/CLJ-31?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs for example. – amalloy Jun 23 '17 at 19:08