# ANN: ToggleableAsserts.jl

**URL:** https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291
**Category:** Package Announcements
**Created:** [November 20, 2019, 1:58am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291 "2019-11-20T01:58:17Z")
**Posts on this page:** 19
**Page:** 1

<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: [November 20, 2019, 1:58am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/1 "2019-11-20T01:58:17Z")

</div>

Following two back to back questions on slack on the topic of “how can I turn off assertions in my code?” I decided to make a small package insipired by this clever trick: [@assert alternatives? - #14 by WschW](https://discourse.julialang.org/t/assert-alternatives/24775/14)

> **[GitHub - MasonProtter/ToggleableAsserts.jl: Assertions that can be turned on...](https://github.com/MasonProtter/ToggleableAsserts.jl)**
>
> Assertions that can be turned on or off with a switch, with no runtime penalty when they're off. - GitHub - MasonProtter/ToggleableAsserts.jl: Assertions that can be turned on or off with a swi...

Here’s a little demonstration showing how we can have assertions that we can turn on or off without any runtime penalty by recompiling functions depending on the assertion:

```julia
using ToggleableAsserts

function foo(u, v)
    @toggled_assert length(u) == length(v)
    1
end

```

```julia
julia> foo([1, 2], [1])
ERROR: AssertionError: length(u) == length(v)
Stacktrace:
 [1] foo(::Array{Int64,1}, ::Array{Int64,1}) at ./REPL[1]:2
 [2] top-level scope at REPL[2]:1 

julia> toggle(false)
[ Info: Toggleable asserts turned off.

julia> foo([1, 2], [1])
1

julia> @code_llvm foo([1,2], [1])
; @ REPL[1]:2 within `foo'
define i64 @julia_foo_16854(%jl_value_t addrspace(10)* nonnull align 16 dereferenceable(40), %jl_value_t addrspace(10)* nonnull align 16 dereferenceable(40)) {
top:
  ret i64 1
} 

```

* * *

**Edit 1** : The `@toggle` macro has been changed to a function: `toggle` following this comment: [ANN: ToggleableAsserts.jl - #11 by rdeits](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/11)

**Edit 2** : ToggleableAsserts.jl is now a registered package. Install it by simply running

```julia
pkg> add ToggleableAsserts

```

---

<div class="post-metadata">

### Author: ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)
#### Post date: [November 20, 2019, 6:22am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/2 "2019-11-20T06:22:58Z")

</div>

Er? Is this thing Thread safe? What if multiple threads called “@toggle false” and “@toggle true”?

---

<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: [November 20, 2019, 6:45am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/3 "2019-11-20T06:45:16Z")

</div>

Good question!

I’m not actually sure what guarantees julia gives in that regard, so I threw `@toggle` in a lock. If anyone reading this knows about thread safety, let me know if what I did here was sufficient and / or overkill: [https://github.com/MasonProtter/ToggleableAsserts.jl/commit/3029fa0565115ea6dad07468061e389d70ae0db7](https://github.com/MasonProtter/ToggleableAsserts.jl/commit/3029fa0565115ea6dad07468061e389d70ae0db7).

I feel like entering and exiting a debugging mode like this is a pretty weird thing to do in a multithreaded context though anyways…

---

<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: [November 20, 2019, 8:10pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/4 "2019-11-20T20:10:37Z")

</div>

Okay, I’ve made it so that the only valid inputs to the `@toggle` macro are literally writing `true` or `false` because I realized that writing things like `rand(Bool)` in there would cause all sorts of problems with my implementation and I think that is a reasonable restriction.

I’ve also submitted the package to the general registry and am now in the mandatory waiting period for new packages.

---

<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: [November 20, 2019, 9:28pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/5 "2019-11-20T21:28:53Z")

</div>

You need to hit top level scope between changing or you will get world age errors.

---

<div class="post-metadata">

### Author: ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)
#### Post date: [November 20, 2019, 9:34pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/6 "2019-11-20T21:34:33Z")

</div>

Here is an improvement to your module. Use a Reference to store your global state

```julia
module ToggleableAsserts

const ASSERT_TOGGLE = Ref(true)

macro toggled_assert(cond, text=nothing)
    if text==nothing
        assert_stmt = esc(:(@assert $cond))
    else
        assert_stmt = esc(:(@assert $cond $text))
    end
    :(ToggleableAsserts.ASSERT_TOGGLE[] ? $assert_stmt : nothing)
end

const toggle_lock = ReentrantLock()

macro toggle(bool)
    bool ∈ [:true, :false] || error("Toggle only takes true or false literals.")
    quote
        lock(ToggleableAsserts.toggle_lock) do
            @assert $bool isa Bool
            ToggleableAsserts.ASSERT_TOGGLE[] = $bool
            on_or_off = $bool ? "on." : "off."
            @info "Toggleable asserts turned "*on_or_off
        end
    end
end

export @toggled_assert, @toggle

end # module

```

---

<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: [November 20, 2019, 9:37pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/7 "2019-11-20T21:37:29Z")

</div>

@kristoffer.carlsson Hm, you’re right! I think in that case I’ll try to make the `@toggle` macro error unless it’s called from the global scope.

@StevenSiew That could be useful for some purposes, but it imposes a runtime overhead even if the assertion is turned off, so it’s not the direction I’d want to move this package.

---

<div class="post-metadata">

### Author: ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)
#### Post date: [November 20, 2019, 9:41pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/8 "2019-11-20T21:41:06Z")

</div>

oh yeah! I forgot that macros occurs at compile time.

---

<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: [November 21, 2019, 12:22am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/9 "2019-11-21T00:22:43Z")

</div>

Sometimes we get the hero we do not deserve, XD.

I am one of the people that started these threads asking for alternatives in the past. However, because my PhD, I never had the time to make the solution a package. I thank you for this. I will make use of it.

---

<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: [November 21, 2019, 12:50am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/10 "2019-11-21T00:50:57Z")

</div>

I couldn’t find a way to detect if `@toggle` was invoked in the global scope or not, so I just ended up adding a warning to the README.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [November 21, 2019, 2:47am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/11 "2019-11-21T02:47:48Z")

</div>

As far as I can tell, there’s no need for `@toggle` to be a macro–it can just be a function:

```julia
function toggle(enable::Bool)
    lock(toggle_lock) do
        @eval ToggleableAsserts assert_toggle() = $enable
        on_or_off = enable ? "on." : "off."
        @info "Toggleable asserts turned "*on_or_off
    end
end

```

There’s nothing _wrong_ with using a macro, but it’s an unnecessary layer of complexity.

---

<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: [November 21, 2019, 3:05am UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/12 "2019-11-21T03:05:42Z")

</div>

Good point! I originally made a macro because I intended to modify `assert_toggle()` directly with the output code and then realized that wouldn’t work so I switched to doing an `eval` and never realized I could get rid of the macro.

---

<div class="post-metadata">

### Author: ![vladium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vladium/32/11526_2.png) [@vladium](https://discourse.julialang.org/u/vladium)
#### Post date: [November 25, 2019, 2:55pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/13 "2019-11-25T14:55:52Z")

</div>

I love this idea (had a thought of implementing such a utility myself)!

I am reminded of Java asserts that are toggled at classloading time. Thread safety of loading a class is ensured by the JVM. As a result, thread safety does not incur any runtime overhead post classloading because the assert-triggered bytecode blocks are guarded by am immutable “static final” boolean flag field (the JIT is within its right to and will in fact elide all of them).

I wonder if something similar could be done in Julia – I think it requires some kind of a hook during include() so that assertion status could be set at some intermediate code representation level. Checking locks _at runtime_ will almost surely result in overhead that’s too high for truly liberal assert usage (defensive programming, etc).

---

<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: [November 25, 2019, 4:13pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/14 "2019-11-25T16:13:30Z")

</div>

> [@vladium](#):
>
> Checking locks _at runtime_ will almost surely result in overhead that’s too high for truly liberal assert usage (defensive programming, etc).

If I’m interpreting you correctly here, it seems you’re saying that ToggleableAsserts incurs a runtime penalty due to checking locks. That is not the case. The only time a lock is checked is when the assertions are toggled on or off. Once the assertions are turned off, they are completely removed from the function body by the compiler:

```julia
using ToggleableAsserts, BenchmarkTools

function f()
    @toggled_assert (sleep(1); true)
    1
end

g() = 1

```

```julia
julia> @btime f();
  1.002 s (7 allocations: 160 bytes)

julia> @btime g();
  0.019 ns (0 allocations: 0 bytes)

julia> toggle(false)
[ Info: Toggleable asserts turned off.

julia> @btime f();
  0.019 ns (0 allocations: 0 bytes)

```

```julia
julia> @code_llvm f()
define i64 @julia_f_17080() {
top:
  ret i64 1
}

julia> @code_llvm g()
define i64 @julia_g_17114() {
top:
  ret i64 1
}

```

As you can see, once I run `toggle(off)`, the assertions are completely gone.

---

<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: [November 25, 2019, 4:14pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/15 "2019-11-25T16:14:40Z")

</div>

In other news, ToggleableAsserts.jl is now registered, so you can now install it by simply running

```julia
pkg> add ToggleableAsserts

```

---

<div class="post-metadata">

### Author: ![vladium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vladium/32/11526_2.png) [@vladium](https://discourse.julialang.org/u/vladium)
#### Post date: [November 25, 2019, 4:43pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/16 "2019-11-25T16:43:05Z")

</div>

> The only time a lock is checked is when the assertions are turned on or off. When the assertions are turned off, they are completely removed from the function body from the compiler…

If so, this is exactly the desired outcome.

I think I was reacting to earlier comments that advocated against using macros here – my understanding of Julia facilities is that _some_ language construct is required that would work at an intermediate representation level. My expectation would have been for that to be macros, but perhaps that’s not the only way… I have not looked at your code to understand the details of thread safety in the latest design. I surmised from comments that there is a boolean flag that’s being read and written under some lock protection (the @toggle false, @toggle true thing). When Julia JIT decides to compile a function, does it read the same lock? Or is it read at parsing time? I am not educated about Julia “class loading” process (compared with, say, Java spec of the process [Chapter&nbsp;5.&nbsp;Loading, Linking, and Initializing](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html). Note an explicit mention of when assertions are enabled).

Also note that in Java the assertions can be enabled in one class and disabled in another, etc. It’s not a matter of “entering and leaving debug mode all the time”, it’s actually very useful for isolating bugs in some suspect areas while avoiding slowdowns in the rest of runtime. Java assertion facility is also convenient because “packages” are organized in a tree and there is a notion of “subpackages” with associated ability to set assertion status at subtree levels. Quoting [https://docs.oracle.com/cd/E19683-01/806-7930/assert-4/index.html:](https://docs.oracle.com/cd/E19683-01/806-7930/assert-4/index.html:)

> With one argument ending in “…”, assertions are enabled in the specified package and **any subpackages** by default. If the argument is simply “…”, assertions are enabled in the unnamed package in the current working directory. With one argument not ending in “…”, assertions are enabled in the specified class.

(Java assertions can be enabled at various levels of granularity via JVM command line arguments but also at runtime, via the ClassLoader API. [ClassLoader (Java Platform SE 7 )](https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#setPackageAssertionStatus(java.lang.String,%20boolean)) This is all very nice for “componentization”.)

I wish Julia would adopt a Java-like naming convention for packages/modules and avoid R/python “wild west” future in that regard … 🤓

---

<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: [November 25, 2019, 5:03pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/17 "2019-11-25T17:03:11Z")

</div>

> [@vladium](#):
>
> I have not looked at your code to understand the details of thread safety in the latest design.

It’s incredibly simple and actually shorter than your above post. Here’s literally all the package code:

```julia
assert_toggle() = true

macro toggled_assert(cond, text=nothing)
    if text==nothing
        assert_stmt = esc(:(@assert $cond))
    else
        assert_stmt = esc(:(@assert $cond $text))
    end
    :(assert_toggle() ? $assert_stmt : nothing)
end

const toggle_lock = ReentrantLock()

function toggle(enable::Bool)
    lock(toggle_lock) do
        @eval ToggleableAsserts assert_toggle() = $enable
        on_or_off = enable ? "on." : "off."
        @info "Toggleable asserts turned "*on_or_off
    end
end

```

So if I write `@toggled_assert cond` somewhere, that will be macroexpanded to

```julia
if assert_toggle()
   @assert cond
end

```

And then writing `toggle(false)` will overwrite the definition of `assert_toggle` to

```julia
assert_toggle() = false

```

Due to julia’s code invalidation machinery, this makes any method relying on `assert_toggle` to get recompiled. Since `assert_toggle` is a constant function, code saying  
`if assert_toggle()` is equivalent to `if false` and so those blocks are completely skipped by the compiler.

> [@vladium](#):
>
> Also note that in Java the assertions can be enabled in one class and disabled in another,

Something similar is definitely possible (and easy!) here too, but I haven’t gotten around to it yet.

---

<div class="post-metadata">

### Author: ![vladium](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vladium/32/11526_2.png) [@vladium](https://discourse.julialang.org/u/vladium)
#### Post date: [November 25, 2019, 5:29pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/18 "2019-11-25T17:29:26Z")

</div>

Great. I need to learn more about Julia’s code loading process. I was not aware that it could track and recompile dependencies. (could get expensive in some scenarios, I’d imagine).

---

<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: [November 25, 2019, 6:42pm UTC](https://discourse.julialang.org/t/ann-toggleableasserts-jl/31291/19 "2019-11-25T18:42:59Z")

</div>

> [@vladium](#):
>
> (could get expensive in some scenarios, I’d imagine)

You only pay for what you use. If you have a package loaded that uses `@toggled_assert` a thousand times and you do `toggle(false)`, those thousand methods only get recompiled if you (or a function you called) actually call them. The cost isn’t up front.

I don’t really see any way that one could lessen this cost. Since we want the assertions to be elided, the only way to do that is recompilation.
