This is a common error for interactive development:
julia> struct MyType a end
julia> isapprox(a::MyType, b::MyType) = abs(a.a-a.b) ≤ 10 # FORGOT TO IMPORT
isapprox (generic function with 1 method)
julia> import Base.isapprox # SO LET'S MAKE UP FOR IT
WARNING: import of Base.isapprox into Main conflicts with an existing identifier; ignored.
I wonder if it would be possible to do something similar for Julia. Strictly for interactive development. The only remedy I know of is restarting (and of course not doing development in Main, but that just happens).
Another approach, complementary, would be [as illustration] to inquire “do you want to import isapprox?” As it is, it is much much rarer to parallel operationalize an importable namthan it is to omit the module qualification. Others will have better ways to get here. imo this is an incremental way forward, allowing Julia’s collaborative spirit to just work more so while we do.
unintern seems like a weird name for this since the symbol is not the issue, it’s the resolved binding that’s the issue. The current situation is pretty annoying and it would be great to figure out a way that trying the wrong thing doesn’t force you to restart your REPL session.
How about an undo buffer at the REPL? Hitting Cmd-Z would strike out the last command(s) and restore the global state. This might require a lot of memory shuffling, but other memory-intensive software like Photoshop still do it.
(Of course the size of the buffer should be user-definable, and setting it to zero would disable the feature.)
Not that slow. I think only one page (maybe 4 kb) would be copied if one element of a large array is changed. And the delay only happens when the user hits “Enter”. I think the key-press itself will take more time than the memory copy most of the time.
Another place to do this would be in Jypyter notebooks. If the Julia/Python/whatever process is forked before executing each code cell, then one could at any time modify a cell and re-evaluate the rest of the document without having to re-run any previous cells. (And then one could undo the entire change with Cmd-Z.)
A general undo feature would also be helpful if you accidentally modify the wrong array at the REPL, or even if you get a core dump. These are things that could never be handled by the language itself.
I don’t think one needs to resort to (potentially very expensive) hacks, as I hope that a solution will be provided by Julia in the medium run.
You mean “surprisingly cheap” hacks.
I don’t know that julia can do anything meaningfully better than this; at least performance-wise.
I think an undo requires storing the global state, in a turing complete language.
Or at least storing the parts of the state that can possibly change.
(Working out which parts can definitely (rather than possibly) change I think runs into the halting problem)
There is no better mechanism for that than copy-on-write.
Of course, if it is just unbinding, rather than an univeral undo, that statement does not apply,
at least not as much.
Feels a lot like #265