You can also look at taking advantage of constant propogation to get the behavior you want.
asserting() = false #making this a function results in code being invalidated and recompiled when this gets changed
macro mayassert(test)
esc(:(if $(@__MODULE__).asserting()
@assert($test)
end))
end
f(x) = @mayassert x < 2
If we use that in a function we can see it gets compile out
julia> @code_llvm f(2)
; @ REPL[3]:1 within `f'
define void @julia_f_12238(i64) {
top:
ret void
}
we can just as easily turn it back on.
julia> asserting() = true
julia> @code_typed f(2)
CodeInfo(
1 ─ %1 = (Base.slt_int)(x, 2)::Bool
└── goto #3 if not %1
2 ─ return
3 ─ %4 = %new(Core.AssertionError, "x < 2")::AssertionError
│ (Base.throw)(%4)::Union{}
└── $(Expr(:unreachable))::Union{}
) => Nothing
Note: It is worth noting that @assert
statements can sometimes help the compiler generate faster code. In those cases it would be best to use a normal @assert
statement then a toggle-able one.