
notebook β go-notebook

Go notebooks with native speed, kept values and a reproducible order.
π Website Β· π Documentation
A notebook is a Markdown file whose ```go blocks are cells. The kernel:
- compiles it into a real Go program, so cells run at native speed;
- orders the cells by what they use, worked out from the code itself as marimo does for Python, not by the order you ran them in;
- runs only what changed. A cell whose code and inputs did not change keeps its result, and its values are handed over instead of being computed again. That holds across rebuilds and across runs: results and values are kept on disk.
# Spectrum
```go
import "math"
n := 1_000_000
```
The sum below runs once; editing the last cell does not run it again.
```go
sum := 0.0
for i := 1; i <= n; i++ {
sum += 1 / float64(i*i)
}
```
```go
math.Sqrt(6 * sum)
```
$ notebook run spectrum.md
ββ cell 0 (line 4, ran in 11Β΅s)
ββ cell 1 (line 12, ran in 2.065ms)
ββ cell 2 (line 19, ran in 30Β΅s)
3.1415916986605086
$ # change the last cell to math.Pi - math.Sqrt(6*sum), then:
$ notebook run spectrum.md
ββ cell 0 (line 4, kept)
ββ cell 1 (line 12, kept)
ββ cell 2 (line 19, ran in 48Β΅s)
9.54929284535666e-07
The second run is a new process: sum comes back from the kernel's store, it is not summed again.
Use
go install github.com/go-notebook/notebook/cmd/notebook@latest
notebook run analysis.md # run it, print each cell's results
notebook html analysis.md # run it, write analysis.html (no scripts, no external resources; $\TeX$ math typeset by go-tex)
notebook watch analysis.md # run it on every save and keep analysis.html current
Edit the .md in any editor; with watch, the page follows the file.
examples/spectrum.md finds two tones in Gaussian noise with go-ndarray (arrays, fft.RFFT, a seeded generator that gives NumPy's numbers for the same seed) and draws the signal and its spectrum with go-plot.
Cells
A cell is Go with statements allowed at the top level:
import "strings"
func words(s string) []string { return strings.Fields(s) }
w := words("to be or not to be")
len(w) // the final expression is shown
- Names defined at the top level are shared with every cell. Each name is defined by one cell, and a cell may not assign to another cell's variable. That is what makes the order a function of the code.
- Names starting with
_, and err, stay local to their cell.
- A final call returning
(value, error) shows the value; a non-nil error fails the cell.
- A value with a
Display() map[string][]byte method shows itself as HTML, SVG or PNG.
- Errors point at the notebook's own lines. A panic stops the cells that read the failing one, and they say why.
How it works
format parses the Markdown and analysis builds the dependency graph from the syntax. gen writes the Go program, type-checking cell by cell to learn the types of shared variables. kernel compiles it into a worker, drives it through runtime, and keeps results and values under a hash of each cell's code and inputs. export writes the HTML page. The reasons for each choice, and what is not done yet, are in docs/design.md; the documentation covers the cell rules, the command and the kernel in more detail.
It is part of an ecosystem built for it: go-ndarray (N-dimensional arrays in thirteen dtypes, with FFT, linear algebra, and random numbers bit-identical to NumPy's for the same seed), go-plot (figures, with TeX labels), and, in progress, go-numerics (special functions, optimisation, integration), go-statistics and go-dataframe.
License
BSD-3-Clause. See LICENSE.