The Scala REPL is inferior to a bunch of other REPLs (Bash, Ruby, Python, ...) in that it does not handle Ctrl-C gracefully. The whole process dies, and you lose all your work, instead usually the last-command exiting and only rarely the whole-process dying
It turns out that solving the runaway-REPL problem is relatively easy:
sun.misc.Signal.handle(new Signal("INT"), new sun.misc.SignalHandler () {
def handle(sig: Signal) {
mainThread.stop()
}
})
This is all that is required at the top of the program. The REPL's own try-catch error recovery is sufficient to do the rest.
Notably, this uses sun.misc.* functionality, which I'm not sure is available on other JVMs. I'd guess they also provide similar signal-handling functionality (speculation). This also makes use of the @Deprecated Thread#stop() method, which apparently is unsafe. Also notably, the groovysh/jython REPLs shares the same behavior as Scala, in forcing you to terminate the process if you accidentally infinite loop.
However, I think that despite the fact that Thread#stop() is unsafe, it is no more unsafe than all the other things that the JVM provides (Runtime#exec anyone?). Furthermore, I think that a REPL providing a best-effort cleanup is still worth it, even if there are no guarantees: even trying to kill a separate process on your own machine can lead to the same problems that they deprecated Thread#stop() for! Similarly, you can easily get your Bash shell or OS into a state that it's unrecoverable and you need to re-boot.
I'm sure many of us make use of Bash's best-effort process-killing and are happy that a single bad ls doesn't force us to terminate and re-start our SSH session, even though most of us have had my bash-prompt force-killed due to process/system damage when it's really severe.
Is there any interest in putting this kind of thing into the main Scala distribution? I I could easily put this functionality into my own custom REPL (and I have
here) if people think using the deprecated
Thread#stop is too sketchy. But I do think that having the REPL not blow up you when you make a mistake would be of value to a lot of people, and would be willing to do the legwork necessary to test this on various platforms and JVMs. Worst come to worst we use reflection to load the thing and just no-op otherwise.
Thoughts?