gopherdata / gophernotes

The Go kernel for Jupyter notebooks and nteract.
MIT License
3.83k stars 264 forks source link

Changes in a package without restarting the kernel #93

Open novikk opened 6 years ago

novikk commented 6 years ago

If I import a package and then make changes to a function in this package, these changes won't take any effect if I do not restart the kernel. Running the import again doesn't solve the issue, I need to restart the kernel, and re-run the imports.

cosmos72 commented 6 years ago

This is a limitation of gomacro interpreter, I will open an issue there

cosmos72 commented 6 years ago

Implemented upstream, see https://github.com/cosmos72/gomacro/issues/15

@dwhitena, please consider updating the vendored copy of gomacro - and adding a gophernote magic command that invokes fast.Interp.Comp.UnloadPackage(path string)

SpencerPark commented 6 years ago

Hi @cosmos72 you are on fire lately! On the note of magics these are actually an ipython thing and not a jupyter thing. They are implemented in the ipython kernel and not part of the protocol/notebooks but rather at the language level and so they are still missing support.

The approach to magics seems to be just a source->source transformation that just desugars any %[a-zA-Z][^\n]* into a function call (similar for cell magics). Any opinions on the magic syntax as you have been also doing some cool stuff with gomacro for supporting new language features. The other option is to continue with the % syntax to be consistent with the canonical implementation.

This is related to #65 so it might be best to continue over there.

cosmos72 commented 6 years ago

Thanks for the clarification @SpencerPark.

That's actually good news: it means no changes are needed in the Jupyter <-> gophernotes messaging protocol - it's just a matter of recognizing such magics in the received source code, and executing them.

Currently, gomacro uses the prefix : for these special commands that are not part of the language, as for example :help :env :inspect :quit :unload and others.
If % is the norm in Jupyter world, I can add it too - or make it configurable.

But there is one more point: such special commands are not supported by fast.Interp.Eval(), and I think they don't belong there. They are handled by classic.Interp.Repl() and classic.Interp.ReplStdin() before invoking fast.Interp.Eval(). This is not optimal and a legacy of when classic.Interp was the default interpreter - nowadays its REPL forwards calls to fast.Interp.Eval() by default.

So there are two steps to implement this feature:

  1. gomacro side: I should move support for special commands to a better place, for example by creating fast.Interp.Repl(*bufio.Reader)
  2. gophernotes side: once 1. is ready, use it instead of fast.Interp.Eval()
SpencerPark commented 6 years ago

Thanks for the update @cosmos72.

I don't believe gomacro needs any updates as long as the function invoked with the :commands are accessible which it seems they are.

The convention set with IPython's magics is that they are extensible and can be defined via user packages. I know IJulia uses Julia's own syntax for magics and there is a javascript kernel that uses % syntax but I don't believe there is really the precedent to stick with % if the language has a better syntax. From my understanding the closest thing is build comments which don't seem to apply here. I like the : syntax when used on it's own line but for cell magics do we just extend it to ::cell-magic-command?

Also going back to the first point we would most likely need the ability for users to define magics. With that in mind this introduces the need for a gophernotes runtime that is evaluated in the user space when the kernel is booted with some special values exposed to gomacro like the kernel/protocol functions.