Speeding up the exit(); restart REPL loop in VSCode

I use Revise, but I frequently change struct definitions, which requires to exit Julia and start another REPL, wait for my package to compile. You know the drill; there must be a better way! How do you handle this?

The perfect solution would be for VSCode to always have two REPLs open, automatically opening a new one and loading my code whenever I close a stale REPL.

…any chance someone knows how to do this?

2 Likes

I think that having two simultaneous REPLs in VSCode is not yet supported, but there is ongoing work related to that; see:
https://github.com/julia-vscode/julia-vscode/issues/1030

I wonder why it’s unsupported. It’s trivial to open several python interpreters; why not so for Julia?

We provide very tight integration between the REPL and the UI in VS code with things like the workspace explorer etc, and those UI elements currently all assume that there is only one Julia REPL. We do plan to support more than one, but it will require a fair bit of work in the extension to robustly support that scenario.

You can of course always run multiple instances of Julia in shell instances that you start inside VS Code, but those won’t be hooked up to the integration points that the Julia extension provides (code execution, plot gallery etc.)

2 Likes

I’d suggest using inline evaluation to re-define your whole module, which allows for structs to be changed all you want (with the caveat that you need to redefine all previous instances of your structs to work with the “new” module’s functions). That usually gets you around needing to restart.

The idea of keeping multiple Julia process around to connect to is something we had in Juno, but usually caused more issues than it was worth. Without trying to restore at least the loaded packages it’s also not a tremendous time saver.

1 Like

I can’t get this to work; could you elaborate? I have

module ToyMod 
export Toy 

struct Toy
   a::Int 
end 

end

which I send to the REPL. I can successfully execute

using .ToyMod
toy=Toy(3)

Now I change ToyMod.Toy to include the additional b::Int; re-execute ToyMod in the REPL, but when I toy=Toy(3,4), it throws a MethodError.

Maybe you also repeated using .ToyMod after redefining ToyMod? If you did, then you should have seen something like:

WARNING: using ToyMod.Toy in module Main conflicts with an existing identifier.

This would mean that there is already a definition of the struct Toy in Main (the one imported the first time you executed using .ToyMod), and you are trying to modify it, which is not allowed. If you redefine the whole module, but don’t export Toy (or don’t try to import it twice), there should be no conflict, and ToyMod.Toy should reflect the new definition. (But if you already have some Toy object created with the older definition, then the situation can be messy.)

(This doesn’t work if you are tracking the module definition with Revise. You must really rebind ToyMod to a new module object, not just try to modify the definitions inside it, as said before regarding Maain.)

2 Likes

Got it. Thanks; it works now. To clarify, your suggestion still works if Revise is enabled. (Your parenthetical suggests otherwise). In short:

  1. Execute the module definition in the REPL
  2. Within the REPL do
julia> using .ToyMod 
julia> toy= ToyMod.Toy(3) 
  1. Now change ToyMod
  2. Re-execute it back in the REPL.

ToyMod.Toy will reflect the new module definition.

1 Like

Right, having Revise enabled won’t affect. What I meant is that the problem happens if you track the module with Revise. For instance, if you have the code of ToyMod in a file and load it with includet (not include).