Hello, Gophers! Gophercon Opening Keynote 24 Apr 2014 Rob Pike Google, Inc. https://go.dev * Video A video of this talk was recorded at GopherCon in Denver. .link https://www.youtube.com/watch?v=VoS7DsT1rdM Watch the talk on YouTube * Hello, gophers! .image hellogophers/gophers.jpg 500 750 * Hello, gophers! .play hellogophers/hellogophers.go * History This is a historic occasion. Go has achieved a level of success worthy of a conference. * Success Many factors contribute to that success. - features - lack of features - combination of features - design - people - time * Case study A look back, focusing on code. * Two programs A close look at two programs. First is the first Go program _you_ ever saw. Historic for you. Second is the first Go program _we_ ever saw. Historic for all gophers. First up: "hello, world". * hello.b .code hellogophers/hello.b First appeared in a 1972 B tutorial by Brian W. Kernighan. (Not, as sometimes claimed, a few years earlier in BCPL.) * hello.c .code hellogophers/hello.c First appeared in _Programming_in_C:_A_Tutorial_, by Brian W. Kernighan, 1974. Came as a document with Unix v5. * hello.c .code hellogophers/helloKnR.c First appeared in _The_C_Programming_Language_, by Brian W. Kernighan and Dennis M. Ritchie, 1978. * hello.c, Draft ANSI C .code hellogophers/helloDraftAnsi.c Appeared in _The_C_Programming_Language_, _Second_Edition_, (Based on Draft-Proposed ANSI C) by Brian W. Kernighan and Dennis M. Ritchie, 1988. * hello.c, ANSI C89 .code hellogophers/helloAnsi.c Appeared in _The_C_Programming_Language_, _Second_Edition_, round two, by Brian W. Kernighan and Dennis M. Ritchie, 1988. "You've gotta put a void THERE?" -Ken Thompson * A generation or two later... (Skipping all the intermediate languages.) Go discussions start in late 2007. Specification first drafted in March 2008. For experimentation and prototyping, compiler work already underway. Initially generated C output. Once the specification arose, compiler rewritten to generate native code. * hello.go, June 6, 2008 .code hellogophers/hello_20080606.go First checked-in test. The `print` builtin is all we have, and `main` returns an `int`. Note: no parentheses on `print`. * hello.go, June 27, 2008 .code hellogophers/hello_20080627.go When `main` returns, the program calls `exit(0)`. * hello.go, August 11, 2008 .play hellogophers/hello_20080811.go Parentheses now required: `print` now a function not a primitive. * hello.go, October 24, 2008 .code hellogophers/hello_20081024.go The "printf as we know and love it" goes in. (The test still uses `print` not `printf`; we've switched examples here.) * hello.go, January 15, 2009 .play hellogophers/hello_20090115.go Upper case for export. "Casification." * hello.go, Dec 11, 2009 .play hellogophers/hello_20091211.go No more semicolons. A major change that occurs _after_ the open source release (Nov 10, 2009). The current version. It took us a while to get here (32 years!). A lot of history. * Not just C We "started with C" but Go is profoundly different. Some of the languages that influenced and informed the design of Go: C: statement and expression syntax Pascal: declaration syntax Modula 2, Oberon 2: packages CSP, Occam, Newsqueak, Limbo, Alef: concurrency BCPL: the semicolon rule Smalltalk: methods Newsqueak: `<-`, `:=` APL: `iota` And others. Also some was invented whole: `defer`, constants, for instance. Plus lessons good and bad from all those plus: C++, C#, Java, JavaScript, LISP, Python, Scala, ... * hello.go, Go version 1 Which brings us to today. .play hellogophers/hello.go Let's dig deeper, break this down. * Hello, world in 16 tokens `package` `main` `import` `"fmt"` `func` `main` `(` `)` `{` `fmt` `.` `Println` `(` `"Hello,`Gophers`(some`of`whom`know`日本語)!"` `)` `}` * package Major topic in early design discussions: Key to scalability. What is a package? Ideas from Modula-2 etc. Why are there packages? Hold all the information you need to build. No circular dependencies (imports). No subpackages. Separation of package name and package path. Visibility is package-level, not type-level. Within a package, you have the whole language, outside only what you permit. * main One place where C legacy shows through. Was originally `Main` for some forgotten reason. `Main` package, `main` function. Special because the root of the initialization tree. * import Mechanism for loading a package. Implemented by the compiler (as opposed to a text processor). Worked hard to make it efficient and linear. Imports a package, not a set of identifiers. As for export: It used to be a keyword. * "fmt" Package path is just a string, not a list of identifiers. Allows the language to avoid defining what it means—adaptability. From the beginning wanted a URL as an option. Allows for future growth. * func A keyword introduces functions (and types, variables, constants) for easy parsing. Easy parsing is important with function literals (closures). By the way, keyword was originally `function`. * Aside: Mail thread from February 6, 2008 From: Ken Thompson To: gri, r larry and sergey came by tonight. we talked about go for more than an hour. they both said they liked it very much. p.s. one of larrys comments was "why isnt function spelled func?" --- From: Rob Pike To: ken, gri fine with me. seems compatible with 'var'. anyway we can always say, "larry said to call it 'func'" * main Where program starts... except it isn't. Separation of initialization from normal execution, long planned. Where does initialization happen? Feeds back to package design. * () Look Ma, no `void`. No return value for `main`: handled by runtime. No function args (command line is in `os` package). No return value. Return values and syntax. * { Braces not spaces. And not square brackets. Why is the newline after the brace? * fmt All imported identifiers are _qualified_ by their import. _Every_ identifier is either local to package or func, or qualified by type or import. Profound effect on readability. Why `fmt` not `format`? * . How many uses are there in Go for a period token? (Lots.) The meaning of `a.B` requires using the type system. But it is clear to humans and very easy to read. Autopromotion of pointers (no `->` operator). * Println `Println` not `println`: capitals for export. Always knew it would be reflection-driven. (Safety, formatless printing.) Variadic functions. Argument type was `(...)`; became `(...interface{})` on Feb 1, 2010. * ( Traditional function syntax. * "Hello, Gophers (some of whom know 日本語)!" UTF-8 input source, so strings as literals are UTF-8 automatically. But what is a string? One of the first things written in the specification, hardly changed today. .link /blog/strings go.dev/blog/strings * ) No semicolon. Semicolons went away shortly after release. Much futzing around to try to cull them in early days. Eventually accepted the BCPL approach. * } Done. * Aside: Not discussed - types - constants - methods - interfaces - libraries - memory management - concurrency (coming up) Plus tools, ecosystem, community, ...: Language is central but only part of the story. * Success Factors: - building on history - building on experience - process of design - early ideas refined into final approach - concentrated effort by a small dedicated team Finally: Commitment. Go 1.0 locked down the language and libraries. * Another round Now watch similar evolution of a second program. * Problem: Prime sieve Problem specification from _Communicating_Sequential_Processes_, by C. A. R. Hoare, 1978 "Problem: To print in ascending order all primes less than 10000. Use an array of processes, SIEVE, in which each process inputs a prime from its predecessor and prints it. The process then inputs an ascending stream of numbers from its predecessor and passes them on to its successor, suppressing any that are multiples of the original prime. " * Solution Defined in the 1978 CSP paper. (Note: not the sieve of Eratosthenes.) "This beautiful solution was contributed by David Gries." * CSP In Hoare's 1978 CSP paper .code hellogophers/sieve.csp No channels, just processes so number of primes is fixed by program. * Newsqueak _circa_ 1988. Language by Rob Pike, program by Tom Cargill via Doug McIlroy. Uses channels, so length of run is programmable. (Where did the idea of channels come from?) .code hellogophers/sieve.newsqueak 1,/BREAK/ * Newsqueak (cont'd) .code hellogophers/sieve.newsqueak /BREAK/,$ * sieve.go, March 5, 2008 First version in a Go specification, probably the second non-trivial program written. `>` to send, `<` to receive. Channels are pointers. `Main` is capitalized. .code hellogophers/sieve_20080305.go 1,/BREAK/ * sieve.go, March 5, 2008 (cont'd) .code hellogophers/sieve_20080305.go /BREAK/,$ * sieve.go, July 22, 2008 `-<` to send, `<-` to receive. Channels still pointers. Now `main` not capitalized. .code hellogophers/sieve_20080722.go 1,/BREAK/ * sieve.go, July 22, 2008 (cont'd) .code hellogophers/sieve_20080722.go /BREAK/,$ * sieve.go, September 17, 2008 Communication operators now prefix and postfix `<-`. Channels still pointers. .code hellogophers/sieve_20080917.go 1,/BREAK/ * sieve.go, September 17, 2008 (cont'd) .code hellogophers/sieve_20080917.go /BREAK/,$ * sieve.go, January 6, 2009 The `make` builtin arrives. No pointers. Code wrong! (One `*` left, bad argument types.) .code hellogophers/sieve_20090106.go 1,/BREAK/ * sieve.go, January 6, 2009 (cont'd) .code hellogophers/sieve_20090106.go /BREAK/,$ * sieve.go, September 25, 2009 First correct modern version. Also: capitalization gone. Uses `fmt`. .play hellogophers/sieve_20090925.go 1,/BREAK/ * sieve.go, September 25, 2009 (cont'd) .play hellogophers/sieve_20090925.go /BREAK/,$ * sieve.go, December 10, 2009 Semicolons gone. Program as it is today. .play hellogophers/sieve.go 1,/BREAK/ * sieve.go, December 10, 2009 (cont'd) .play hellogophers/sieve.go /BREAK/,$ "This beautiful solution was contributed by a decades-long process of design." * Aside: Not discussed - `select` The core connector for real concurrent applications. (A fact not always appreciated). Origins in Dijkstra's guarded commands. Made truly concurrent in Hoare's CSP. Refined through Newsqueak, Alef, Limbo, and other routes. Go's version specified on March 26, 2008. Simplifications, clarifications, syntactic considerations. * Stability Sieve program unchanged since late 2009—stability! Open source systems are not always dependably compatible and stable. Go is. This is a very important reason for Go's success. * Trends Graphs in usage metrics show knee in curve at Go 1.0 release. .image hellogophers/trends.png * Success The factors for Go's success? Obvious: Features and tools. - concurrency - garbage collection - efficient implementation - static types but dynamic feel - rich but limited standard library - tooling (and the factors that make it possible) - `gofmt` - programming in the large * Success Less obvious: process. - focus on the original goals - concentrated development followed by freeze - consensus of a small core team - vital contributions from a community that "gets it" - rich ecosystem generated as a consequence In short, an open source community that shares our mission, coupled to a language designed for today's world. * Fitness to purpose From _Go:_the_emerging_language_of_cloud_infrastructure_ by Donnie Berkholz, March 2014. [[/s/emerging]] .image hellogophers/emerging.png * The future This is where you come in! .image hellogophers/gophers.jpg 500 750