Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: read eval print loop facilities #39165

Open
gonzojive opened this issue May 20, 2020 · 5 comments
Open

proposal: read eval print loop facilities #39165

gonzojive opened this issue May 20, 2020 · 5 comments
Labels
Projects
Milestone

Comments

@gonzojive
Copy link

@gonzojive gonzojive commented May 20, 2020

Many languages offer read eval print loops (REPLs) that allow interactive development of computer programs. REPLs are useful and timeless, and Go should have one.

Go has survived without a REPL, perhaps because compilation speed has always been a project priority. Often full, repeated re-compilation and -execution is a good substitute for a REPL, but there are advantages to working with a runtime:

  1. For large programs, such as those that use big libraries like TensorFlow, linking and starting a new binary can be "slow." Say a minute. As fast as the compiler and linker are, most REPLs have milliseconds of latency from keyboard input until execution begins.

  2. When a large amount of data or state is present in the runtime, it may be be expensive, inconvenient, or infeasible to re-execute the altered program to observe the same state. During development of a web scraper, for instance, it may take half an hour to download a set of webpages again. The programmer could restructure the program to persist the data and load it, but this is an unnecessary burden. ML engineers routinely load large tables of data for interactive analysis in colab notebooks, a web-based repl.

The proposal is simple, perhaps too simple: REPLs are great, and go should have one. If a broad proposal is insufficient, I can attempt to work out more detail.


A brief note on my exploration so far:

One approach would be to extend the features of the plugin system to allow incremental definition of packages. The finality of a package is where I have struggled in implementing a REPL based on existing facilities: new methods cannot be defined, references cannot be made to unexported variables, and so forth. Could the plugin system allow a new version of a package to be installed that references existing internal package variables, functions, and types? Perhaps with restrictions, such as no replacement of existing functions, and packages that can be replaced need to be compiled with a special flag.

Without the ability to modify an existing package, it's already possible to use the plugin system to write a kind of go shell. For example, variables defined at top level can be put into a shell-managed package and referenced by manipulation of identifiers in the ast read by the shell. But this is all a bit clunky and limited. What we really want is to write a package like normal and add pieces of the package to the runtime as they are ready.

(I am not so concerned about supporting the deletion of a package or aspects of a package, but other languages do support such deletions at runtime with various limitations.)

@gopherbot gopherbot added this to the Proposal milestone May 20, 2020
@gopherbot gopherbot added the Proposal label May 20, 2020
@robpike
Copy link
Contributor

@robpike robpike commented May 20, 2020

@gonzojive
Copy link
Author

@gonzojive gonzojive commented May 20, 2020

Thanks. My experience with a repl is in Common Lisp (SBCL) where code is compiled and evaluated. The REPL solutions I have seen for Go seem to require writing an interpreter, not using the usual compilation pathway. Without compilation, the repl code can be slower, differ in subtle ways from compiled code, and overall feel second class.

The technical heart of the proposal, which is only implied at the moment, is being able to append to or replace parts of an existing package in a runtime.

@gonzojive gonzojive closed this May 20, 2020
@gonzojive gonzojive reopened this May 20, 2020
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented May 20, 2020

Do we really need plugins for a REPL? Since the compiler is fast, can't we simply recompile and re-run the file after each input line?

@gonzojive
Copy link
Author

@gonzojive gonzojive commented May 20, 2020

Do we really need plugins for a REPL? Since the compiler is fast, can't we simply recompile and re-run the file after each input line?

Are you referring to re-running the full executable? I mention in the original post why this may be inadequate for certain workflows - workflows that are common practice in other languages. Perhaps you are referring to something else.

@dpinela
Copy link
Contributor

@dpinela dpinela commented May 21, 2020

Also, while the compiler is fast, it isn't instantaneous, so that approach gets slower the long you keep a REPL session open.

@rsc rsc added this to Incoming in Proposals Jun 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Proposals
Incoming
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.