A macro is like a template, so if you pass in an expression then that expression will show up in the expansion everywhere it is referenced, so you may execute the expression more than once. The let binding is a way to cause the lock expression to be evaluated once, but then reference the result of the evaluation
The try stuff is a whole thing, which has to do with how different jvm byte code verifiers verify that the usages of monitor locks in the bytecode follow specific patterns, and if you don't follow certain patterns it will reject the bytecode
Generally not something you need to worry about
user=> (defmacro foo [a] `(do ~a ~a))
#'user/foo
user=> (foo (prn 1))
1
1
nil
user=>user=> (defmacro foo [a] `(let [x# ~a] x# x#))
#'user/foo
user=> (foo (prn 1))
1
nil
user=>From Clojure core. What’s going on here? What’s the purpose of the outer try ? Why juggle ~x to lockee# and then lockee# to locklocal# rather than bind locklocal# to ~x directly?
Right, but why the intermediary lockee#, which only seems to rebind to locklocal#? Binding down ~x is itself good macro hygiene, like you say.
OK, I would have thought that a try without catch / finally would compile down to ~nothing.
@henrik You are right. I've checked with two expansions with clj-java-decompiler.core/disassemble , one with dummy try and one without, and the generated bytecode is identical.
Aha, interesting @alexyakushev, I thought I was watching sorcery, but maybe I’m watching history. Residue from a refactor or similar. I’m going to look at the commits for this.
Both things are almost certainly leftovers from a previous implementation rather than bytecode magic. I had Claude exercise the current one, and one where the try and rebind is elided, and it yields ~identical byte code, except for the rebind costing 4 throwaway codes.
So presumably, I’m looking at a Clojure core “let the codebase move as little as humanly possible” type of decision rather than bytecode juggling magic.
Other than the monitor-enter itself moving out of the try, that was exactly the analyzer adaption you mentioned @hiredman.
> Ensure monitor object is on stack, for verifiers the commit message for CLJ-1472 may help explain