I found an example of an unless
macro in Julia here written as follows:
macro unless(test, branch)
quote
if !$test
$branch
end
end
end
However, when I try to use it, it fails (apparently there is a hygiene problem, but I can't figure it out exactly). Here is the test that I used:
x, y = 0, 1
@unless (x == 5) begin # should execute
y = 3
end
@unless (x == 0) begin # should not execute
y = 5
end
@assert y == 3 # FAILS! SAYS y is 0
Now I can make this work by escaping only the branch, not the test:
macro unless(test, branch)
quote
if !$test
$(esc(branch))
end
end
end
My question is: why does it suffice to only escape the branch but not the test? Now I did try macroexpanding. In the first case, without the esc
, I get this:
julia> macroexpand(:(@unless (x == 5) begin y = 3 end))
quote # none, line 3:
if !(x == 5) # none, line 4:
begin # none, line 1:
#2#y = 3
end
end
end
Now even though neither macro parameter was escaped, ONLY the y
was gensymed! Can anyone explain why this was the case? (I know that the second version works because when I escape the branch, The y doesn't get gensymed and the macro expands to y = 3
as expected. But I'm totally at a loss as to why the x
was not gensymed even though there was no use of esc
.)