github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/talks/2012/goforc.slide (about) 1 Go for C programmers 2 ACCU, Silicon Valley Chapter, Nov. 14, 2012 3 4 # Go is a general-purpose programming language developed at Google. 5 # Go's design is influenced by the C and Pascal lineage, but instead of providing 6 # a conglomerate of features, Go takes a fresh look at the essential mechanisms 7 # required for modern programming tasks. As a result, Go has evolved to a compact 8 # language of surprising power. In this presentation we give a brief introduction 9 # to Go, slightly slanted towards programmers with a C/C++ background, and then 10 # talk about particularly interesting aspects of Go. 11 12 Robert Griesemer 13 Google Inc. 14 gri@golang.org 15 16 * Organization of this talk 17 18 Part 1: Introduction to Go 19 20 Break 21 22 Part 2: Object-oriented and concurrent programming in Go 23 24 # if time permits and desire exists 25 26 * Motivation 27 28 * Have 29 30 Incomprehensible and unsafe code. 31 32 Extremely slow builds. 33 34 Missing concurrency support. 35 36 Outdated tools. 37 38 # C, C++ are > 30 years old! 39 # Java is 15 years old, but not really a systems-programming language. 40 # (No control over data layout, no unsigned, verbose, etc.) 41 42 * Want 43 44 Readable, safe, and efficient code. 45 46 A build system that scales. 47 48 Good concurrency support. 49 50 Tools that can operate at Google-scale. 51 52 # A language for the 21. century! 53 54 * Meet Go 55 56 Compact, yet expressive 57 # spec is ~50 pages 58 59 Statically typed and garbage collected 60 61 Object- but not type-oriented 62 63 Strong concurrency support 64 65 Efficient implementation 66 67 Rich standard library 68 69 Fast compilers 70 71 Scalable tools 72 73 * Hello, World 74 75 .play goforc/hello.go 76 77 # the canonical first program 78 # note: immediately readable for a C programmer even without prior knowledge of Go 79 # (not the case with C++'s Hello, World, which is using the << operator) 80 # which bring us to the first item on the "Want" list: readable code. 81 82 * Syntax 83 84 * Syntax 85 86 _Syntax_is_not_important..._-_unless_you_are_a_programmer._ 87 Rob Pike. 88 89 _The_readability_of_programs_is_immeasurably_more_important_than_their_writeability._ 90 Hints on Programming Language Design 91 C. A. R. Hoare 1973 92 93 # A lot of effort has gone into honing Go's syntax over more than 3 years. 94 # The result is a clutter- and stutter-free, compact, yet readable notation. 95 # Consider some alternatives... 96 97 * Too verbose 98 99 scoped_ptr<logStats::LogStats> 100 logStats(logStats::LogStats::NewLogStats(FLAGS_logStats, logStats::LogStats::kFIFO)); 101 102 # real example from C++ (2012) (names changed) 103 # logStats mentioned 9 times! 104 # too much clutter 105 106 * Too dense 107 108 (n: Int) => (2 to n) |> (r => r.foldLeft(r.toSet)((ps, x) => 109 if (ps(x)) ps -- (x * x to n by x) else ps)) 110 111 # prime sieve in Scala 112 # pretty and short but incomprehensible 113 114 * Just right 115 116 t := time.Now() 117 switch { 118 case t.Hour() < 12: 119 return "morning" 120 case t.Hour() < 18: 121 return "afternoon" 122 default: 123 return "evening" 124 } 125 126 # looks like pseudo code 127 # readable even w/o knowing Go 128 # lots of things are going on but not relevant for understanding 129 # no clutter 130 131 * Reading Go code 132 133 * Packages 134 135 A Go program consists of _packages_. 136 137 A _package_ consists of one or more _source_files_ (`.go` files). 138 139 Each _source_file_ starts with a _package_clause_ followed by declarations. 140 141 .code goforc/hello.go 142 143 By convention, all files belonging to a single package are located in a single directory. 144 145 * Declarations, "Pascal-style" (left to right) 146 147 Pattern: keyword names [type] [initializer] 148 149 .code goforc/decls.go /START/,/STOP/ 150 151 * Why? 152 153 p, q *Point 154 155 func adder(delta int) func(x int) int 156 157 # try this in C 158 # composition of types straight-forward 159 160 * Constants 161 162 In Go, constants are _mathematically_precise_. 163 164 There is no need for qualifiers (`-42LL`, `7UL`, etc.) 165 166 .code goforc/consts.go /START1/,/STOP1/ 167 168 Only when used, constants are truncated to size: 169 170 .play goforc/consts.go /START2/,/STOP2/ 171 172 Huge win in readability and ease of use. 173 174 * Types 175 176 Familiar: 177 - Basic types, arrays, structs, pointers, functions. 178 179 But: 180 - `string` is a basic type. 181 - No automatic conversion of basic types in expressions. 182 - No pointer arithmetic; pointers and arrays are different. 183 - A function type represents a function; context and all. 184 185 New: 186 - _Slices_ instead of array pointers + separate length: `[]int` 187 - _Maps_ because everybody needs them: `map[string]int` 188 - _Interfaces_ for polymorphism: `interface{}` 189 - _Channels_ for communication between goroutines: `chan` `int` 190 191 * Variables 192 193 Familiar: 194 195 .code goforc/vars.go /START1/,/STOP1/ 196 197 New: Type can be inferred from type of initializing expression. 198 199 .code goforc/vars.go /START2/,/STOP2/ 200 201 Shortcut (inside functions): 202 203 .code goforc/vars.go /i :=/ 204 205 It is _safe_ to take the address of _any_ variable: 206 207 .code goforc/vars.go /return/ 208 209 * Functions 210 211 Functions may have multiple return values: 212 213 func atoi(s string) (i int, err error) 214 215 Functions are first-class citizens (_closures_): 216 217 .code goforc/adder.go /START1/,/STOP1/ 218 .play goforc/adder.go /START2/,/STOP2/ 219 220 * Statements 221 222 .code goforc/stmts.go /START/,/STOP/ 223 224 * Go statements for C programmers 225 226 Cleanups: 227 228 - No semicolons 229 - Multiple assignments 230 - `++` and `--` are statements 231 - No parentheses around conditions; curly braces mandatory 232 - Implicit `break` in `switch`; explicit `fallthrough` 233 234 New: 235 236 - `for` `range` 237 - type `switch` 238 - `go`, `select` 239 - `defer` 240 241 * Assignments 242 243 Assignments may assign multiple values simultaneously: 244 245 a, b = x, y 246 247 Equivalent to: 248 249 t1 := x 250 t2 := y 251 a = t1 252 b = t2 253 254 For instance: 255 256 a, b = b, a // swap a and b 257 i, err = atoi(s) // assign results of atoi 258 i, _ = atoi(991) // discard 2nd value 259 260 * Switch statements 261 262 Switch statements may have multiple case values, and `break` is implicit: 263 264 switch day { 265 case 1, 2, 3, 4, 5: 266 tag = "workday" 267 case 0, 6: 268 tag = "weekend" 269 default: 270 tag = "invalid" 271 } 272 273 The case values don't have to be constants: 274 275 switch { 276 case day < 0 || day > 6: 277 tag = "invalid" 278 case day == 0 || day == 6: 279 tag = "weekend" 280 default: 281 tag = "workday" 282 } 283 284 * For loops 285 286 .code goforc/forloop.go /START1/,/STOP1/ 287 288 A `range` clause permits easy iteration over arrays and slices: 289 290 .play goforc/forloop.go /START3/,/STOP3/ 291 292 Unused values are discarded by assigning to the blank (_) identifier: 293 294 .code goforc/forloop.go /START2/,/STOP2/ 295 296 * Dependencies 297 298 * Dependencies in Go 299 300 An _import_declaration_ is used to express a _dependency_ on another package: 301 302 import "net/rpc" 303 304 Here, the importing package depends on the Go package "rpc". 305 306 The _import_path_ ("net/rpc") uniquely identifies a package; multiple packages may have the same name, but they all reside at different locations (directories). 307 308 By convention, the package name matches the last element of the import path (here: "rpc"). 309 310 _Exported_ functionality of the `rpc` package is available via the _package_qualifier_ (`rpc`): 311 312 rpc.Call 313 314 A Go import declaration takes the place of a C _include_. 315 316 * Naming: An excursion 317 318 How names work in a programming language is critical to readability. 319 Scopes control how names work. 320 Go has very simple scope hierarchy: 321 322 - universe 323 - package 324 - file (for imports only) 325 - function 326 - block 327 328 * Locality of names 329 330 Upper case names are _exported_: `Name` _vs._ `name`. 331 332 The package qualifier is always present for imported names. 333 334 (First component of) every name is always declared in the current package. 335 336 One of the best (and hardest!) decisions made in Go. 337 338 * Locality scales 339 340 No surprises when importing: 341 342 - Adding an exported name to my package cannot break your package! 343 344 Names do not leak across boundaries. 345 346 In C, C++, Java the name `y` could refer to anything. 347 In Go, `y` (or even `Y`) is always defined within the package. 348 In Go, `x.Y` is clear: find `x` locally, `Y` belongs to it, and there is only one such `Y`. 349 350 Immediate consequences for readability. 351 352 * Back to imports 353 354 Importing a package means reading a package's exported API. 355 356 This export information is self-contained. For instance: 357 358 - A imports B 359 - B imports C 360 - B exports contain references to C 361 362 B's export data contains all necessary information about C. There is no need for a compiler to read the export data of C. 363 364 This has huge consequences for build times! 365 366 * Dependencies in C 367 368 `.h` files are not self-contained. 369 370 As a result, a compiler ends up reading core header files over and over again. 371 372 `ifdef` still requires the preprocessor to read a lot of code. 373 374 No wonder it takes a long time to compile... 375 376 At Google scale: dependencies explode, are exponential, become almost non-computable. 377 378 A large Google C++ build can read the same header file tens of thousands of times! 379 380 # it is real work, too, teaching the compiler what a string is each time 381 382 * Tools 383 384 * A brief overview 385 386 Two compilers: gc, gccgo 387 388 Support for multiple platforms: x86 (32/64bit), ARM (32bit), Linux, BSD, OS X, ... 389 390 Automatic formatting of source code: `gofmt` 391 392 Automatic documentation extraction: `godoc` 393 394 Automatic API adaption: `gofix` 395 396 All (and more!) integrated into the `go` command. 397 398 * Building a Go program 399 400 A Go program can be compiled and linked without additional build information (`make` files, etc.). 401 402 By convention, all files belonging to a package are found in the same directory. 403 404 All depending packages are found by inspecting the import paths of the top-most (_main_) package. 405 406 A single integrated tool takes care of compiling individual files or entire systems. 407 408 * The go command 409 410 Usage: 411 412 go command [arguments] 413 414 Selected commands: 415 416 build compile packages and dependencies 417 clean remove object files 418 doc run godoc on package sources 419 fix run go tool fix on packages 420 fmt run gofmt on package sources 421 get download and install packages and dependencies 422 install compile and install packages and dependencies 423 list list packages 424 run compile and run Go program 425 test test packages 426 vet run go tool vet on packages 427 428 .link http://golang.org/cmd/go/ 429 430 * Break 431 432 # After the break, we will discuss OOP and concurrency in Go. 433 434 * Object-oriented programming 435 436 * What is object-oriented programming? 437 438 "Object-oriented programming (OOP) is a programming paradigm using _objects_ – usually instances of a class – consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction, encapsulation, messaging, modularity, polymorphism, and inheritance. Many modern programming languages now support forms of OOP, at least as an option." 439 440 (Wikipedia) 441 442 # Important: 443 # Notion of _objects_ 444 # _Objects_ have _state_ (data fields), and _methods_ (for interactions) 445 446 * OOP requires very little extra programming language support 447 448 We only need 449 450 - the notion of an _Object_, 451 - a mechanism to interact with them (_Methods_), 452 - and support for polymorphism (_Interfaces_). 453 454 Claim: Data abstraction, encapsulation, and modularity are mechanisms 455 in their own right, not OOP specific, and a modern language (OO or not) 456 should have support for them independently. 457 458 459 * Object-oriented programming in Go 460 461 Methods without classes 462 463 Interfaces without hierarchies 464 465 Code reuse without inheritance 466 467 Specifically: 468 469 - Any _value_ can be an _object_ 470 - Any _type_ can play the role of a _class_ 471 - _Methods_ can be attached to any _type_ 472 - _Interfaces_ implement polymorphism. 473 474 * Methods 475 476 .play goforc/point.go 477 478 * Methods can be attached to any type 479 480 .play goforc/celsius.go 481 482 * Interfaces 483 484 type Stringer interface { 485 String() string 486 } 487 488 type Reader interface { 489 Read(p []byte) (n int, err error) 490 } 491 492 type Writer interface { 493 Write(p []byte) (n int, err error) 494 } 495 496 type Empty interface{} 497 498 An interface defines a set of methods. 499 A type that implements all methods of an interface is said to implement the interface. 500 All types implement the empty interface interface{}. 501 502 * Dynamic dispatch 503 504 .play goforc/interface.go /START/,/STOP/ 505 506 A value (here: `corner`, `boiling`) of a type (`Point`, `Celsius`) that implements 507 an interface (`Stringer`) can be assigned to a variable (`v`) of that interface type. 508 509 * Composition and chaining 510 511 Typically, interfaces are small (1-3 methods). 512 513 Pervasive use of key interfaces in the standard library make it easy to chain APIs together. 514 515 package io 516 func Copy(dst Writer, src Reader) (int64, error) 517 518 The io.Copy function copies by reading from any Reader and writing to any Writer. 519 520 Interfaces are often introduced ad-hoc, and after the fact. 521 522 There is no explicit hierarchy and thus no need to design one! 523 524 * cat 525 526 .code goforc/cat.go 527 528 # An `os.File` implements the `Reader` interface; 529 # `os.Stdout` implements the `Writer` interface. 530 531 * Interfaces in practice 532 533 Methods on any types and _ad_hoc_ interfaces make for a light-weight OO programming style. 534 535 Go interfaces enable post-facto abstraction. 536 # Existing code may not know about a new interface 537 538 No explicit type hierarchies. 539 # Coming up with the correct type hierarchy is hard 540 # They are often wrong 541 # They are difficult and time-consuming to change 542 543 "Plug'n play" in a type-safe way. 544 545 # There's much more but we won't have time for more detail. 546 547 * Concurrency 548 549 * What is concurrency? 550 551 Concurrency is the composition of independently executing computations. 552 553 Concurrency is a way to structure software, particularly as a way to write clean code that interacts well with the real world. 554 555 It is not parallelism. 556 557 * Concurrency is not parallelism 558 559 Concurrency is not parallelism, although it enables parallelism. 560 561 If you have only one processor, your program can still be concurrent but it cannot be parallel. 562 563 On the other hand, a well-written concurrent program might run efficiently in parallel on a multiprocessor. That property could be important... 564 565 For more on that distinction, see the link below. Too much to discuss here. 566 567 .link http://golang.org/s/concurrency-is-not-parallelism 568 569 * A model for software construction 570 571 Easy to understand. 572 573 Easy to use. 574 575 Easy to reason about. 576 577 You don't need to be an expert! 578 579 (Much nicer than dealing with the minutiae of parallelism (threads, semaphores, locks, barriers, etc.)) 580 581 There is a long history behind Go's concurrency features, going back to Hoare's CSP in 1978 and even Dijkstra's guarded commands (1975). 582 583 * Basic Examples 584 585 * A boring function 586 587 We need an example to show the interesting properties of the concurrency primitives. 588 589 To avoid distraction, we make it a boring example. 590 591 .code goforc/example0.go /START1/,/STOP1/ 592 .play goforc/example0.go /START2/,/STOP2/ 593 594 * Ignoring it 595 596 The `go` statement runs the function as usual, but doesn't make the caller wait. 597 598 It launches a goroutine. 599 600 The functionality is analogous to the & on the end of a shell command. 601 602 .play goforc/example1.go /START/,/STOP/ 603 604 * Ignoring it a little less 605 606 When main returns, the program exits and takes the function `f` down with it. 607 608 We can hang around a little, and on the way show that both main and the launched goroutine are running. 609 610 .play goforc/example2.go /START/,/STOP/ 611 612 * Goroutines 613 614 What is a goroutine? It's an independently executing function, launched by a `go` statement. 615 616 It has its own call stack, which grows and shrinks as required. 617 618 It's very cheap. It's practical to have thousands, even hundreds of thousands of goroutines. 619 620 It's not a thread. 621 622 There might be only one thread in a program with thousands of goroutines. 623 624 Instead, goroutines are multiplexed dynamically onto threads as needed to keep all the goroutines running. 625 626 But if you think of it as a very cheap thread, you won't be far off. 627 628 * Channels 629 630 A channel in Go provides a connection between two goroutines, allowing them to communicate. 631 632 .code goforc/channels.go /START1/,/STOP1/ 633 .code goforc/channels.go /START2/,/STOP2/ 634 .code goforc/channels.go /START3/,/STOP3/ 635 636 * Using channels 637 638 A channel connects the `main` and `f` goroutines so they can communicate. 639 640 .play goforc/communication1.go /START1/,/STOP1/ 641 .code goforc/communication1.go /START2/,/STOP2/ 642 643 * Synchronization 644 645 When the main function executes `<–c`, it will wait for a value to be sent. 646 647 Similarly, when the function `f` executes `c<–value`, it waits for a receiver to be ready. 648 649 A sender and receiver must both be ready to play their part in the communication. Otherwise we wait until they are. 650 651 Thus channels both communicate and synchronize. 652 653 Channels can be unbuffered or buffered. 654 655 * Using channels between many goroutines 656 657 .play goforc/communication2.go /START1/,/STOP1/ 658 659 A single channel may be used to communicate between many (not just two) goroutines; many goroutines may communicate via one or multiple channels. 660 661 This enables a rich variety of concurrency patterns. 662 663 # There's enough material for several talks on this subject alone. 664 665 * Elements of a work-stealing scheduler 666 667 .code goforc/worker1.go /START2/,/STOP2/ 668 669 The `worker` uses two channels to communicate: 670 - The `in` channel waits for some work order. 671 - The `out` channel communicates the result. 672 - As work load, a worker (very slowly) computes the list of prime factors for a given order. 673 674 * A matching producer and consumer 675 676 .code goforc/worker1.go /START3/,/STOP3/ 677 678 The `producer` produces and endless supply of work orders and sends them `out`. 679 680 The `consumer` receives `n` results from the `in` channel and then terminates. 681 682 * Putting it all together 683 684 .play goforc/worker1.go /START1/,/STOP1/ 685 686 We use one worker to handle the entire work load. 687 688 Because there is only one worker, we see the result coming back in order. 689 690 This is running rather slow... 691 692 * Using 10 workers 693 694 .play goforc/worker2.go /START1/,/STOP1/ 695 696 A ready worker will read the next order from the `in` channel and start working on it. Another ready worker will proceed with the next order, and so forth. 697 698 Because we have many workers and since different orders take different amounts of time to work on, we see the results coming back out-of-order. 699 700 On a multi-core system, many workers may truly run in parallel. 701 702 This is running much faster... 703 704 * The Go approach 705 706 Don't communicate by sharing memory, share memory by communicating. 707 708 * There's much more... 709 710 * Links 711 712 Go Home Page: 713 714 .link http://golang.org 715 716 Go Tour (learn Go in your browser) 717 718 .link http://tour.golang.org 719 720 Package documentation: 721 722 .link http://golang.org/pkg 723 724 Articles galore: 725 726 .link http://golang.org/doc