Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding switch to disable assertions #7732

Closed
mlhetland opened this issue Jul 26, 2014 · 6 comments
Closed

Adding switch to disable assertions #7732

mlhetland opened this issue Jul 26, 2014 · 6 comments

Comments

@mlhetland
Copy link
Contributor

After a discussion on Julia-Users, it seems to me that at least some might agree with me that being able to turn off assertions could be a good idea. This is permitted in most languages, it seems. My suggestion is to follow the example of D, which I believe has made some sensible decisions on assertions and DbC in general. Their solution is to split assertions into two types, named assert and enforce. They then have a command-line switch named --release that turns off assert but leaves enforce in place. If we adopt such a switch, with an accessor similar to isinteractive(), it can be used also by others, similar to (but the negation of) the __debug__ variable in Python, which is set to True only if the -O switch is not supplied.

My suggestion is:

  • Add the switch --release at the Julia level (i.e., in client.jl) with a subsequently available accessor isrelease(), which is exported, so it can also be used by others (though this is an ancillary benefit).
  • Rename assert to enforce and @assert to @enforce.
  • Introduce new versions of assert and @assert that use isrelease() to determine whether to become a no-op or to delegate to enforce and @enforce, respectively. This will not entirely eliminate the cost of calls to assert, of course—one will still need to evaluate the arguments and execute the if-statement, but it will eliminate the cost (and the functionality) of @assert in release code.

The idea, then, is to use assert and @assert more for testing purposes, debugging and for checking for programming errors, and to use enforce and @enforce for error handling and input checking, and for any other kind of assertions one would want to keep in the code, regardless of release status.

I have made a stab at implementing the switch, function and macro. Because the switch only takes effect once client.jl is loaded, I have renamed the uses of assert to enforce in base/ (renamed all uses, for consistency, though not strictly necessary), but I left the uses in test/ alone. (I have updated repl.c but not docs, manpage or helpdb.jl, for example. And I haven't added any tests, as I didn't find any for the original assertion functionality, and I'm not sure what infrastructure you'd want to use to test command-line switches…)

The new function/macro are defined as follows—which I believe is not entirely correct…

assert(x) = isrelease() ? nothing : enforce(x)
macro assert(ex,msgs...)
    if isrelease()
        :nothing
    else
        :(@enforce(($ex),($msgs)...))
    end
end

It works for my simple ad hoc tests, but fails in, for example, test/bitarray.jl, where a call to @assert occurs inside another macro with an argument also named ex. I then get complaints on ex not existing. So I guess my quoting mojo isn't quite up to snuff, but I'm guessing this should be easy to fix? (Just calling @enforce gives me the wrong kind of return value, as far as I can see.)

Anyone interested in this? Should I submit a WIP pull request?

@mlhetland
Copy link
Contributor Author

Ah, I guess I forgot esc().

@mlhetland
Copy link
Contributor Author

Checked in my tentative implementation (mlhetland/julia@366e00a).

@mlhetland
Copy link
Contributor Author

An alternative would be to keep assert as it is, and introduce expect (or something like that) for the version that could be disabled. Less intrusive (but it would leave us without the rather standard functionality of being able to disable the most obvious form of assertion, assert).

@vtjnash
Copy link
Member

vtjnash commented Mar 25, 2016

related discussions in #15495 and #15514

@KristofferC
Copy link
Member

I would want an assert that check only when running in some sort of explicit debug mode. That way, asserts that are too costly for normal use can be added.

@KristofferC
Copy link
Member

Closing in favor of #10614

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants