Drivers
The native drivers that provide the interface, console and network.
Contents
How a Program becomes Go, in parts. Start with the introduction, then follow each part into the rendered output and the runtime it links against.
- Introduction — what the Go target is, and how to read the rest of this section.
- Capabilities — which high-level features are possible, built in or through a library.
- Example — a full program using every keyword, and the Go it renders to.
- Naming considerations — how Program's dotted names are carried into Go.
- Entry point — starting a program from
mainwith its drivers. - Drivers — the native drivers that provide the interface, console and network.
- Runtime — the Reactive and Context machinery the rendered code links against.
- Native modules — the hand-written Go behind
NATIVEfunctions. - Keywords — how each of Program's keywords renders to Go.
- Project setup — the files and commands to build and run the rendered program.
- Reserved words — the words Go keeps for itself, and how a colliding name is escaped.
Defining a driver
A driver is a Go value implementing the Driver interface: it drains one context channel
and reconciles the resources it owns. Here is a console driver — it drains the
Console.Lines channel and prints each line that has changed since the last cycle.
type ConsoleDriver struct {
lastById map[int64]string
}
func NewConsoleDriver() *ConsoleDriver {
return &ConsoleDriver{lastById: map[int64]string{}}
}
func (d *ConsoleDriver) Channel() string { return "Console.Lines" }
func (d *ConsoleDriver) Kind() DriverKind { return ArrayChannel }
func (d *ConsoleDriver) Init(addUpdates AddUpdates) {}
func (d *ConsoleDriver) Dispatch(emissions []Line) {
for _, line := range emissions {
if d.lastById[line.Id] != line.Text {
fmt.Println(line.Text)
d.lastById[line.Id] = line.Text
}
}
}
Registering it
A program lists the drivers it uses; the runtime opens a channel for each and never hardcodes one.
func main() {
Program.Application(func() {
Main()
}, []Driver{
NewConsoleDriver(),
})
}
How the runtime runs it
Each cycle the runtime opens the driver's channel, runs the reactive program (which emits into it),
drains it, and passes the slice to Dispatch:
Context.OpenArray("Console.Lines")
program = Reactive.Run(program, updates)
driver.Dispatch(Context.DrainArray("Console.Lines"))
A driver that produces events — a timer, a network reply, often on its own goroutine —
calls the addUpdates it was given in Init, which schedules the next cycle.
The three shapes are the same as everywhere: a tree renderer (the terminal interface), a request set
(network), and a shared ticker.