Reading the spec probably isn't the best way to experience the "fun" in any case. (Though the spec is worth a read once you've use the language a bit -- as far as specs go, it's concise and readable.)
"Fun" is quite a personal thing, but similar people often have similar experiences, so I'll take a stab at answering from my perspective:
Go is fun because the language is:
* Easy to learn: I learned it coming from years of Python and some C. You can be productive in Go in a couple of weeks. My first medium-sized project in Go was porting a web backend from Python to Go, and I found it a lot of fun (
https://benhoyt.com/writings/learning-go/).
* Builds fast: even large programs compile and build in seconds (not minutes or hours). Go caches builds of packages that haven't changed, meaning the time from editing code to running it is very short, sometimes close to instantaneous.
* Runs fast: Go compiles to reasonably fast native code. Coming from an interpreted language like Python, this is great when you need to do something like loop over the characters in a string.
* Solid stdlib: enough quality stuff in the standard library to get a lot done quickly.
* Concrete focus: good Go code (like the stdlib) tends toward
concrete types and simple patterns rather than abstract interfaces,
factories, and deep nesting.
* Excellent tooling: "go build" builds your project with no ceremony. "go test ./..." runs all your tests. "go run" builds and runs a program in one step. The caches for the above just work.
The above is why Go is fun for me. That leaves out Go's other unique features (though arguably these are more "useful" than "fun"):
* Unique take on types and interfaces that doesn't result in an inheritance mess.
* Statically typed. For medium-sized to large projects, this really helps reassure you when refactoring (compared to Python, JavaScript, and so on).
* Generic slices and maps: right from Go 1 (that is, pre-Go 1.18-generics), Go always had type-safe growable arrays and hash tables, two of the most useful data structures.
* (Some) control over memory allocation. You don't usually have to worry about it, but when you need to reduce allocations, you can: make(), reuse buffers, and so on.
* Goroutines and channels. Concurrency is never easy, but at least with Go the primitives are built into the language and relatively straight-forward to learn.
* io.Reader and io.Writer. These are simple but amazing tools for composing I/O (I'm comparing to things like the vague mess that is Python's "file-like objects").
* The Go community's focus on few dependencies. So much better than the pain and fragility of a node_modules directory with 1500 entries.
* Easily-deployable binaries. Instead of having to ship around a big runtime and stdlib, to deploy a Go program, you just copy the binary to the target machine. (And Go 1.16's "embed" means you can even include your static files, templates, and so on.)
* Incredible cross-compilation. Just set two environment variables (GOOS and GOARCH) and type "go build", and have a macOS or Windows binary a few seconds later.
I'm sure others have their own lists...
-Ben