Go (programming language)

Not to be confused with Go! (programming language), an agent-based language released in 2003.
Go
Paradigm compiled, concurrent, imperative, structured
Designed by Robert Griesemer
Rob Pike
Ken Thompson
Developer Google Inc.
First appeared 2009
version 1.4.2[1] / 17 February 2015
strong, static, inferred, structural
Implementation language
C, Go, Asm
OS Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD,[2] MS Windows, Plan 9[3]
License BSD-style[4] + Patent grant[5]
.go
Website golang.org

Go, also commonly referred to as golang, is a programming language initially developed at Google[7] in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson.[6] It is a statically-typed language with syntax loosely derived from that of C, adding garbage collection, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library.

The language was announced in November 2009 and is now used in some of Google's production systems.[8] Go's "gc" compiler targets the Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD, Plan 9, and Microsoft Windows operating systems and the i386, amd64, ARM and IBM POWER processor architectures.[9] A second compiler, gccgo, is a GCC frontend.[10][11]

History

Ken Thompson states that, initially, Go was purely an experimental project. Referring to himself along with the other original authors of Go, he states:[12]

When the three of us [Thompson, Rob Pike, and Robert Griesemer] got started, it was pure research. The three of us got together and decided that we hated C++. [laughter] ... [Returning to Go,] we started off with the idea that all three of us had to be talked into every feature in the language, so there was no extraneous garbage put into the language for any reason.

The history of the language before its first release, back to 2007, is covered in the language's FAQ.[13]

Language design

Go is recognizably in the tradition of C, but makes many changes to improve conciseness, simplicity, and safety. The following is a brief overview of the features which define Go (for more information see the language specification):

Frequent criticisms assert that:

The language designers argue that these trade-offs are important to Go's success,[24] and explain some particular decisions at length,[25] though they do express openness to adding some form of generic programming in the future, and to pragmatic improvements in areas like standardizing ways to apply code generation[26] and reducing garbage collection pause times.[27]

Syntax

Go's syntax includes changes from C aimed at keeping code concise and readable. The programmer needn't specify the types of expressions, allowing just i := 3 or s := "some words" to replace C's int i = 3; or char* s = "some words";. Semicolons at the end of lines aren't required. Functions may return multiple values, and returning a result, err pair is the conventional way a function indicates an error to its caller in Go.[lower-alpha 1] Go adds literal syntaxes for initializing struct parameters by name, and for initializing maps and slices. As an alternative to C's three-statement for loop, Go's range expressions allow concise iteration over arrays, slices, strings, and maps.

Types

For safety and convenience Go adds some basic types not present in C:

Structurally, Go's type system has a few differences from C and most C derivatives. Go's user-defined types are not interchangeable even if they share the same underlying data layout, and conversion has to be explicit in cases where it could be implied in other C-like languages.[32] Unlike in C, conversions between number types, such as between 32- and 64-bit integers, are explicit; to ensure that doesn't create verbose conversion-heavy code, numeric constants in Go represent abstract, untyped numbers.[33]

Finally, in place of non-virtual inheritance, Go has a feature called type embedding in which one object can contain others and pick up their methods.

Package system

In Go's package system, each package has a path (e.g., "compress/bzip2" or "golang.org/x/net/html") and a name (e.g., bzip2 or html). References to other packages' definitions must always be prefixed with the other package's name, and only the capitalized names from other modules are accessible: io.Reader is public but bzip2.reader is not.[34] The go get command can retrieve packages stored in a remote repository such as Github or Google Code, and package paths often look like partial URLs for compatibility.[35]

Concurrency: goroutines, channels, and select

Go provides facilities for writing concurrent programs that share state by communicating.[36][37][38] Concurrency refers not only to multithreading and CPU parallelism, which Go supports, but also to asynchrony: letting slow operations like a database or network-read run while the program does other work, as is common in event-based servers.[39]

Go's concurrency-related syntax and types include:

