Exercises for the O'Reily book "Leaning Go, 2nd Edition"
  • Go 98.5%
  • Makefile 1.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-18 15:22:57 -07:00
ch1 Chapter 1 complete 2026-07-27 17:08:47 -07:00
ch2 Chapter 2 complete 2026-07-27 20:43:47 -07:00
ch3 Chapter 3 complete 2026-08-09 22:21:43 -07:00
ch4 Chapter 4 complete 2026-08-09 22:21:54 -07:00
ch5 Chapter 5 complete 2026-08-24 16:28:21 -07:00
ch6 Chapter 6 complete 2026-08-26 00:28:47 -07:00
ch7 Chapter 7 complete 2026-09-06 16:40:25 -07:00
ch8 Chapter 8 complete(ish) 2026-09-18 15:22:57 -07:00
README.org Chapter 8 complete(ish) 2026-09-18 15:22:57 -07:00

Chapter Notes

Chapter 1

Chapter 2

  • Leading 0 with no prefix being octal is strange. I'm glad the book suggests not using it to reduce confusion.
  • Underscores allowed in numbers for place separation makes me happy.
  • rune literal :: single character, denoted with single quotes. Common escapes are runes; e.g., \n, \t, \', \\
  • interpreted string literal :: double quoted strings. Called interpreted because they interpret runes into single characters
  • raw string literal :: backquoted string, runes are not interpreted automatically
  • The result of integer division is also an integer, not a float.
  • += etc are valid for modifying; e.g., somevar *= 3
  • declaration lists :: Allows assigning multiple variables at once, as a part of a single visual block

       var (
      	a rune
      	b int = 10
      	c = 30
      )
  • := :: declaration and assignment shorthand. Like var but also does assignment to existing variables. only valid inside of functions

      a, b := 20, 40
      a := 60
  • Immutability in go is pretty limiting…
  • Similar to zig, unread variables cause a compile time error

    • I still think that while this makes sense at the end of a feature development, it's needlessly frustrating during development. I wish this could be turned off for dev builds and enforced for production builds.
  • Unicode allowed in var names is neat, but feel like they'd be a pain to actually use… glad the book calls this out.
  • Camel case over snake case.
  • wat?

    This is because Go uses the case of the first letter in the name of a package-level declaration to determine if the item is accessible outside the package.

Chapter 3

  • Weird restrictions on array typing. Hope that I hear more about why.
  • ok, so slices are the real arrays, I guess? That nomenclature is a bit obnoxious.
  • ok, so we finally found nil
  • nil isn't comparable, but a length of nil is 0?
  • Despite the kinda weird nomenclature around slices, I do like the split between length and capacity.

    • make(int[], 0, 10) is a neat way to start with nothing, knowing you probably won't go above 10
  • Slicing slices sharing a memory address seems like a really cool feature but a sharp knife. I already know that at some point I am going to accidentally change a value I don't expect with this.
  • map[string][]string is so difficult to visually parse.
  • The comma ok idiom makes me want to just have an :ok sigil again.

Chapter 4

  • Scoping a variable to an if block is neat. Gotta think on if it's actually useful though. I guess it kind of formalizes something I do fairly frequently: declaring a var right above a scope for use in it.

      if n := rand.Intn(10); n == 0 {
      	fmt.Println("That's too low")
      } else if n > 5 {
      	fmt.Println("That's too big:", n)
      } else {
      	fmt.Println("That's a good number:", n)
      }
  • I have… feelings… about Go only having a for loop.

    • no do...while I have less strong feelings about, I guess.
    • I feel like fewer keywords here is just going to make the code harder to understand.
    • I don't feel like for-range is an improvement over the more common for-in.
    • Having for-range give a random order during iteration, but a fixed order in a debugging print, feels likely to bite.
  • No fall-through on switch pleases me.
  • Scoping to a block will take practice to recognize, took me a couple of passes to understand how this is a "blank switch":

      switch someVar := 10; {
      	case 1,2,3,4:
      		// something
      	default:
      		// something else
      }
  • I appreciate the reasoning the author provides for deciding between a switch and if/else. Switch indicates a relationship between the evils.

