If someone created a debugging environment for Go based on a VM, which also let one recompile source from within the debugger then continue execution, then it would be, for all intents and purposes, as productive and immediate as the old Smalltalk environments. You'd have the same small-grained cycles of inspecting state, modifying code, rewinding the stack to the place of your choosing, then getting immediate feedback.
Source code changes could be saved as log-structured patch files, which could then be thrown away or applied to the source tree as desired. One could also steal some ideas from the Smalltalk Change Log tool by adding similar editing, search, and filtering commands.
With tools like this, one could recompile for "interpreted debug mode," have complete visibility and control of runtime state to debug a problem, then take the resulting patch file and apply it to the source tree. It would be a best of both worlds scenario -- all the enhanced debugging of an interpreted runtime with the type safety and speed of compiled code.
Interactive coding is a very powerful way of working, it's one of the reasons I'm so productive in Mathematica.
At a Go talk he did, I raised the idea with Russ Cox of having a "repl" package that would allow one to instrument a running program with a live REPL to do debugging and development on it.
The reflect package is powerful enough to make some of that relatively straightforward, but one major problem is that Go can't construct new types at runtime. Another challenge would be dynamic linking of new code -- because the Go toolchain doesn't support dynamic linking there would seem to be no hope of say entering anonymous functions on the REPL.
Unless one builds a full Go interpreter -- but who wants to be in the business of maintaining a fully compliant Go interpreter that can interoperate with the Go runtime?
Still, calling existing functions and banging on variables would be pretty useful.
> one major problem is that Go can't construct new types at runtime.
The current implementations can't. I don't see any reason why one couldn't. In any case, I don't think that's such a big deal. One just goes from completely seamless interactive coding to mostly seamless interactive coding.
> Unless one builds a full Go interpreter
That is precisely what I was proposing. (Are you implying some sort of hard VM/interpreter dichotomy? I've met some people who implement VMs who think this is somewhat arbitrary.)
>but who wants to be in the business of maintaining a fully compliant Go interpreter that can interoperate with the Go runtime?
There would be no need to interoperate at all with the current Go runtime. One would have to have their own Go runtime, however. As an alternative, one could just target an emulator with no optimizations, then use debugging information and dirty tricks to map the new code with the old state in an entirely new process.
> Could you fake interpretation by continually recompiling everything?
That's pretty much what the modern JIT VM Smalltalk environments do. On recompiling a method, all the affected JIT compiled machine code is kicked out of the code cache, and you start from interpretation again, which eventually results in the "hot" code being JIT compiled again.
Source code changes could be saved as log-structured patch files, which could then be thrown away or applied to the source tree as desired. One could also steal some ideas from the Smalltalk Change Log tool by adding similar editing, search, and filtering commands.
With tools like this, one could recompile for "interpreted debug mode," have complete visibility and control of runtime state to debug a problem, then take the resulting patch file and apply it to the source tree. It would be a best of both worlds scenario -- all the enhanced debugging of an interpreted runtime with the type safety and speed of compiled code.