From these tools one can build concurrent constructs like worker pools, pipelines (in which, say, a file is decompressed and parsed as it downloads), background calls with timeout, "fan-out" parallel calls to a set of services, and others.[41] Channels have also found uses further from the usual notion of interprocess communication, like serving as a concurrency-safe list of recycled buffers,[42] implementing coroutines (which helped inspire the name goroutine),[43] and implementing iterators.[44]

While the communicating-processes model is favored in Go, it isn't the only one: memory can be shared across goroutines (see below), and the standard sync module provides locks and other primitives.[45]

Lack of race condition safety

There are no restrictions on how goroutines access shared data, making race conditions possible. Specifically, unless a program explicitly synchronizes via channels or other means, writes from one goroutine might be partly, entirely, or not at all visible to another, often with no guarantees about ordering of writes.[46] Furthermore, Go's internal data structures like interface values, slice headers, and string headers are not immune to race conditions, so type and memory safety can be violated in multithreaded programs that modify shared instances of those types without synchronization.[47][48]

Idiomatic Go minimizes sharing of data (and thus potential race conditions) by communicating over channels, and a race-condition tester is included in the standard distribution to help catch unsafe behavior. Still, it is important to realize that while Go provides building blocks that can be used to write correct, comprehensible concurrent code, arbitrary code isn't guaranteed to be safe.

Some concurrency-related structural conventions of Go (channels and alternative channel inputs) are derived from Tony Hoare's communicating sequential processes model. Unlike previous concurrent programming languages such as occam or Limbo (a language on which Go co-designer Rob Pike worked[49]), Go does not provide any built-in notion of safe or verifiable concurrency.[46]

Interface system

In place of virtual inheritance, Go uses interfaces. An interface declaration is nothing but a list of required methods: for example, implementing io.Reader requires a Read method that takes a []byte and returns a count of bytes read and any error.[50] Code calling Read needn't know whether it's reading from an HTTP connection, a file, an in-memory buffer, or any other source.

Go's standard library defines interfaces for a number of concepts: input sources and output sinks, sortable collections, objects printable as strings, cryptographic hashes, and so on.

Go types don't declare which interfaces they implement: having the required methods is implementing the interface. In formal language, Go's interface system provides structural rather than nominal typing.

The example below uses the io.Reader and io.Writer interfaces to test Go's implementation of SHA-256 on a standard test input, 1,000,000 repeats of the character "a". RepeatByte implements an io.Reader yielding an infinite stream of repeats of a byte, similar to Unix /dev/zero. The main() function uses RepeatByte to stream a million repeats of "a" into the hash function, then prints the result, which matches the expected value published online.[51] Even though both reader and writer interfaces are needed to make this work, the code needn't mention either; the compiler infers what types implement what interfaces:

package main
 
import (
    "fmt"
    "io"
    "crypto/sha256"
)
 
type RepeatByte byte
 
func (r RepeatByte) Read(p []byte) (n int, err error) {
    for i := range p {
        p[i] = byte(r)
    }
    return len(p), nil
}
 
func main() {
    testStream := RepeatByte('a')
    hasher := sha256.New()
    io.CopyN(hasher, testStream, 1000000)
    fmt.Printf("%x", hasher.Sum(nil))
}

(Run or edit this example online.)

Also note type RepeatByte is defined as a byte, not a struct. Named types in Go needn't be structs, and any named type can have methods defined, satisfy interfaces, and act, for practical purposes, as objects; the standard library, for example, stores IP addresses in byte slices.[52]

Besides calling methods via interfaces, Go allows converting interface values to other types with a run-time type check. The language constructs to do so are the type assertion,[53] which checks against a single potential type, and the type switch,[54] which checks against multiple types.

interface{}, the empty interface, is an important corner case because it can refer to an item of any concrete type, including builtin types like string. Code using the empty interface can't simply call methods (or built-in operators) on the referred-to object, but it can store the interface{} value, try to convert it to a more useful type via a type assertion or type switch, or inspect it with Go's reflect package.[55] Because interface{} can refer to any value, it's a limited way to escape the restrictions of static typing, like void* in C but with additional run-time type checks.

