recur in catch and finally?

38 views
Skip to first unread message

Meikel Brandmeyer

unread,
Nov 16, 2008, 4:23:18 AM11/16/08
to clo...@googlegroups.com
Hi,

I tried the following code, which is a valid loop, IMHO, since it
doesn't leave the catch clause.

(try
:xxx
(catch Exception e
(loop [x e]
(if (nil? (.getCause x))
x
(recur (.getCause x))))))

However I get:

java.lang.UnsupportedOperationException: Cannot recur from catch/
finally (NO_SOURCE_FILE:1)

Is this intended?

Sincerely
Meikel


Stephen C. Gilardi

unread,
Nov 16, 2008, 12:55:28 PM11/16/08
to clo...@googlegroups.com
On Nov 16, 2008, at 4:23 AM, Meikel Brandmeyer wrote:

I tried the following code, which is a valid loop, IMHO, since it
doesn't leave the catch clause.

(try
 :xxx
 (catch Exception e
   (loop [x e]
     (if (nil? (.getCause x))
       x
       (recur (.getCause x))))))

However I get:

java.lang.UnsupportedOperationException: Cannot recur from catch/finally (NO_SOURCE_FILE:1)

Is this intended?

Hi Meikel,

It is intended. Please see the discussion here:


--Steve

Meikel Brandmeyer

unread,
Nov 16, 2008, 1:44:29 PM11/16/08
to clo...@googlegroups.com
Hi Stephen,

Am 16.11.2008 um 18:55 schrieb Stephen C. Gilardi:
>> Is this intended?

I skimmed through the thread, and it seems the discussion is
for the following case:

(loop [...]
(try
...
(catch ... (recur ...))))

I wouldn't expect this to work. However in my case the structure
was:

(try
...
(catch ... (loop [...] (recur ...))))

So the loop did not cross the catch clause. From theoretic
point of view, I don't see a reason, why this should not be
possible. From a practical point of view there might be well
a reason why this prohibited. But then it should be mentioned
in the docs: "no loop inside catch".

Sincerely
Meikel


Stephen C. Gilardi

unread,
Nov 16, 2008, 2:55:36 PM11/16/08
to clo...@googlegroups.com

On Nov 16, 2008, at 1:44 PM, Meikel Brandmeyer wrote:

I skimmed through the thread, and it seems the discussion is
for the following case:

(loop [...]
 (try
   ...
   (catch ... (recur ...))))

I wouldn't expect this to work. However in my case the structure
was:

(try
 ...
 (catch ... (loop [...] (recur ...))))

So the loop did not cross the catch clause. From theoretic
point of view, I don't see a reason, why this should not be
possible.

Right you are, I had missed that distinction between the two cases. Now it looks to me like your code should work and that the test for recur in catch should be refined to detect the case where recur destination is also in the catch and allow that.

--Steve

Chouser

unread,
Nov 16, 2008, 8:09:49 PM11/16/08
to clo...@googlegroups.com

You could of course work around this by putting your loop in some
other function and calling it from inside catch.

--Chouser

mb

unread,
Nov 17, 2008, 2:06:04 AM11/17/08
to Clojure
Hi,

On 17 Nov., 02:09, Chouser <chou...@gmail.com> wrote:
> You could of course work around this by putting your loop in some
> other function and calling it from inside catch.

In this specific case I used:
(last (take-while #(not (nil? %)) (iterate #(.getCause %) e)))

However, a separate function would also work. That is not
the point. One can work around it. But I try to follow the
principle of least surprise as much as possible. So when
valid looking code doesn't work for an obscure reason, this
certainly is a surprise.

I have no problem putting the loop into a dedicated function.
Or find some equivalent way to express it. However then it
should be documented somewhere, that this is actually
necessary. ("for technical reasons loop/recur cannot be
used in/at/for....")

Sincerely
Meikel

Rich Hickey

unread,
Nov 17, 2008, 8:32:13 AM11/17/08
to Clojure
Yes, it's an arbitrary restriction (due to complexity) which I should
document.

Rich
Reply all
Reply to author
Forward
0 new messages