clj-kondo has a linter which checks for a try
without a catch
or finally
. This made me curious and led me to this commit
https://github.com/clojure/clojure/commit/6c0c37e048f49ee5cd3afa79ce461abbc6a0c367
Anyone know the history/rationale behind this?
I suppose you mean: why not just throw if there's no catch/finally?
There is one try without catch/finally in the locking macro. Not sure why it's there, but it has a subtle implication for the bytecode, if I remember correctly
@slipset (try x (catch Exception _))
has slightly different semantics than (do x)
even if no exception is thrown
even ignoring the extra needless bytecodes that would be emitted
@bronsa I guess what I’m asking is why would you want (try foo)
the body of a try is hoisted in a fn, so recur breaks for example
@slipset macros may emit it
it's the same reason why you'd want (do x)
instead of simply x
it's convenient when doing codegen :)
Right.
ah nice
user=> (clj-java-decompiler.core/decompile (try :dummy))
// Decompiling class: user$fn__198
import clojure.lang.*;
public final class user$fn__198 extends AFunction
{
public static final Keyword const__0;
public static Object invokeStatic() {
return user$fn__198.const__0;
}
@Override
public Object invoke() {
return invokeStatic();
}
static {
const__0 = RT.keyword(null, "dummy");
}
}
I guess (try :dummy)
would be equivalent to ((fn [] :dummy))
for that purpose
Oh, an iefe 🙂
I don’t have the details on hand, but I recall that Clojure seemed to emit more bytecode ops than java in to do a try-catch and I was confused why
meaning, it seemed heavier overhead than in java
There’s more local clearing probably
I think that is nice to clojure have (try ... #_(catch ...))
for REPL proposes (just comment the catch
part for dev)
And also nice kondo
warns you about that
that may be it @alexmiller maybe I’ll redo my example again to remember - wish I would have noted it