Go Environment

Default environment for the Go language

This notebook describes and creates a reusable environment for Go Jupyter runtimes in Nextjournal. Check out the showcase if you want to see what the environment contains. To see how it’s built, see setup.

Nextjournal's Go environment has two Jupyter kernels available:

  • lgo, a standalone kernel currently running on v1.9.7 of the official Go compiler, because of regressions in more recent versions.

  • gophernotes, which comes with its own unofficial Go interpreter, compiled with the official Go v1.13.5 compiler.

The default is lgo, for speed and somewhat richer Jupyter support. To use lgo with the official Go compiler version 1.9.7, simply remix the Nextjournal Go template. To switch to the gophernotes kernel after remixing the template (see image below):

  • Scroll to the bottom of the notebook.

  • Expand the Runtime Languages section.

  • Access the ··· menu, then Configure...

  • In the expanded panel, re-select Go in the top menu.

  • Once loaded, select the Go (gnotes) kernel in the lower menu.

  • Click the Save & Add button to insert a cell with the new gophernotes runtime.

Showcase

Go-Chart

// This sample is copied from https://github.com/wcharczuk/go-chart/tree/master/_examples/stacked_bar
import (
  "bytes"
  "fmt"
  "os"
  
  "github.com/wcharczuk/go-chart"
)
sbc := chart.StackedBarChart{
	Title: "Test Stacked Bar Chart",
	Background: chart.Style{
		Padding: chart.Box{
			Top: 40,
		},
	},
	Height: 512,
	Bars: []chart.StackedBar{
		{
			Name: "This is a very long string to test word break wrapping.",
			Values: []chart.Value{
				{Value: 5, Label: "Blue"},
				{Value: 5, Label: "Green"},
				{Value: 4, Label: "Gray"},
				{Value: 3, Label: "Orange"},
				{Value: 3, Label: "Test"},
				{Value: 2, Label: "??"},
				{Value: 1, Label: "!!"},
			},
		},
		{
			Name: "Test",
			Values: []chart.Value{
				{Value: 10, Label: "Blue"},
				{Value: 5, Label: "Green"},
				{Value: 1, Label: "Gray"},
			},
		},
		{
			Name: "Test 2",
			Values: []chart.Value{
				{Value: 10, Label: "Blue"},
				{Value: 6, Label: "Green"},
				{Value: 4, Label: "Gray"},
			},
		},
	},
}
var buf bytes.Buffer
err := sbc.Render(chart.PNG, &buf)
if err != nil {
    fmt.Printf("Error rendering chart: %v\n", err)
    return
}
_ctx.Display.PNG(buf.Bytes(), nil)
15.4s
Go lgo/1.9 Test (Go (lgo))
Go

Setup

Build the Go Environment

Download Go binaries.

for ver in $GO_VERSION $GO_EX_VERSIONS; do
  FILENAME="go${ver}.linux-amd64.tar.gz"
  FILEURL="https://dl.google.com/go/${FILENAME}"
  
  wget --progress=bar:force ${FILEURL} ${FILEURL}.sha256
  echo " ${FILENAME}" >> ${FILENAME}.sha256
  sha256sum -c ${FILENAME}.sha256
done
tar -cf /results/goses.tar go*.tar.gz
4.9s
Go (Bash)
goses.tar

Install Go(s).

mkdir -p /opt/go/packages
cd /opt/go
tar -xf NJ__REF_
for ver in $GO_VERSION $GO_EX_VERSIONS; do
  tar -zxf go${ver}.linux-amd64.tar.gz
  mv go ${ver}
  rm go${ver}.linux-amd64.tar.gz
done
ln -s ${GO_VERSION} default
15.4s
Go (Bash)

lgo needs 1.9 because of bugs in Go.

mkdir -p /opt/go/lgo
go get github.com/yunabe/lgo/cmd/lgo
go get -d github.com/yunabe/lgo/cmd/lgo-internal
lgo install
python3 $GOPATH/src/github.com/yunabe/lgo/bin/install_kernel
56.8s
Go (Bash)

gophernotes is fine with 1.13.

/opt/go/1.13.5/bin/go get -u github.com/gopherdata/gophernotes
mkdir -p /usr/local/share/jupyter/kernels/gophernotes
cp $GOPATH/src/github.com/gopherdata/gophernotes/kernel/* \
  /usr/local/share/jupyter/kernels/gophernotes/
69.2s
Go (Bash)

Make the display name descriptive.

sed -i 's/"display_name": "Go"/"display_name": "Go (gnotes)"/' \
  /usr/local/share/jupyter/kernels/*/kernel.json
0.2s
Go (Bash)

Install some libraries.

go get -u github.com/wcharczuk/go-chart
/opt/go/1.13.5/bin/go get -u github.com/wcharczuk/go-chart
/opt/go/1.13.5/bin/go get -u -t gonum.org/v1/gonum/...
/opt/go/1.13.5/bin/go get -u -t gonum.org/v1/plot/...
85.2s
Go (Bash)

Check everything.

du -hsx /
go version
jupyter kernelspec list
4.5s
Go (Bash)

Test

// naiveFib calculates the n-th fibonacci number
func naiveFib(n int) int {
    if n > 1 {
        return naiveFib(n - 1) + naiveFib(n - 2)
    }
    return 1
}
naiveFib(20)
1.3s
Go lgo/1.9 Test (Go (lgo))
Go

Go, go, Golang Gopher...

import (
    "fmt"
    "io/ioutil"
    "net/http"    
)
var gopherPNG []byte
{
    res, err := http.Get("https://golang.org/doc/gopher/frontpage.png")
    if err != nil {
        fmt.Printf("Failed to get: %v\n", err)
        return
    }
    defer res.Body.Close()
    gopherPNG, err = ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Printf("Failed to read: %v\n", err)
        return
    }
    _ctx.Display.Text("PNG Gopher", nil)
    _ctx.Display.PNG(gopherPNG, nil)
}
1.4s
Go lgo/1.9 Test (Go (lgo))
Go
Runtimes (2)
Runtime Languages (2)