Instantly, and progressively, by starting at the top and working through a single document that is both a reference and a guide.
Beautiful work.
Edit: One change I would make is to change p := pair{3, 4} into p := pair{x: 3, y: 4} which helps your declarations keep working in the future when you extend or modify the definition of `pair`.
Go isn't a Lisp, last I checked. I am referring to "Pair" as a class/interface in an OO language. If you're using Pair to construct a linked list in a OO language, I salute you, but that's even more of an anti-pattern.
Pair is an OO anti-pattern because it's an arbitrary grouping of two things in a generic container, and you shouldn't do that in OO - classes are cheap. You should make a class that represents what the collection of those two things actually are. Typical field names in generic Pair objects are 'left' and 'right' or 'first' and 'second' which tells you nothing about the values you stick into them (except the types, if you're using a strongly typed language). If, as suggested in the example, the pair holds a 'x' and a 'y', a better choice could be to call it "Point" or even "Point2D". If it's a key/value pair from a map data structure it should be "Entry" with fields "key" and "value" - etc.
It is worth pointing out that the pair in question is indeed an {x, y int} (using Go's ability to elide repeated types, so this means both x and y are an int). The name may be poor, but since it also will in general use be paired with the module name, it may not be, either. "Pair" is a poor name, rationals.Pair might not be.
A truly generic Pair in go would be Pair{interface {}, interface{}}, and that would be a code smell. (Only a smell though, since it's possibly part of some larger construct that is basically getting around Go's compile-time type system and replacing it with a run-time check.)
It's generic, not in the Java-generics sense of the work, but in the sense that x and y are generic names - they don't tell you what x and y are. Yes, they are of type int, but are they apples or oranges? In the example, they are indeed just two numbers that we chose to keep together, although the name and field names suggest that the author has a point in mind.
rationals.Pair is still a poor name, it's a pair of what and for what purpose? Assuming you're referring to rational numbers, ratio struct {p, q int} is better.
In my C code I've been moving away from distinguishing primitive types by name alone, preferring to wrap them in single-element structs to get some type safety:
Yes, it's less informative, because you're missing the context of why the apples and oranges are lumped together in the pair. FWIW fruit_basket_t is poorly named too, since fruit baskets not things that can count apples and oranges (and nothing else), they are generic containers capable of holding all kinds of fruit.
I like the single-element structs. I've been finding myself doing that more and more in Java and I quite enjoy it. First epiphany was replacing bool with enums.
I don't think "fruit_basket" (or "fruit_counts", say, addressing your later point) really gives much more clue as to why you're grouping these things than does the templated pair. When there is an informative name, use it, to be sure. Occasionally there's not much more reason than "I am using both of these elsewhere. This is much more the case when things are used locally than when they are exposed in interfaces, to be sure.
Agreed. Diving in to examples is the best way to learn. I'm usually wary of these "Learn X in Y minutes" posts, but this one is great - maybe due to Go's succinctness?
Instantly, and progressively, by starting at the top and working through a single document that is both a reference and a guide.
Beautiful work.
Edit: One change I would make is to change p := pair{3, 4} into p := pair{x: 3, y: 4} which helps your declarations keep working in the future when you extend or modify the definition of `pair`.