The Evolution of Go

GopherCon 2015 Keynote - July 9, 2015

Robert Griesemer

Google, Inc.

Video

A video of this talk was recorded at GopherCon in Denver.

Personal background

Starting points

What could possibly go wrong?

Guiding principles

Things of interest should be easy; even if that means not everything is possible.

Literature on good language design is sparse

First design notes

Date: Sun, 23 Sep 2007 23:33:41 -0700
From: "Robert Griesemer" <gri@google.com>
To: "Rob 'Commander' Pike" <r@google.com>, ken@google.com
Subject: prog lang discussion
...
*** General:
Starting point: C, fix some obvious flaws, remove crud, add a few missing features
  - no includes, instead: import
  - no macros (do we need something instead?)
  - ideally only one file instead of a .h and .c file, module interface
should be extracted automatically
  - statements: like in C, though should fix 'switch' statement
  - expressions: like in C, though with caveats (do we need ',' expressions?)
  - essentially strongly typed, but probably w/ support for runtime types
  - want arrays with bounds checking on always (except perhaps in 'unsafe mode'-see section on GC)
  - mechanism to hook up GC (I think that most code can live w/ GC, but for a true systems
    programming language there should be mode w/ full control over memory allocation)
  - support for interfaces (differentiate between concrete, or implementation types, and abstract,
    or interface types)
  - support for nested and anonymous functions/closures (don't pay if not used)
  - a simple compiler should be able to generate decent code
  - the various language mechanisms should result in predictable code
...

Looking back

Many Day One ideas made it into Go:

Many concepts were missing, and even more ideas didn't make it.

However, we were off to a good start. This was not at all obvious at the time!

Most ideas come from previous ideas.

(Alan Kay)

Or, as some critics would say: There's nothing new in Go!

They are missing the point:

The task of the programming language designer " is consolidation not innovation ".
(Hoare, 1973).

The Algol family

Algol60

(John Backus, John McCarthy, Alan Perlis, et al, 1958-1960)

=> Block structure, nested and recursive functions and procedures, type declarations and static typing, "for" statement, "return" statement, semicolon separated statements, "begin"-"end" blocks, "call by name", etc.

"Here is a language [Algol60] so far ahead of its time, that it was not only an improvement on its predecessors, but also on nearly all its successors." (C.A.R. Hoare)

Coincidentally, a few years before:
- Backus Naur Normal Form (John Backus, Peter Naur, 1958)

Algol successors

=> BEGIN/END for blocks, semicolons as separators, left-to-right declarations,
principled structured data types, notion of predeclared ("standard") functions, designed for teaching.

=> Curly braces for blocks, semicolons as terminators, declarations mimic use,
duality between arrays and pointers, static typing but weak enforcement, designed to write Unix kernel.

Pascal successors

=> Modules separate compilation and encapsulation, coroutines and monitors, support for low-level programming.

=> Simplified modules, dynamic type extension and type tests, streamlined syntax.

Philosophy: "Make it as simple as possible, but not simpler." (A. Einstein)

=> Experimental Oberon dialect with classes and methods.

=> Oberon with methods on records (== structs), replaces Object Oberon.

Tree node lookup in Oberon-2

MODULE Trees;

IMPORT Texts, Oberon;

TYPE
    Tree* = POINTER TO Node;  (* star denotes export, not pointer! *)
    Node* = RECORD
        name-: POINTER TO ARRAY OF CHAR;  (* minus denotes read-only export *)
        left, right: Tree
    END;

PROCEDURE (t: Tree) Lookup* (name: ARRAY OF CHAR): Tree;
    VAR p: Tree;
BEGIN p := t;
    WHILE (p # NIL) & (name # p.name^) DO
        IF name < p.name^ THEN p := p.left ELSE p := p.right END
    END;
    RETURN p
END Lookup;

...

Analogous code in Go

package trees

import ( "fmt"; "runtime" )

type (
    Tree *Node
    Node struct {
        name        string
        left, right Tree
    }
)

func (t *Node) Lookup(name string) Tree {
    var p Tree
    p = t
    for p != nil && name != p.name {
        if name < p.name { p = p.left } else { p = p.right }
    }
    return p
}

...

Observations

=> C tokens, Oberon structure.

=> Go concepts further distilled (e.g.; just one loop construct).

Go's heritage is at least as much Oberon as it is C!
(packages, imports, strict memory safety, garbage collection, dynamic type checks, etc.)

Object orientation and generics

Around 1990: OO and type-system "craze" taking its toll on programming languages.
- C++, Java, others
- complex OO type systems
- complex generic type systems

Proliferation of dynamically typed interpreted languages:
- Erlang, Perl, Python, Lua, Javascript, Ruby, etc.

1990s, 2000s: Backlash.
- Complex OO code is modern analog to unstructured "spaghetti code" of 1970.
- Realization that large programs in dynamically typed languages become unmaintainable.
- Cluttered notation: “Public Static Void” (Rob Pike, OSCON 2010).

Object orientation in Go: Interfaces

Inspiration: Smalltalk (Alan Kay, Dan Ingalls, Adele Goldberg, 1972-1980)
- Everything is an object.
- Any message can be sent to any object.

Want: Similar power in (mostly) statically typed language without the type-system fuss.
- Notion of interfaces for static typing.
- Usually objects carry type information => restricts object types to "classes".

Crucial insight: Can attach methods to any type if interfaces carry type info rather than objects.

Methods and interfaces are the only additional mechanisms needed for object-oriented programming.

Concurrency

Origins:

Generics

Putting it all together

Luxury to spend two years to hammer out basics (thanks, Google!).

Crucial: Added one feature at a time.

Initially: Team of three very different people.
- Intensive discussions, emotional.
- Humbling experience.

Having multiple people illuminating each new feature from different angles
made language much stronger.

Later:
- Russ Cox's razor cutting through the crud, making it work well.
- Ian Lance Taylor providing a 2nd implementation (validation of design).
- go/types (now in 1.5!) provides a 3rd frontend (validation of compilers and spec).

Having 3 frontends proved tremendously useful.

Evolving Go

Original design went through many (syntactic and semantic) transitions:

Features that came in much later:

The future of Go

What makes a programming language successful?

How about Go?

Will Go become mainstream?

It takes about 10 years for a programming language to become "established".

Pitfalls

The language is frozen, but these are a form of "language design":

These mechanisms are not part of the language spec and thus may diverge
over time or have different semantics on different platforms.

Need to be watchful of this development.

Closing thoughts

Thank you

Robert Griesemer

Google, Inc.

Use the left and right arrow keys or click the left and right edges of the page to navigate between slides.
(Press 'H' or navigate to hide this message.)