Keno’s recent changes on in-development versions of Julia enable safe redefinition of constants, including, for example, struct types. This is great, especially for interactive use, Revise.jl, etc.
However, I think it’d be good if there was a command-line option to warn on the redefinition of a constant, furthermore, this should probably be turned on by default for package tests.
It was always common for include to be misused (including the same source file repeatedly), and --warn-overwrite=yes is helpful in this regard, as it warns on method overwrite, however now it will be possible to redefine any constant, so the failure modes on include-misuse are expanded.
I propose either of these changes:
add a new command-line option, say --warn-redefine-constant=yes, and enable it by default for package tests
adjust --warn-overwrite=yes to warn on the redefinition of any constant
Probably a good idea to allow by default in the REPL and error by default in a script. People seem to think it’s ok to do things that emit warnings for some reason. Of course now it’s actually fairly safe, just potentially slow since it invalidates code.
How far does it go? I can imagine backedges can help change methods that access those constants upon execution, whatever runtime errors those may cause, but does it also change accesses in already evaluated method/struct definitions? For example, reassigning a non-type to a constant type name might still be callable, but it won’t make sense in annotations and type bounds. Even if we restrict type names to types, reassigning a concrete type to an abstract type’s name can result in concrete supertyping in other struct definitions.
That’s the part I can see happening, e.g. foo() = AbstractType() getting invalidated. I’m asking about something like foo(x::AbstractType) = x or struct Bar <: AbstractType end; AbstractType = 1 should fail for both cases, and AbstractType = Int should fail for the latter.
I’ve noticed these don’t seem to be Revise-d at the moment, I’d think this either means more back-edges are needed, or when redefining a struct something like methodswith needs to be called.