Interface values are implemented using pointer to data and a second pointer to run-time type information.[56] Like some other types implemented using pointers in Go, interface values are nil if uninitialized.[57] Unlike in environments like Java's virtual machine, there is no object header; the run-time type information is only attached to interface values. So, the system imposes no per-object memory overhead for objects not accessed via interface, similar to C structs or C# ValueTypes.

Go does not have interface inheritance, but one interface type can embed another; then the embedding interface requires all of the methods required by the embedded interface.[58]

Omissions

Go deliberately omits certain features common in other languages, including generic programming, dynamic linking, assertions, pointer arithmetic, and inheritance.

After initially omitting exceptions, the language added the exception-like panic/recover mechanism, which the Go authors advise using for unrecoverable errors such as those that should halt an entire program or server request, or as a shortcut to propagate errors up the stack within a package (but not across package boundaries; there, error returns are the standard API).[59][60][61][62]

The Go authors express an openness to generic programming, explicitly argue against assertions and pointer arithmetic, while defending the choice to omit type inheritance as giving a more useful language, encouraging heavy use of interfaces instead.[6] Some built-in functions are in fact type-generic, but these are treated as special cases, which Rob Pike calls a "weakness" of the language and something that may change at some point.[28] The Google team that designs the language built a compiler for an experimental Go dialect with generics at one point, but didn't release it.[63]

Conventions and code style

The Go authors and community put substantial effort into molding the style and design of Go programs:

When adapting to the Go ecosystem after working in other languages, differences in style and approach can be as important as low-level language and library differences.

Language tools

Go includes the same sort of debugging, testing, and code-vetting tools as many language distributions. The Go distribution includes, among other tools,

It also includes profiling and debugging support, runtime instrumentation (to, for example, track garbage collection pauses), and a race condition tester.

There is an ecosystem of third-party tools that add to the standard distribution, such as gocode, which enables code autocompletion in many text editors, goimports (by a Go team member), which automatically adds/removes package imports as needed, errcheck, which detects code that might unintentionally ignore errors, and more. Plugins exist to add language support in widely used text editors, and at least one IDE, LiteIDE[65] targets Go in particular.

Examples

Hello world

Here is a Hello world program in Go:

package main
 
import "fmt"
 
func main() {
    fmt.Println("Hello, World")
}

(Run or edit this example online.)

Echo

This imitates the Unix echo command in Go:[66]

package main
 
import (
    "flag"
    "fmt"
    "strings"
)
 
func main() {
    var omitNewline bool
    flag.BoolVar(&omitNewline, "n", false, "don't print final newline")
    flag.Parse() // Scans the arg list and sets up flags.
 
    str := strings.Join(flag.Args(), " ")
    if omitNewline {
        fmt.Print(str)
    } else {
        fmt.Println(str)
    }
}

File Read

// Reading and writing files are basic tasks needed for
// many Go programs. First we'll look at some examples of
// reading files.
 
package main
 
import (
    "bufio"
    "fmt"
    "io"
    "io/ioutil"
    "os"
)
 
// Reading files requires checking most calls for errors.
// This helper will streamline our error checks below.
func check(e error) {
    if e != nil {
        panic(e)
    }
}
 
