Philosophy on asserts

Curious what the view on asserts in released, production code is.

Working on PR for Pkg.TOML. It has lots of places that trigger assert error on nothing values with a get method: get(x) = (@assert !isnull(x); x). In the package, nothing is often acceptable, but requires explicit handling. Note that isnull() returns true or false based when whether the argument is nothing–precedes the isnothing() function in Julia 1.1.

In every instance of the use of this get method, it is wrapped in or preceded by an if statement that properly handles the nothing value, consistent with the rules of TOML, including generating appropriate errors where necessary.

Before all these “nothings” were explicitly handled, the asserts were a good testing strategy–if you have the appropriate test cases, you’ll find out where you failed to handle a nothing. In the production code, should the asserts be left in? As the code is currently written, none of the asserts can be raised. I’m inclined to remove them.

For comparison, the JSON package in the registry contains no @asserts.

@assert is documented that it might be removed at some optimization level in the future (it currently is never removed).

So doing something like

@assert password_is_correct(pwd)
launch_the_nukes()

is not recommended.

7 Likes

Why does your comment seem so topical?
:blush:

Given that, I’ve removed the asserts. They were, in any case, no ops.

I don’t see how that follows from what Kristoffer said.
I think the message is that (in the future), Julia will have a runtime option that can disable @assert statements, so don’t use for critical control flow.

Are they?
Aren’t they runtime checks “asserting” x is not null?

I noted that each assert was a branch in an if statement that already tested explicitly for nothing values or immediately preceded by a test and return. None of the asserts could ever be raised because of these explicit tests.

In the code I referenced nothing values are often valid, signaling that no more input data was present in a stream. The if statements ensured that proper values were returned (or assigned). This is better than raising an assert and aborting. The asserts
were a great way to find all those places during testing.

The Julia version seems clearer than one of the Python implementations I looked at. It seems reasonable that the first person who wrote it started with code in another language, did much more than a port to Julia, but like anyone had only so much time.

Neither Kristoffer nor I wrote this code. It serves its purpose and neither of us invested that much time in it. Like lots of code, another pair of eyes finds something to make incrementally better, fix a bug, nudge performance a bit or just do some housekeeping.

The feature to suppress asserts with a runtime switch is great. Asserts that test for required conditions can be left in the source and be easily switched back on for testing.

  • Lewis

You may be interested in

2 Likes