ANN: llgoi, an llgo-based REPL for Go

566 views
Skip to first unread message

Peter Collingbourne

unread,
Apr 5, 2015, 8:31:59 PM4/5/15
to golang-nuts, Andrew Wilkins
Hi all,

I'd like to announce that llgoi, a Go REPL I've been working on on and off for the past few months, has reached a reasonable level of stability. It supports expressions, statements, most declarations and imports, including binary imports from the standard library and source imports from $GOPATH.

The main advantage of this REPL over some other Go REPL efforts in the past (such as igo) is that this one integrates directly with a Go compiler, specifically llgo, which allows it to more easily persist state between lines, such as variable values and the binary code behind imported Go packages. For one thing, this means that expressions can be evaluated against large Go packages without needing a recompile after every line.

Example session:

  (llgo) 1+1
  #0 untyped int = 2
  (llgo) x := 1
  x untyped int = 1
  (llgo) x++
  (llgo) x
  #0 int = 2
  (llgo) import "fmt"
  (llgo) fmt.Println("hello world")
  hello world
  #0 int = 12
  #1 error (<nil>) = <nil>
  (llgo) for i := 0; i != 3; i++ {
         fmt.Println(i)
         }
  0
  1
  2
  (llgo) func foo() {
         fmt.Println("hello decl")
         }
  (llgo) foo()
  hello decl
  (llgo) import "golang.org/x/tools/go/types"
  (llgo) types.Eval("1+1", nil, nil)
  #0 golang.org/x/tools/go/types.TypeAndValue = {mode:4 Type:untyped int Value:2}
  #1 error (<nil>) = <nil>

llgoi is available on the x86-64 Linux platform. It is part of the llgo project, and you can get it by following the instructions in the llgo README. There is also more detailed documentation in the docs directory.

Having a Go REPL easily available has changed how I develop Go programs. For example, a month or so ago I had a need to write a one-off utility to gather some statistics. Having a REPL available allowed me to quickly experiment with various functions in my program simply by importing it into the REPL. I hope that it can help you program more effectively too!

Thanks,
Peter

minux

unread,
Apr 5, 2015, 11:35:10 PM4/5/15
to Peter Collingbourne, golang-nuts, Andrew Wilkins
Awesome project! Thanks Peter. It will definitely help further reducing my need for scripting languages. ;)

Sebastien Binet

unread,
Apr 6, 2015, 3:31:44 AM4/6/15
to Peter Collingbourne, golang-nuts, Andrew Wilkins
On Mon, Apr 6, 2015 at 2:31 AM, 'Peter Collingbourne' via golang-nuts
<golan...@googlegroups.com> wrote:
> Hi all,
>
> I'd like to announce that llgoi, a Go REPL I've been working on on and off
> for the past few months, has reached a reasonable level of stability. It
> supports expressions, statements, most declarations and imports, including
> binary imports from the standard library and source imports from $GOPATH.
>
> The main advantage of this REPL over some other Go REPL efforts in the past
> (such as igo) is that this one integrates directly with a Go compiler,
> specifically llgo, which allows it to more easily persist state between
> lines, such as variable values and the binary code behind imported Go
> packages. For one thing, this means that expressions can be evaluated
> against large Go packages without needing a recompile after every line.

that's really nice.
I like how you leveraged llvm's JIT to be able to import modules at runtime:
http://llvm.org/klaus/llgo/blob/master/cmd/llgoi/llgoi.go#L-139

does that work for modules with some parts written in assembly as well?
(I was waiting for gc to gain shared library support to be able to
import modules for io/go-eval)

[...]

> Having a Go REPL easily available has changed how I develop Go programs. For
> example, a month or so ago I had a need to write a one-off utility to gather
> some statistics. Having a REPL available allowed me to quickly experiment
> with various functions in my program simply by importing it into the REPL. I
> hope that it can help you program more effectively too!

yes, exploratory work (eg as done in science) nicely fits in that description.
that's why IPython, IJulia and the like strives in scientific circles.

I hope llgoi will soon be shipped with llvm installs.

-s

PS: minor nitpick. github.com/sbinet/igo (or rather, sbinet/go-eval)
doesn't rebuild/recompile after each line.

Peter Collingbourne

