Petr Gladkikh
Petr Gladkikh

Reputation: 1932

Why recur from catch section in Clojure is illegal

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.

Upvotes: 10

Views: 558

Answers (1)

Alan Thompson
Alan Thompson

Reputation: 29976

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 [email protected]. 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

Upvotes: 1

Related Questions