Go docs

Golang-Syd, Oct 17, 2012

Rob Pike

Google, Inc.

Documentation

Text

There are many ways to show documentation as text

Man pages: Unix 1st Edition, 1971

Man pages: Apple OS X 10.8, 2012

Javadoc 1996+

Javadoc 1996+

Godoc 2009+

Godoc 2009+

Godoc

blog.golang.org

Code walks

Community contributions

Go wiki

Gopkgdoc

Gopkgdoc

Go By Example

Go By Example

Talks

Presentations

We give a lot of talks.

Most of the tools for presentations focus on style, not ease of creation.

Present

In the go.talks repo, have a new tool: present.

go get code.google.com/p/go.talks/present

Took about an hour to put this talk together.

Docs:

Input for the previous slide

* Present

In the `go.talks` repo, have a new tool: `present`.

    go get code.google.com/p/go.talks/present

- Simple
- Easy to use
- Easy, smooth to present

Took about an hour to put this talk together.

Docs:

.link http://go.pkgdoc.org/code.google.com/p/go.talks/present

Input for the previous slide redux

* Input for the previous slide

.code go-docs.slide /^\* Present$/,/^\.link/

Revenge of the input for the the previous slide

* Input for the previous slide redux

.code go-docs.slide /^\*.*previous/,/^\.code/

Many choices

Lots of presentations, different styles.

Fatal flaw

They all have code.

Can't execute the code!

Want to edit and play.

The playground

Can run code from the browser

The tour

Can run code from the browser

Use this technology

Want to embed the playground technology in the other media.

Triggering example: Go Concurrency Patterns, Google I/O, 2012

Needed to demonstrate concurrency and the passage of time.

Go Concurrency Patterns

An extract from the talk.

Multiplexing

These programs make Joe and Ann count in lockstep.
We can instead use a fan-in function to let whosoever is ready talk.

func fanIn(input1, input2 <-chan string) <-chan string {
    c := make(chan string)
    go func() { for { c <- <-input1 } }()
    go func() { for { c <- <-input2 } }()
    return c
}
// +build OMIT

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
    c := fanIn(boring("Joe"), boring("Ann"))
    for i := 0; i < 10; i++ {
        fmt.Println(<-c)
    }
    fmt.Println("You're both boring; I'm leaving.")
}

// START2 OMIT
func boring(msg string) <-chan string { // Returns receive-only channel of strings. // HL
	c := make(chan string)
	go func() { // We launch the goroutine from inside the function. // HL
		for i := 0; ; i++ {
			c <- fmt.Sprintf("%s: %d", msg, i)
			time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond)
		}
	}()
	return c // Return the channel to the caller. // HL
}
// STOP2 OMIT


// START3 OMIT
func fanIn(input1, input2 <-chan string) <-chan string { // HL
	c := make(chan string)
	go func() { for { c <- <-input1 } }() // HL
	go func() { for { c <- <-input2 } }() // HL
	return c
}
// STOP3 OMIT

.code and .play

Input for the previous slide:

* Multiplexing

These programs make Joe and Ann count in lockstep.
We can instead use a fan-in function to let whosoever is ready talk.

.code go-docs/faninboring.go /START3/,/STOP3/
.play go-docs/faninboring.go /START1/,/STOP1/

faninboring.go (I)

package main

import (
    "fmt"
    "math/rand"
    "time"
)

// START1 OMIT
func main() {
    c := fanIn(boring("Joe"), boring("Ann")) // HL
    for i := 0; i < 10; i++ {
        fmt.Println(<-c) // HL
    }
    fmt.Println("You're both boring; I'm leaving.")
}
// STOP1 OMIT

faninboring.go (II)

// START2 OMIT
func boring(msg string) <-chan string { // Returns receive-only channel of strings. // HL
    c := make(chan string)
    go func() { // We launch the goroutine from inside the function. // HL
        for i := 0; ; i++ {
            c <- fmt.Sprintf("%s: %d", msg, i)
            time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond)
        }
    }()
    return c // Return the channel to the caller. // HL
}
// STOP2 OMIT


// START3 OMIT
func fanIn(input1, input2 <-chan string) <-chan string { // HL
    c := make(chan string)
    go func() { for { c <- <-input1 } }() // HL
    go func() { for { c <- <-input2 } }() // HL
    return c
}
// STOP3 OMIT

.code and .play again

The input for the Multiplexing slide again:

* Multiplexing

These programs make Joe and Ann count in lockstep.
We can instead use a fan-in function to let whosoever is ready talk.

.code go-docs/faninboring.go /START3/,/STOP3/
.play go-docs/faninboring.go /START1/,/STOP1/

Multiplexing again

These programs make Joe and Ann count in lockstep.
We can instead use a fan-in function to let whosoever is ready talk.

func fanIn(input1, input2 <-chan string) <-chan string {
    c := make(chan string)
    go func() { for { c <- <-input1 } }()
    go func() { for { c <- <-input2 } }()
    return c
}
// +build OMIT

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
    c := fanIn(boring("Joe"), boring("Ann"))
    for i := 0; i < 10; i++ {
        fmt.Println(<-c)
    }
    fmt.Println("You're both boring; I'm leaving.")
}

// START2 OMIT
func boring(msg string) <-chan string { // Returns receive-only channel of strings. // HL
	c := make(chan string)
	go func() { // We launch the goroutine from inside the function. // HL
		for i := 0; ; i++ {
			c <- fmt.Sprintf("%s: %d", msg, i)
			time.Sleep(time.Duration(rand.Intn(2e3)) * time.Millisecond)
		}
	}()
	return c // Return the channel to the caller. // HL
}
// STOP2 OMIT


// START3 OMIT
func fanIn(input1, input2 <-chan string) <-chan string { // HL
	c := make(chan string)
	go func() { for { c <- <-input1 } }() // HL
	go func() { for { c <- <-input2 } }() // HL
	return c
}
// STOP3 OMIT

Executable documentation

Plans

Deploy executable examples throughout:

Thank you