func main() {
 
    // Perhaps the most basic file reading task is
    // slurping a file's entire contents into memory.
    dat, err := ioutil.ReadFile("/tmp/dat")
    check(err)
    fmt.Print(string(dat))
 
    // You'll often want more control over how and what
    // parts of a file are read. For these tasks, start
    // by `Open`ing a file to obtain an `os.File` value.
    f, err := os.Open("/tmp/dat")
    check(err)
 
    // Read some bytes from the beginning of the file.
    // Allow up to 5 to be read but also note how many
    // actually were read.
    b1 := make([]byte, 5)
    n1, err := f.Read(b1)
    check(err)
    fmt.Printf("%d bytes: %s\n", n1, string(b1))
 
    // You can also `Seek` to a known location in the file
    // and `Read` from there.
    o2, err := f.Seek(6, 0)
    check(err)
    b2 := make([]byte, 2)
    n2, err := f.Read(b2)
    check(err)
    fmt.Printf("%d bytes @ %d: %s\n", n2, o2, string(b2))
 
    // The `io` package provides some functions that may
    // be helpful for file reading. For example, reads
    // like the ones above can be more robustly
    // implemented with `ReadAtLeast`.
    o3, err := f.Seek(6, 0)
    check(err)
    b3 := make([]byte, 2)
    n3, err := io.ReadAtLeast(f, b3, 2)
    check(err)
    fmt.Printf("%d bytes @ %d: %s\n", n3, o3, string(b3))
 
    // There is no built-in rewind, but `Seek(0, 0)`
    // accomplishes this.
    _, err = f.Seek(0, 0)
    check(err)
 
    // The `bufio` package implements a buffered
    // reader that may be useful both for its efficiency
    // with many small reads and because of the additional
    // reading methods it provides.
    r4 := bufio.NewReader(f)
    b4, err := r4.Peek(5)
    check(err)
    fmt.Printf("5 bytes: %s\n", string(b4))
 
    // Close the file when you're done (usually this would
    // be scheduled immediately after `Open`ing with
    // `defer`).
    f.Close()
 
}

[67][68]

Notable users

Some notable open-source applications in Go include:

Other companies and sites using Go (generally together with other languages, not exclusively) include:[69][70]

Libraries

Go's open-source libraries include:

Some sites help index the libraries outside the Go distribution:

Community and conferences

Reception

Go's initial release led to much discussion.

Michele Simionato wrote in an article for artima.com:[81]

