@assert alternatives?

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.

23 Likes