Julia will do this. One can specialize or outright override existing function methods. Julia’s JIT compiler will even go back and recompile any code that may have depended on the old method to use the new.
Note of course this is dangerous when used carelessly - the system is intended for extending or specializing functions for new input types, rather than replacing methods. One fun thing to do is replace something fundamental like integer addition and watch everything immediately break, via e.g. Base.:+(a::Int64, b::Int64) = 0.
Base.:+(a::Int64, b::Int64) = 0
(While much of Julia’s compiler is written in Julia, it is itself is “immune” to such redefinitions because it lives in it’s own fixed “world”, but so much of the system depends on the standard libary that this instantly destroys any REPL session).
Julia is actually at the top of my list! I just finished reading the manual, and I find it a bit unclear about this. It seems to indicate that sometimes an already-compiled expression or incrementally-compiled module won’t see overrides that come later?