Stop running code pasted into REPL on first error

Hi there, first time poster so not sure if this is the appropriate venue for this.

My workflow involves writing code in a text editor and pasting it into a terminal (I use the Terminus and SendCode plugins in Sublime Text, resulting in a setup similar to Juno or Hydrogen in Atom). One thing that causes me a lot of headaches is that I try to paste in a large chunk of code and the first line throws an error. But Julia goes on happily trying to execute the rest of the code, sometimes making distributed calls that aren’t easy to interrupt.

In the IPython shell (which, like Julia, has bracketed paste) I don’t get this problem. If you paste a block of code in, it stops running at the first error. This seems to me to be a much more sane default behavior. Is there any way to get this behavior in the Julia REPL?

1 Like

Obvious question: Why not include your code, or better yet, make a module (and use Revise)? What you’re doing seems to flow against the tau of Julia. I’m guessing there are more effective workflows. Are you open to alternatives or do you need to work this way for some reason?

Very fair question. I do use include for sections of the code that are relatively stable. The workflow I described is for developing code and for interactive analysis type of work (as you one might do in a jupyter notebook). For example, in one file, I might have a short section that fits models (taking 20 minutes or so) and then below it I have a section with diagnostics that I may want to edit based on the outcome of that 20-minute fitting process. I could split these into separate files, I suppose, but ultimately this will become one script that does the fitting and generates summary result, so it’s easier for me to keep it in one file when I’m developing it.

EDIT: a second factor is that I am often editing local files but running them on a remote server. Using include means I risk accidentally running an old version because my fswatch-rysync command hasn’t finished updating the server files.

Your workflow is not so uncommon. If you are open to alternate suggestions, myself and other could maybe help, but I don’t want to assume.

1 Like

Please! I’m always looking for ways to work more efficiently!

1 Like

Another question that will influence suggestions:

Are you open to using VS Code?

The Juno and VS Code teams recently merged and future work is focused on making VS Code the de facto IDE for Julia development. It already has most of what you want and it is pretty amazing.

Here are two videos definitely worth watching:

Switching editors is not always an option and that is fine. You should be able to have a better developer experience than your current state even in Sublime, but just checking :slight_smile:

That… is probably not a workable option for me. I tried Juno for a couple months but abandoned it because of how dependent I am on the sublime configuration I’ve built up over the last 10 years.

I will give it a look though, just in case it has something that really blows me away.

1 Like

For what it is worth:

With Microsoft acquiring Github, it seems pretty clear the Atom trend is unlikely to reverse and I can’t think of anything that would reverse the Sublime trend. 10 years sounds like a good run and maybe time to consider moving on :slight_smile:

If code is submitted via CTRL + Enter, the issue described in post one remains vs code as far as I know

1 Like

I wouldn’t be surprised, so there is some low hanging fruit to help @fredcallaway with his workflow.

Instead of a huge script that gets pasted to the REPL or executed in VS Code, at a minimum, I would recommend putting that into a module or at least a giant function. Both would terminate execution when it hits an error.

For interactivity, something else maybe worth looking at is Pluto.jl.

Any other suggestions?

Wow, Pluto looks amazing! This looks like it will be especially useful for code that isn’t too computationally intensive.

However, I still think the original request for handling errors in the REPL is a legitimate one. Whether or not it is the best practice, I’m sure I’m not the only one who pastes blocks of code into a REPL. And the current behavior of continuing to execute lines after an error is probably not what most people would want.

2 Likes

Given limited resources of open-source projects and other priorities, I doubt this non-problem is going to be on anyone’s radar any time soon. In fact, this is the very first “no no” listed in the Julia style guide:

https://docs.julialang.org/en/v1/manual/style-guide/#Write-functions,-not-just-scripts-1

:slight_smile:

Also, if you are dumping a big script into the REPL, I am pretty sure you aren’t making your variables const , which means you’re hitting the first “no no” on the Julia performance tips too :sweat_smile:

https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-global-variables-1

I definitely think you should consider rethinking your workflow :pray:

2 Likes

OK. For what it’s worth, I haven’t noticed any performance issues using global variables as long as no serious processing is done on them while they’re in global scope. But I understand that I’m not following best practices and so my specific needs aren’t the priority for devs.

Thanks for taking the time to help me out!

I use VSCode, but I still sometimes need to eval some code in the global scope. They are not long, around 3 or 4 lines usually, but it’d be good if the REPL stopped evaling them if an error occurred. Putting everything under a function is a good practice, but when one is in the initial stage of developing the function, using the global scope gives one more power to debug and explore various things rapidly. Of course, most languages don’t have a REPL, and a good debugger can cover some of the same uses, but the REPL workflow can also be powerful.

1 Like

Btw, another great way to learn better workflows is participating in some of the Julia live code streams. Those guys are pretty active and it is fun.

https://julialang.live/

:slight_smile:

[Edit: Not to mention all the awesome presentations at the recent JuliaCon.]

Btw, one quick fix you could do regardless of editor is…

Starting with a big script like

.
.
.
# Lots of stuff
.
.
.

change this to

function run()
.
.
.
# Lots of stuff
.
.
.
end; run()

If you paste this into the REPL, it should terminate the way you are expecting if there is an error (and have better performance).

Is that different from a let block? This is my current workaround (although as @NightMachinary mentions, it prevents you from retroactively inspecting the local variables)

let
# Lots of stuff
end
2 Likes

That also seems fine :+1:

Edit: Does it do what you expect?

Still, if you want to inspect variables, I don’t think you can do better than wrapping it in a module in VS Code with the debugger. You can see all variables in your workspace :heart_eyes:

Maybe clunky, but working:

try
  # lots of stuff
catch
end
1 Like

If you like the behavior of IPython, you can get something similar by installing IJulia in your project, then running
jupyter console --kernel=julia-1.5

I’d ask @stevengj if such a work environment is a reasonable choice. (I’ve only tried it as an experiment.)
One difference is that history from previous sessions does not seem to be maintained.