REPL Development in Go with Gore

A Julia developer setting up a Julia style development process in Go

Erik Engheim
4 min readFeb 19, 2020

I normally write code using Julia these days and over the years I have come to love using REPL style development in dynamic languages like Julia, Python and JavaScript.

So when refreshing my Go programming skills, I want to have some of the same experience. Go has several REPL alternatives and I have not tried them all. I have been quite happy with Gore, which is what I will cover here.

Gore works in an almost banal way. It simply gradually builds up a program as you enter stuff on the REPL prompt. Each time you add a line it runs the whole program.

Kind of primitive compared to a REPL in a dynamic language but it works surprisingly well. The nice thing about this is that you can actually dump the program that Gore builds up.

Step by Step Installation

The current module system in Go has gotten me confused, but it seems like you can kind of pretend it does not exist. Defining GOPATH environment variable still seems useful in go1.13 even if supposedly you don't need it anymore. Here is my configuration for my fish shell.

set -x GOPATH $HOME/Development/go
set -x PATH $PATH /usr/local/go/bin $GOPATH/bin

You would have to modify this slightly if you use bash or zsh. The point is that many of the go packages you install require $GOPATH/bin or /usr/local/go/bin to be in your path for the OS to find them.

Assuming you are on macOS (that is what I use), you simply install the latest version of Go using Homebrew, or download install package from go homepage.

$ brew install go

Install Go command completion gocode

$ go get -u github.com/mdempsky/gocode

This will place the source code for gocode into the $GOPATH/src/github.com/mdempsky/gocode directory. Basically the path matches the location of the package on the internet. While the corresponding executable is stored at $GOPATH/bin/gocode.

If everything was setup correctly, you should be able to write:

$ which gocode
$GOPATH/bin/gocode

Next you install Gore itself.

$ go get -u github.com/motemen/gore/cmd/gore

It should also end up as code under $GOPATH/src and an executable under $GOPATH/bin.

Usage

Gore comes with a decent online help to get you started.

$ gore
gore version 0.5.0 :help for help
gore> :help
:import <package> import a package
:type <expr> print the type of expression
:print print current source
:write [<file>] write out current source
:clear clear the codes
:doc <expr or pkg> show documentation
:help show this help
:quit quit the session
gore>

If you want to import the fmt package which you use for Prinln you can do this:

gore> :import fmt
gore> fmt.Println("Hello world")
Hello world
12
nil
gore>

Notice you don’t write the package name quoted as you would with normal Go code.

Creating and Importing your own packages

Of course what we are really interested in when doing REPL style development is to be able to import our own packages and testing them. I have found different ways of doing this.

If you want to create a package foobar you do the following:

  1. Create a directory for your package with e.g. mkdir -p $GOPATH/src/foobar
  2. Add some source code file to directory touch $GOPATH/src/foobar/baz.go
  3. Put package foobar at the top of the baz.go file, and type in whatever functions or types you want.
  4. Install package by going into package directory cd $GOPATH/src/foobar and type go install. You may not need this step.

Here is an example of a function calculating the factorial in my baz.go file:

package foobar

func Fac(x int) int {
prod := 1
for x > 1 {
prod *= x
x -= 1
}
return prod
}

To use this package in Gore we should be able to easily import this package. But I will get this error message.

$ gore
gore version 0.5.0 :help for help
gore> :import foobar
import: could not import "foobar"
gore>

I don’t know why as it works in normal Go source code files. A workaround is to copy the files to /usr/local/go/src which is where your Go installation puts the builtin go packages. Not a great solution IMHO.

Fortunately Gore has another nice workaround, which allows you to put your Go source code files anywhere:

$ gore --context baz.go
gore version 0.5.0 :help for help
added file baz.go
gore> Fac(3)
6

Unfortunately you have to exit core and do this over again each time you change the contents of baz.go

Why do REPL Style Development?

If you are new to REPL style development, you may wonder what the benefits are. One simple benefit is that you can think in terms of package development rather than in terms of programs. You never need to define a main-function and pollute it with a bunch of throw away code just to test your functions.

Just write your package with the functions you want and test them in the REPL afterwards. Why not write proper tests instead? Because initially you are writing code in an exploratory fashion and don’t care about figuring out proper tests for these functions.

You can create objects in the REPL and immediately see their contents. You can check types of variables and inspect member variables. Especially when learning a language this is a very efficient way of working. Rather than looking up all sorts of info in the documentation about what types a function returns and what you can do with it, you can simply try it out in the REPL.

For instance, maybe you wonder whether 5.6 is a float64 or float32. Instead of figuring out what term to search for in the Go manual, you can just write:

gore> :type 5.6
float64

--

--

Erik Engheim
Erik Engheim

Written by Erik Engheim

Geek dad, living in Oslo, Norway with passion for UX, Julia programming, science, teaching, reading and writing.

No responses yet