Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why recur from catch section in Clojure is illegal

Tags:

clojure

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.

like image 715
Petr Gladkikh Avatar asked Jun 23 '17 10:06

Petr Gladkikh


1 Answers

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
like image 113
Alan Thompson Avatar answered Oct 15 '22 13:10

Alan Thompson