unread,
Apr 6, 2015, 3:55:58 AM4/6/15
to Sebastien Binet, golang-nuts, Andrew Wilkins
On Mon, Apr 6, 2015 at 12:31 AM, Sebastien Binet <seb....@gmail.com> wrote:
On Mon, Apr 6, 2015 at 2:31 AM, 'Peter Collingbourne' via golang-nuts
<golan...@googlegroups.com> wrote:
> Hi all,
>
> I'd like to announce that llgoi, a Go REPL I've been working on on and off
> for the past few months, has reached a reasonable level of stability. It
> supports expressions, statements, most declarations and imports, including
> binary imports from the standard library and source imports from $GOPATH.
>
> The main advantage of this REPL over some other Go REPL efforts in the past
> (such as igo) is that this one integrates directly with a Go compiler,
> specifically llgo, which allows it to more easily persist state between
> lines, such as variable values and the binary code behind imported Go
> packages. For one thing, this means that expressions can be evaluated
> against large Go packages without needing a recompile after every line.

that's really nice.
I like how you leveraged llvm's JIT to be able to import modules at runtime:
http://llvm.org/klaus/llgo/blob/master/cmd/llgoi/llgoi.go#L-139

does that work for modules with some parts written in assembly as well?
(I was waiting for gc to gain shared library support to be able to
import modules for io/go-eval)

It doesn't support packages that use assembly, and I have no plans to support it. I'm not really sure if it could work at all because llgo uses a different ABI to gc. Probably what would be more feasible (but still rather difficult) is adding support for packages that use cgo.

> Having a Go REPL easily available has changed how I develop Go programs. For
> example, a month or so ago I had a need to write a one-off utility to gather
> some statistics. Having a REPL available allowed me to quickly experiment
> with various functions in my program simply by importing it into the REPL. I
> hope that it can help you program more effectively too!

yes, exploratory work (eg as done in science) nicely fits in that description.
that's why IPython, IJulia and the like strives in scientific circles.

I hope llgoi will soon be shipped with llvm installs.

Agree. We'll see if we can do that for the next release.

-s

PS: minor nitpick. github.com/sbinet/igo (or rather, sbinet/go-eval)
doesn't rebuild/recompile after each line.

Ah yes, you are quite right, my mistake. I must have been thinking of another REPL (perhaps go-repl).

Thanks,
Peter

Rob Pike

unread,
Apr 6, 2015, 11:22:49 AM4/6/15
to Peter Collingbourne, golang-nuts, Andrew Wilkins
Nice work. Two small but important points.

First, it's noisy. This little demo shows more type and module information than data, almost all of it not explicitly requested by the user. For debugging the interpreter that's fine, but from a usability perspective it could be quieter.

Second, please make sure that any output it prints spontaneously (as opposed to what the user requests through Printf etc.) is valid input again. The text on the screen is often useful as input again, but it's clumsy if the output must be edited first. As an obvious candidate here, even though I doubt the value of telling me that 2 is an untyped int every time it comes up, the text

#0 untyped int = 2

would be more convenient if laid out like this:

// untyped int
// 2

or maybe even

// untyped int
2

-rob


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Wilkins

unread,
Apr 6, 2015, 9:12:51 PM4/6/15
to Rob Pike, Peter Collingbourne, golang-nuts
On Mon, 6 Apr 2015 at 23:22 Rob Pike <r...@golang.org> wrote:
Nice work. Two small but important points.

First, it's noisy. This little demo shows more type and module information than data, almost all of it not explicitly requested by the user. For debugging the interpreter that's fine, but from a usability perspective it could be quieter.

Second, please make sure that any output it prints spontaneously (as opposed to what the user requests through Printf etc.) is valid input again. The text on the screen is often useful as input again, but it's clumsy if the output must be edited first. As an obvious candidate here, even though I doubt the value of telling me that 2 is an untyped int every time it comes up, the text

#0 untyped int = 2

would be more convenient if laid out like this:

// untyped int
// 2

or maybe even

// untyped int
2

I'm inclined to relegate the type information and package import tracing to a verbose mode. Either way, using comment syntax SGTM.

Peter Collingbourne

unread,
Apr 6, 2015, 10:27:27 PM4/6/15
to Rob Pike, golang-nuts, Andrew Wilkins
Thank you Rob. Your suggestions make a lot of sense. It occurred to me that the type information will almost always be available where it matters if the interpreter's output is to look like valid input, so I definitely agree that it should be omitted.

Peter

gordon...@gmail.com

unread,
Apr 7, 2015, 4:08:46 PM4/7/15
to golan...@googlegroups.com, axw...@gmail.com, p...@google.com
Nice!  I'm sure I'll check it out at some point.

Just one comment, this doesn't look right:

  (llgo) x := 1
  x untyped int = 1

Shouldn't x have type int?

Peter Collingbourne

unread,
Apr 7, 2015, 5:49:13 PM4/7/15
to gordon...@gmail.com, golang-nuts, Andrew Wilkins
It should, and indeed does; in this case, the wrong type is printed. This issue should become moot once I get around to making the tool less noisy.

Peter
Reply all
Reply to author
Forward
0 new messages