# @assert alternatives?

**URL:** <https://discourse.julialang.org/t/assert-alternatives/24775>\
**Category:** New to Julia\
**Created:** [May 30, 2019, 5:22pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775 "2019-05-30T17:22:15Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 30, 2019, 5:22pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/1 "2019-05-30T17:22:15Z")

</div>

AFAIK there is no way yet to globally disable `@assert` with a compiler switch, even if doing so was already considered in the past ([here](https://github.com/JuliaLang/julia/issues/7732) and [here](https://github.com/JuliaLang/julia/issues/10614), for example). While this is not done (as I do like to believe some day someone will implement this), what is the “de facto” solution for having `@assert` in performance critical code? There is a package? We can redefine the behavior for a no-op in some way? Should we implement our own macro? Use ifs and a global boolean variable?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [May 30, 2019, 5:49pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/2 "2019-05-30T17:49:55Z")

</div>

You can read environment variables within Julia. Let’s use “ASSERTIONS” as the environment variable that, if it exist and it is set to “TRUE”, we want to enable our assertions. Otherwise, we do not want any assertion checking to occur.

```julia
module MayAssert
    export mayassert
    active = keyexists(ENV, "ASSERTIONS") && ENV["ASSERTIONS"] == "TRUE"
    if active
        macro mayassert(test)
            @assert(test)
        end
     else
         macro mayassert(test)
         end
      end
end

```

```julia
using .MayAssert
@mayassert(false) 
nothing

```

… another session

```julia
$ export ASSERTIONS="TRUE"
$ julia
using MayAssert
@mayassert(false)
AssertionError

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 30, 2019, 6:29pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/3 "2019-05-30T18:29:47Z")

</div>

> [@JeffreySarnoff](#):
>
> You can read environment variables within Julia. Let’s use “ASSERTIONS” as the environment variable that, if it exist and it is set to “TRUE”, we want to enable our assertions. Otherwise, we do not want any assertion checking to occur.

This will read the value of the environment variable at precompile time and will not update when the variable changes until a new precompile is triggered for some other reason.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 30, 2019, 7:15pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/4 "2019-05-30T19:15:29Z")

</div>

Hmm, I think that without someone implementing it in the compiler itself, an `@assert` macro has no way to be a guaranteed no-op and, at the same time, avoid the need to change and recompile a specific module to alternate between “no-op assert” and “working assert”.

Maybe it will need to be a module in which I manually change the value of an ‘active’ flag every time I want to change the status of `@assert`.

Or can I pass something to force a module to be recompiled in a specific `using`/`import`? (or, less ideally, every time it is used/imported)? This also would solve the problem (and allow for reading the ENV to make the decision).

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [May 30, 2019, 9:03pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/5 "2019-05-30T21:03:55Z")

</div>

> [@Henrique\_Becker](#):
>
> Hmm, I think that without someone implementing it in the compiler itself, an `@assert` macro has no way to be a guaranteed no-op and, at the same time, avoid the need to change and recompile a specific module to alternate between “no-op assert” and “working assert”.

Can’t you just turn off precompilation of the module?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [May 30, 2019, 9:07pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/6 "2019-05-30T21:07:51Z")

</div>

@Mason

> The command line flag --compiled-modules={yes. no} enables you to toggle module _precompilation on_ and _off_ . When _Julia_ is started with --compiled-modules=no the serialized modules in the compile cache are ignored when loading modules and module dependencies.

(I don’t know what `_precompile_(false)` does anymore)

@kristoffer.carlsson  
Could mayassert be written as a mutable function wrapper, wrapping  
`fn::Ref(Union{typeof(doassert), typeof(donotassert)})` and get assigned as the desire for assertions is updated … sure, the calling may require some touch, but would it work?

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [May 30, 2019, 10:41pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/7 "2019-05-30T22:41:57Z")

</div>

You can write `active = true` or `active = false` into `deps/deps.jl` (say) at build time based on `ENV["ASSERTIONS"]`. If it is `include`d from `src/MayAssert.jl`, the whole package and all its downstreams would be re-compiled if you re-build `MayAssert`. But it is not ideal to re-compile packages all the time…

Alternatively, how about abusing `@boundscheck`?

```julia
macro mayassert(ex)
    esc(:($Base.@boundscheck $Base.@assert $ex))
end

```

You can then use `--check-bounds={yes|no}` to toggle assertion.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [May 30, 2019, 11:09pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/8 "2019-05-30T23:09:45Z")

</div>

+1 for outside-the-box

we want the assertion macro to be able to dissolve in a released version  
we do not want to force the package user to start with `--check-bounds=no`

reversing the sense of your macro forces bounds checking off when assertions are active, and that is imperfect for development

fwiw years ago I found a way that worked – would be worth more with sourcetext, and maybe it worked by using aspects of very early Julia that no longer hold.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [May 30, 2019, 11:30pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/9 "2019-05-30T23:30:05Z")

</div>

> [@JeffreySarnoff](#):
>
> we do not want to force the package user to start with `--check-bounds=no`

Ah, good point. If you want to get rid of assertion in the release mode, yet another possibility is to release version `x.y` and `x.(y - 1)` of `MayAssert` where `y` is an even number such that `@mayassert` from version `x.y` is a no-op and it’s `@assert` for `x.(y - 1)` (like old Linux kernel which used odd minor version to mean dev version). This way, you can use [`jlm`](https://discourse.julialang.org/t/22849) (a tool I made) to isolate the precompilation cache for “dev builds.”

Aside: even/odd versions work for a binary flag like this. But it would really be nice to have package options ([Package options · Issue #38 · JuliaLang/Juleps · GitHub](https://github.com/JuliaLang/Juleps/issues/38), [Package Options · Issue #458 · JuliaLang/Pkg.jl · GitHub](https://github.com/JuliaLang/Pkg.jl/issues/458)) so that we can, e.g., toggle only a subset of assertions.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [May 31, 2019, 12:25am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/10 "2019-05-31T00:25:50Z")

</div>

add this to `startup.jl`

```julia
const Asserting = Ref( true ) # or Ref( false )

macro mayassert(test)
    :(if Asserting[]
          @assert($test)
      end)
end

```

then while working, to turn off assertions `Asserting[] = false`  
to turn assertions on again `Asserting[] = true`

to use switchable assertions

`@mayassert( precondition )`  
`@mayassert( invariant )`  
`@mayassert( postcondition )`

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [May 31, 2019, 12:43am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/11 "2019-05-31T00:43:10Z")

</div>

`if Asserting[]` has some runtime const (which is totally fine in many cases).

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 31, 2019, 1:18am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/12 "2019-05-31T01:18:37Z")

</div>

@JeffreySarnoff, I think the Ref is not necessary, it is? The keyword `const` on global variables do not just mean their types is constant, not their value?

I am not sure if I understand how macros work, would it compile for the value of `Asserting[]` during the first time the definition is run, and then all the other times it would be no-op or an assert? Because this would work for me.

@tkf, @JeffreySarnoff, I agree that this is not ideal, but abusing --check-bounds is very tempting for me. I would disable `@assert` in the same cases that I would disable bounds check that is when I am confident in the code correctness and would run experiments (to put in scientific papers) and wanted the best performance possible.

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [May 31, 2019, 1:20am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/13 "2019-05-31T01:20:27Z")

</div>

no one will fault you for using a solution that effectively propels your work  
no one will fault you for using a solution that propels your work effectively

(the use of `Ref` allows the assertions to be switched on and off from the REPL)

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [May 31, 2019, 4:06am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/14 "2019-05-31T04:06:21Z")

</div>

You can also look at taking advantage of constant propogation to get the behavior you want.

```julia
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
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
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.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [May 31, 2019, 4:25am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/15 "2019-05-31T04:25:26Z")

</div>

This is very clever!

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 31, 2019, 4:52am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/16 "2019-05-31T04:52:13Z")

</div>

I do agree, I cannot decide if is elegant or hacky clever, but is indeed clever.

Clearly, if a method is changed, so all methods that depend on it also  
need to be recompiled, but not one more. And if the method return the  
same literal every time, it also makes very hard for the compiler to  
mess something.

If nobody jumps out of a bush and bring a caveat or pitfall of this  
solution (as already happened many times in this thread) by tomorrow  
noon, then I can finally decide on a solution, XD.

Thanks everyone

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [May 31, 2019, 5:02am UTC](https://discourse.julialang.org/t/assert-alternatives/24775/17 "2019-05-31T05:02:30Z")

</div>

well crafted

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [May 31, 2019, 3:22pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/18 "2019-05-31T15:22:04Z")

</div>

Perhaps this could be put in a package? I think that could be really useful.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 31, 2019, 4:04pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/19 "2019-05-31T16:04:02Z")

</div>

Using the solution of julia issue #265 to toggle debug info has been discussed (it is also used in e.g [https://github.com/KristofferC/TimerOutputs.jl/blob/master/README.md#overhead](https://github.com/KristofferC/TimerOutputs.jl/blob/master/README.md#overhead) to do essentially the same thing).

The downside is that the more things that use it, the more things have to be recompiled when toggling.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 31, 2019, 6:03pm UTC](https://discourse.julialang.org/t/assert-alternatives/24775/20 "2019-05-31T18:03:14Z")

</div>

> The downside is that the more things that use it, the more things have to be recompiled when toggling.

I think this is a unavoidable downside. If the intention is to have a macro that sometimes do something, sometimes is a no-op, the code that uses it has to be recompiled each time it changes situation. My original question asked by an alternative while `--assert-check=no` does not exist. My use case, therefore, considered that I wanted to define at the start of Julia if the assert would be no-op, or not, and compile everything accordingly. To do so, it would need to recompile any pre-compiled Module that uses `@assert` anyway.

I am really satisfied with this solution and it seems to be a ‘de facto’ solution for the problem (already is used by a package that wants to be able to disable overhead of a non-essential part of the program: measuring how much time was spent in each section).

I will probably use an hybrid of such solution and the `--check-bounds` abuse to easily toggle all extra checking when doing experiments to go on a paper (instead of testing the code correctness). I will also probably become an user of this [TimerOutputs](https://github.com/KristofferC/TimerOutputs.jl/blob/master/README.md) Package as I was doing something like this by hand already.

[Next page](https://discourse.julialang.org/t/assert-alternatives/24775.md?page=2)