Chapter 5

  • I dislike this kind of generalization:

    In practice, not having named and optional parameters isn’t a limitation.

  • variadic operator is so formal, why not call it a spread operator like everyone else?
  • Sometimes I forget that tuple returns aren't actually multiple returns, especially when destructuring is so common.

    The first difference that you’ll see between Go and other languages is that Go allows for multiple return values.

  • I get why this is done – I even like it – but it still feels so weird to draw a hard line on "no named params" and then allow named returns.
  • Woah, did this guy just call Go out for something it's bad at? That's rad. No zealotry here, I guess.

    If you use named return values, you need to be aware of one severe misfeature in Go: blank (sometimes called naked) returns.

  • Assigning functions to variables it interesting, maybe the first really novel thing that I've seen (or I'm just forgetting some other lang doing this)

    • The variable's type is the function's signature
    • Any function matching that signature can be assigned to the variable
    • I'm not entirely sure where this will be be valuable offhand (examples seem a bit contrived), but it's neat at least
  • hmm, I like the declaration list syntax for variables, but I don't know how I feel about it for functions.
  • I'm not sure that Empirical Software Engineering meant that a block level indentation significantly increased code complexity. Many of the code examples in this book are difficult to read simply because they lack spacing between logical blocks, which seems more impactful to me than adding a tab to a begin block.

Chapter 6

  • Have a feeling I'm going to skip a lot of this chapter, based on the first couple of pages.

    • Future Nate: I was wrong.
  • lol, nil can be shadowed. Strange that it's not a reserved keyword.
  • nil causing a panic on dereference is probably why it seems common to return a default value even when an error exists rather than nil, saves a check.

      func someExample() (int, error) {
      	return 0, errors.New("I am destined to fail. Woe is me.")
      }
  • Been a while since I really worked with pointers, but it still irks me that the indirection operator and the pointer type both us *. I know it's not a big deal, I know it makes sense in context, but it still irks me.
  • Good to know

    You can’t use an & before a primitive literal (numbers, booleans, and strings) or a constant because they don’t have memory addresses; they exist only at compile time.

  • ehhh… I'm not sold on this. Willing to be proven wrong.

    The lack of immutable declarations in Go might seem problematic, but the ability to choose between value and pointer parameter types addresses the issue.

  • This bothers me. Mechanical sympathy requires understanding. It can not be given automatically no matter how cool your best practices are.

    This approach of writing software that’s aware of the hardware it’s running on is called mechanical sympathy. The term comes from the world of car racing, where the idea is that a driver who understands what the car is doing can best squeeze the last bits of performance out of it. In 2011, Martin Thompson began applying the term to software development. Following best practices in Go gives it to you automatically.

  • This chapter was long.

Chapter 7

Good to know.

It is nonidiomatic to use this or self.

  • No function overloading seems like the right choice for Go. I really, really like the idea of function heads in Elixir, but I don't think that would fit well here and I'm glad they went the other way.
  • Good.

    methods must be declared in the same package as their associated type; Go doesn’t allow you to add methods to types you don’t control.

  • Interesting, curious as to why this is a hard rule.

    methods must be declared in the same package as their associated type; Go doesn’t allow you to add methods to types you don’t control.

  • lol, "allowing you to call a method on nil is very useful, except when it isn't"
  • Special syntax for methods when assigned as functions to take the instance as a parameter is neat… but it doesn't seem very "small simple language"
  • I like that declaring a type based on another type isn't actually inheritance. Similar but not the same vibes here.

    • It does, however, seem a little inconvenient that methods don't carry over. I assume we'll see interfaces here soon that will solve for this.
  • No, I don't think I like this. This is the kind of special syntax that I will completely forget about and be confused as fuck over later… which means I have to use it just to remember that it exists.

    The first constant in the const block has the type specified, and its value is set to iota. Every subsequent line has neither the type nor a value assigned to it. When the Go compiler sees this, it repeats the type and the assignment to all the subsequent constants in the block, which is iota.

    Field2 is assigned 2 because iota has a value of 1 on the second line in the const block.

  • I approve of composition over inheritance

    • I'm not a big fan of clever syntax though. "A field without a name is embedded" is too clever for me.
    • I think at this point Go has enough of this that it's starting to get questionable how easy Go will actually be to read.
  • Oh goody, here's those interfaces I knew were coming
  • …. all right, then.

    Interfaces are usually named with “er” endings.

  • GTFO of here with your acceptance of nuance

    Go’s developers decided that both groups are right.

  • Not going to lie, this is my third session trying to get through this chapter, and I'm struggling to stay interested in it. I might be skimming a bit at this point…

Chapter 8

  • Yep, those are generics.
  • skim…. skim…. skim….