I see @assert used frequently in the wild to check function inputs, and it looks a lot nicer than putting a bunch of if/throw statements at the top of every function.
However, ModernJuliaWorkflows says:
To test the arguments provided to the functions within your code (for instance their sign or value), avoid @assert (which can be deactivated) and use ArgCheck.jl instead.
and @assert’s docstring says:
Warning
│ An assert might be disabled at various optimization levels. Assert
│ should therefore only be used as a debugging tool and not used for
│ authentication verification (e.g., verifying passwords), nor should
│ side effects needed for the function to work correctly be used
│ inside of asserts.
So,
Why do I still see @assert in so many popular packages despite the warnings?
Can’t we just update @assert to natively do whatever makes ArgCheck better?
It seems silly to tell people to go find external package tools because the built-in tools are not reliable enough. (I wonder similarly about @time and @btime.)
||/&& are also really useful for these short error checks and not quite as large/tedious as the equivalent if block. They’re still longer than a naked @assert (with the auto-generated error message) but about as long as one with a custom message.
Like
x > 0 || throw(DomainError(x,"x must be positive"))
I personally do not like seeing Boolean logic for control flow like that. It seems like a computer science hack that is not very readable for mortals. Related Github Issue
I can’t really follow the discussion, but hopefully we get a suitable alternative before @asserts are just turned off!
Since @assert may be removed in future, you should avoid using @assert with side effects as an essential part the program flow. For example, code like this would be problematic:
v = [1, 2]
@assert pop!(v) == 2 # may stop working in future
println(last(v))