talks: add 2015/simplicity-is-complicated, r's talk at dotGo 2015 Change-Id: I6d96dd63e35fb7e87d65d209328c798c8be0f3d5 Reviewed-on: https://go-review.googlesource.com/17265 Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/2015/simplicity-is-complicated.slide b/2015/simplicity-is-complicated.slide new file mode 100644 index 0000000..19f1fc1 --- /dev/null +++ b/2015/simplicity-is-complicated.slide
@@ -0,0 +1,373 @@ +Simplicity is Complicated + +dotGo +9 Nov 2015 + +Rob Pike +Google +@rob_pike +[[http://golang.org/s/plusrob][+RobPikeTheHuman]] +http://golang.org/ + +* Bonjour mes Gophers! + +.image simplicity-is-complicated/gophers.jpg 512 _ + +* Success + +What makes Go successful? + +Many reasons cited: + +- speed of compilation +- speed of execution +- deployment +- tools +- libraries + +These are not language features. +Less often cited: true language features such as interfaces or concurrency. + +All are important but not really an answer. + +* Simplicity + +My answer: Simplicity. + +Go is simple, at least compared to established languages. + +Simplicity has many facets. + +Simplicity is complicated. + +* Convergence + +[[http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/From-Parallel-to-Concurrent?utm_content=bufferf1e11&utm_medium=social&utm_source=twitter.com&utm_campaign=buffer][Attended]] [[https://langnext2014.eventday.com/][Lang.Next]] conference last year (2014). + +Heard talks about new versions of Java, JavaScript (ECMAScript), Typescript, C#, C++, Hack (PHP), and more. + +These languages actively borrow features from one another. + +They are converging into a single huge language. + +* Language relativity + +_Sapir-Whorf_hypothesis_: Language influences thought. + +Controversial with regard to human languages. + +Close to a fact for computer languages. Consider: + +- logic programming +- procedural programming +- functional programming +- object-oriented programming +- concurrent programming + +Like disciplines in mathematics. + +* Convergence and relativity + +If the languages all converge, we will all think the same. + +But different ways of thinking are good. + +Need different languages for different problems. + +We don't want just one tool, we want a set of tools, each best at one task. + +* Convergence and features + +The talks at Lang.Next were about new language versions (Java 8, ECMAScript 6, C#, C++14) and were lists of features. + +These languages evolve and compete by adding features. + +The languages grow in complexity while becoming more similar. + +Bloat without distinction. + +* Features in Go + +Go is different. + +Go does not try to be like the other languages. + +Go does not compete on features. + +As of Go 1, the language is fixed. + +Many newcomers to Go ask for features from languages they know. +But those features do not belong in Go—and the language is fixed. + +Adding features to Go would not make it better, just bigger. + +That would make Go less interesting by being less different. + +* But you need features! + +Of course, there must be _some_ features. + +But which ones? The right ones! + +Design by consensus. + +* Readability + +If a language has too many features, you waste time choosing which ones to use. +Then implement, refine, possibly rethink and redo. + +Later, "Why does the code work this way?" + +_The_code_is_harder_to_understand_simply_because_it_is_using_a_more_complex_language._ + +Preferable to have just one way, or at least fewer, simpler ways. + +Features add complexity. We want simplicity. + +Features hurt readability. We want readability. + +Readability is paramount. + +* Readable means Reliable + +Readable code is reliable code. + +It's easier to understand. + +It's easier to work on. + +If it breaks, it's easier to fix. + +If the language is complicated: + +- You must understand more things to read and work on the code. +- You must understand more things to debug and fix it. + +A key tradeoff: More fun to write, or less work to maintain? + +* Expressiveness + +Features are often suggested to aid "expressiveness". + +Conciseness can be expressive but not always readable. +(Consider APL: ⊃ 1 ω ∨ . ∧ 3 4 = +/ +⌿ 1 0 ‾1 ∘.θ 1 - ‾1 Φ″ ⊂ ω) + +Can also be expensive, implementing simple ideas with too-powerful primitives. +Performance can also be unpredictable. + +On the other hand, verbosity can inhibit readability by obscuring the intent. + +Build on, but do not be limited by, familiar ideas. + +Be concise while remaining expressive. + +* The right set of features + +Not features for features' sake. + +Features that "cover the space", like a vector basis covering solution space. + +Orthogonal features that interact predictably. + +Simple features that interact in simple ways. + +Simplicity comes from orthogonality and predictability. + +Keep the language's goals in mind. + +* Go's goals + +Clean procedural language designed for scalable cloud software. + +Composable distinct elements, including: + +- concrete data types +- functions and methods +- interfaces +- packages +- concurrency + +Plus: Good tools, fast builds. + +All the pieces feel simple in practice. + +* Simple can be expressive + +.image simplicity-is-complicated/gopherslide2smblue.jpg 512 _ + +* Don't need all those features + +They add complexity without clarity. + +.image simplicity-is-complicated/gopherslide2sm.jpg 512 _ + +* Simplicity + +Go is actually complex, but it _feels_ simple. + +Interacting elements must mesh seamlessly, without surprises. + +Requires a lot of design, implementation work, refinement. + +Simplicity is the art of hiding complexity. + +* A few simple things in Go + +- garbage collection +- goroutines +- constants +- interfaces +- packages + +Each hides complexity behind a simple facade. + +* Garbage collection + +Perhaps the best example of simplicity hiding complexity. + +Very difficult to implement well, but worth it. +Yet so simple the language specification mentions it only in the introduction. +Nonetheless, parts of the language strongly influenced by it. + +Code is simpler because GC is there. +Design does not need to include "ownership". + +Go: there is no `free`. There is only garbage collection. +As simple as it can be. (But complex behind the facade.) + +* Concurrency + +Concurrency is the ability to write your program as independently executing pieces. +In Go, concurrency has three elements: + +- goroutines (execution) +- channels (communication) +- `select` (coordination) + +Let's talk about goroutines. + +* Goroutines + +Start a goroutine with the `go` keyword: + + go function(args) + +Three extra keystrokes ('g', 'o', ' '). Hard to be much simpler. + +Like garbage collection, eliminate considerations from the programmer's concern: + +- no stack size +- no return or completion status +- no mechanism for management +- no "ID" + +These are things other systems would provide. Go instead has a minimalist design. + +Implementation complex, dependent on garbage collection for stack management. + +* Constants + +In Go, constants are just numbers, even though (because) it is strongly typed. + + var nanosecond = time.Second/1e9 + +Simple idea took about a year to work out. Difficulties: + +- "infinite" precision integers +- "infinite" precision floating point (tried and failed with rationals) +- promotion rules (`i` `:=` `2;` `f` `:=` `2.0;` `g` `:=` `1/2;` `h` `:=` `1/2.0`) +- corner cases like shift + +.play simplicity-is-complicated/shift.go /Printf/ + +Still not totally satisfied, but the effect is that constants feel like numbers, contribute to the ease of using Go. But complicated behind the scenes. + +More at [[http://blog.golang.org/constants][this blog post]]. + +* Interfaces + +Just a set of methods. No data. Simple idea, but more complex than expected. + + type Reader interface { + Read([]byte) (int, error) + } + +Also need variables of that type (`var` `reader` `io.Reader`). +These variables add dynamic typing to a statically typed language. + + var r Reader = os.Stdin // Statically checked. + var x interface{} = os.Stdin // Statically checked. + r = x.(Reader) // Dynamically checked. Must be explicit here - design decision. + +Requires careful design. Interface assignment must be implemented at run time (not a v-table). What if it fails? Led to type assertions and the "comma, ok" idiom. + +More complexity crept in. Type assertions and type switches were not in the original plan. + +* Interfaces + +Go's most distinctive and powerful feature. + +Profound effect on library design. + +Enables true component architectures. Prime examples are `io.Reader` and `io.Writer`, generalizations of the Unix pipe idea. + +Feel simple, worth the complexity. + +* Packages + +A design for structuring programs and libraries. + + package big + ... + import "math/big" + +Took a long time to design. Enable componentization, scalability, sharing, data hiding and isolation, ... + +Affect program design, syntax, naming, building, linking, testing, ... + +Separation of package path (`"math/big"`) from package name (`big`). +Enabled the `go` `get` mechanism. + +Intricate to implement yet natural to use. + +After garbage collection, perhaps the highest ratio of true complexity to apparent simplicity, and therefore of the power of simplicity to hide complexity. + +* A "simple" example + +.play simplicity-is-complicated/hello.go + +* Hidden complexity + +Unicode and UTF-8 handled seamlessly. + +Packages imported and used easily. + +`Fprintf` direct to network connection. + +Function promoted to method (`HandleFunc`). + +Truly concurrent—server won't block. + +Production ready. + +All very simple. + +* Summary + +Simplicity is complicated but the clarity is worth the fight. + +.image simplicity-is-complicated/gopherslide2sm.jpg 512 _ + +* Conclusion + +Simplicity is hard—to design. + +Simplicity is complicated—to build. + +But if you get it right... + +Simplicity is easy—to use. + +The success of Go proves it. + +.image simplicity-is-complicated/gopherslide2smblue.jpg 256 _
diff --git a/2015/simplicity-is-complicated/gophers.jpg b/2015/simplicity-is-complicated/gophers.jpg new file mode 100644 index 0000000..ac88bfc --- /dev/null +++ b/2015/simplicity-is-complicated/gophers.jpg Binary files differ
diff --git a/2015/simplicity-is-complicated/gopherslide2sm.jpg b/2015/simplicity-is-complicated/gopherslide2sm.jpg new file mode 100644 index 0000000..887a7bd --- /dev/null +++ b/2015/simplicity-is-complicated/gopherslide2sm.jpg Binary files differ
diff --git a/2015/simplicity-is-complicated/gopherslide2smblue.jpg b/2015/simplicity-is-complicated/gopherslide2smblue.jpg new file mode 100644 index 0000000..54581a1 --- /dev/null +++ b/2015/simplicity-is-complicated/gopherslide2smblue.jpg Binary files differ
diff --git a/2015/simplicity-is-complicated/gopherslide2smbrown.jpg b/2015/simplicity-is-complicated/gopherslide2smbrown.jpg new file mode 100644 index 0000000..4ec67af --- /dev/null +++ b/2015/simplicity-is-complicated/gopherslide2smbrown.jpg Binary files differ
diff --git a/2015/simplicity-is-complicated/hello.go b/2015/simplicity-is-complicated/hello.go new file mode 100644 index 0000000..2b4d4d1 --- /dev/null +++ b/2015/simplicity-is-complicated/hello.go
@@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + "log" + "net/http" +) + +func こんにちは_Gophers(w http.ResponseWriter, req *http.Request) { + fmt.Fprintf(w, "こんにちは Gophers!\n") +} + +func main() { + http.HandleFunc("/", こんにちは_Gophers) + err := http.ListenAndServe("localhost:12345", nil) + if err != nil { + log.Fatal("ListenAndServe: ", err) + } +}
diff --git a/2015/simplicity-is-complicated/shift.go b/2015/simplicity-is-complicated/shift.go new file mode 100644 index 0000000..0b6013c --- /dev/null +++ b/2015/simplicity-is-complicated/shift.go
@@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Printf("%T %T", 2.0, 2.0<<0) +}