Here I just wanted to point out the design choices about interfaces and inheritance. Such ideas are not new and it is a shame that no popular language has followed such particular route in the design space. I hope Go will become popular; if not, I hope such ideas will finally enter in a popular language, we are already 10 or 20 years too late :-(

Dave Astels at Engine Yard wrote:[82]

Go is extremely easy to dive into. There are a minimal number of fundamental language concepts and the syntax is clean and designed to be clear and unambiguous. Go is still experimental and still a little rough around the edges.

Ars Technica interviewed Rob Pike, one of the authors of Go, and asked why a new language was needed. He replied that:[83]

It wasn't enough to just add features to existing programming languages, because sometimes you can get more in the long run by taking things away. They wanted to start from scratch and rethink everything. ... [But they did not want] to deviate too much from what developers already knew because they wanted to avoid alienating Go's target audience.

Go was named Programming Language of the Year by the TIOBE Programming Community Index in its first year, 2009, for having a larger 12-month increase in popularity (in only 2 months, after its introduction in November) than any other language that year, and reached 13th place by January 2010,[84] surpassing established languages like Pascal. As of August 2014, its ranking had dropped to 38th in the index, placing it lower than COBOL and Fortran.[85] Go is already in commercial use by several large organizations.[86]

Regarding Go, Bruce Eckel has stated:[87]

The complexity of C++ (even more complexity has been added in the new C++), and the resulting impact on productivity, is no longer justified. All the hoops that the C++ programmer had to jump through in order to use a C-compatible language make no sense anymore -- they're just a waste of time and effort. Now, Go makes much more sense for the class of problems that C++ was originally intended to solve.

Mascot

Go's mascot is a gopher designed by Renée French, who also designed Glenda, the Plan 9 Bunny. The mascot is based on one French had previously drawn for a WFMU fundraiser T-shirt.[88] The logo and mascot are licensed under Creative Commons Attribution 3.0 license.[89]

Naming dispute

On the day of the general release of the language, Francis McCabe, developer of the Go! programming language (note the exclamation point), requested a name change of Google's language to prevent confusion with his language.[90] The issue was closed by a Google developer on 12 October 2010 with the custom status "Unfortunate" and with the following comment: "there are many computing products and services named Go. In the 11 months since our release, there has been minimal confusion of the two languages."[91]

See also

Notes

  1. Usually, exactly one of the result and error values has a value other than the type's zero value; sometimes both do, as when a read or write can only be partially completed, and sometimes neither, as when a read returns 0 bytes. See Semipredicate problem: Multivalued return.

References

This article incorporates material from the official Go tutorial, which is licensed under the Creative Commons Attribution 3.0 license.
  1. "Release History - The Go Programming Language". Retrieved 17 January 2015.
  2. "lang/go: go-1.4 – Go programming language". OpenBSD ports. 2014-12-23. Retrieved 2015-01-19.
  3. "Go Porting Efforts". Go Language Resources. cat-v. 12 January 2010. Retrieved 18 January 2010.
  4. "Text file LICENSE". The Go Programming Language. Google. Retrieved 5 October 2012.
  5. "Additional IP Rights Grant". The Go Programming Language. Google. Retrieved 5 October 2012.
  6. 6.0 6.1 6.2 "Language Design FAQ". golang.org. 16 January 2010. Retrieved 27 February 2010.
  7. Kincaid, Jason (10 November 2009). "Google’s Go: A New Programming Language That’s Python Meets C++". TechCrunch. Retrieved 18 January 2010.
  8. "Go FAQ: Is Google using Go internally?". Retrieved 9 March 2013.
  9. "Installing Go". golang.org. The Go Authors. 11 June 2010. Retrieved 11 June 2010.
  10. "FAQ: Implementation". golang.org. 16 January 2010. Retrieved 18 January 2010.
  11. "Installing GCC: Configuration". Retrieved 3 December 2011. Ada, Go and Objective-C++ are not default languages
  12. Andrew Binstock (18 May 2011). "Dr. Dobb's: Interview with Ken Thompson". Retrieved 7 February 2014.
  13. "Frequently Asked Questions (FAQ) - The Go Programming Language". Golang.org. Retrieved 2014-03-27.
  14. Pike, Rob. "The Go Programming Language". YouTube. Retrieved 1 Jul 2011.
  15. Rob Pike (10 November 2009). The Go Programming Language (FLV) (Tech talk). Google. Event occurs at 8:53.
  16. Download and install packages and dependencies - go - The Go Programming Language; see godoc.org for addresses and documentation of some packages
  17. godoc.org and, for the standard library, golang.org/pkg
  18. Rob Pike, on The Changelog podcast
  19. 19.0 19.1 19.2 Will Yager, Why Go is not Good
  20. Egon Elbre, Summary of Go Generics discussions
  21. Danny Gratzer, Leaving Go
  22. 22.0 22.1 Jared Forsyth, Rust vs. Go
  23. Janos Dobronszki, Everyday Hassles in Go
  24. Rob Pike, Less is exponentially more
  25. The Go Authors, Frequently Asked Questions (FAQ)
  26. Rob Pike, Generating code
  27. Richard Hudson, Go 1.4+ Garbage Collection (GC) Plan and Roadmap
  28. 28.0 28.1 Pike, Rob (26 September 2013). "Arrays, slices (and strings): The mechanics of 'append'". The Go Blog. Retrieved 7 March 2015.
  29. Andrew Gerrand, Go Slices: usage and internals
  30. The Go Authors, Effective Go: Slices
  31. Rob Pike, Strings, bytes, runes and characters in Go, 23 October 2013
  32. Assignability - the Go Language Specification
  33. Constants - the Go Language Specification
  34. "A Tutorial for the Go Programming Language". The Go Programming Language. Google. Retrieved 10 March 2013. In Go the rule about visibility of information is simple: if a name (of a top-level type, function, method, constant or variable, or of a structure field or method) is capitalized, users of the package may see it. Otherwise, the name and hence the thing being named is visible only inside the package in which it is declared.
  35. Download and install packages and dependencies - go - The Go Programming Language
  36. Share by communicating - Effective Go
  37. Andrew Gerrand, Share memory by communicating
  38. Andrew Gerrand, Codewalk: Share memory by communicating
  39. For more discussion, see Rob Pike, Concurrency is not Parallelism
  40. The Go Programming Language Specification. This deliberately glosses over some details in the spec: close, channel range expressions, the two-argument form of the receive operator, unidrectional channel types, and so on.
  41. Concurrency patterns in Go
  42. John Graham-Cumming, Recycling Memory Buffers in Go
  43. tree.go
  44. Ewen Cheslack-Postava, Iterators in Go
  45. sync - The Go Programming Language
  46. 46.0 46.1 "The Go Memory Model". Google. Retrieved 5 January 2011.
  47. Russ Cox, Off to the Races
  48. Rob Pike (October 25, 2012). "Go at Google: Language Design in the Service of Software Engineering". Google, Inc. "There is one important caveat: Go is not purely memory safe in the presence of concurrency."
  49. Brian W. Kernighan, A Descent Into Limbo
  50. Reader - io - The Go Programming Language
  51. SHA-256 test vectors, set 1, vector #8
  52. src/pkg/net/ip.go
  53. Type Assertions - The Go Language Specification
  54. Type switches - The Go Language Specification
  55. reflect.ValueOf(i interface{}) converts an interface{} to a reflect.Value that can be further inspected
  56. "Go Data Structures: Interfaces". Retrieved 15 November 2012.
  57. Interface types - The Go Programming Language Specification
  58. "Effective Go — Interfaces and methods & Embedding". Google. Retrieved 28 November 2011.
  59. Panic And Recover, Go wiki
  60. Release notes, 30 March 2010
  61. "Proposal for an exception-like mechanism". golang-nuts. 25 March 2010. Retrieved 25 March 2010.
  62. Effective Go: Panic
  63. "E2E: Erik Meijer and Robert Griesemer – Going Go". Channel 9. Microsoft. 7 May 2012.
  64. Commentary - Effective Go
  65. LiteIDE
  66. "A Tutorial for the Go Programming Language". golang.org. 16 January 2010. Retrieved 18 January 2010.
  67. https://gobyexample.com/reading-files. Missing or empty |title= (help)
  68. http://golang.org/pkg/os/. Missing or empty |title= (help)
  69. Erik Unger, The Case For Go
  70. Andrew Gerrand, Four years of Go, The Go Blog
  71. dl.google.com: Powered by Go
  72. Matt Welsh, Rewriting a Large Production System in Go
  73. David Symonds, High Performance Apps on Google App Engine
  74. Patrick Lee, Open Sourcing Our Go Libraries, 7 July 2014.
  75. John Graham-Cumming, Go at CloudFlare
  76. John Graham-Cumming, What we've been doing with Go
  77. Peter Bourgon, Go at SoundCloud
  78. Matt Aimonetti
  79. Simionato, Michele (15 November 2009). "Interfaces vs Inheritance (or, watch out for Go!)". artima. Retrieved 15 November 2009.
  80. Astels, Dave (9 November 2009). "Ready, Set, Go!". engineyard. Retrieved 9 November 2009.
  81. Paul, Ryan (10 November 2009). "Go: new open source programming language from Google". Ars Technica. Retrieved 13 November 2009.
  82. "Google's Go Wins Programming Language Of The Year Award". jaxenter. Retrieved 5 December 2012. |first1= missing |last1= in Authors list (help)
  83. "TIOBE Programming Community Index for August 2014". TIOBE Software. August 2014. Retrieved 22 August 2014.
  84. "Organizations Using Go".
  85. Bruce Eckel (27 August 2011). "Calling Go from Python via JSON-RPC". Retrieved 29 August 2011.
  86. "Gopher".
  87. "FAQ — The Go Programming Language". Golang.org. Retrieved 2013-06-25.
  88. Claburn, Thomas (11 November 2009). "Google 'Go' Name Brings Accusations Of Evil'". InformationWeek. Retrieved 18 January 2010.
  89. "Issue 9 - go — I have already used the name for *MY* programming language". Google Code. Google Inc. Retrieved 12 October 2010.

External links