The runtime is not regular Go code, it's tricky Go code that doesn't have access to the standard library, full of pointer manipulations using unsafe, and with no heap-escaped variables. It also has to deal the fact that the C compiler didn't produce stack maps with type information (and even if it did, it would not have been that useful since it abused uintptr's), so Go code must be really careful about when the stacks are allowed to be moved and how pointers must get proper types.
In short, the Go code in the runtime is about at the same level at C code.
Don't forget that this is a straight 1-to-1 translation; this is not the time to introduce new bugs. After it's all done, the runtime code can be refactored and it might become cleaner and smaller.
PS: there are no go errors, and hence no if err != nil statements in the runtime.
Well its not "much" higher level. It adds memory management and a simpler concurrency story, which helps. But e.g. no generics, no algebraic data types, no pattern matching. Plenty of things will still have to be done by hand. I'm not super surprised.
The runtime code probably deals with a few things that aren't as compact in Go either. For example using the unsafe package in Go is very verbose since you are trying to work around the type system. C just lets you dereference any pointer you want etc etc.
There are many types of code that are significantly longer in C# or java than in C, just because C lets you do crazy things with memory mapping.
To get more terse code, you need to switch from the C family of sytax imo.
There are plenty of C family syntax languages that are more compact. The main reason why Go is very verbose is because it doesn't support generics (so you have to duplicate a lot of code) and no exceptions (so your code is littered with
ok, err := Foo()
if err { ... }
and then the caller has to do the same thing (basically reinventing manually what exceptions do for you).
Absent exceptions, for quick-and-dirty stuff I wish Go had a mode like Bash's 'set -e', which just aborts on any error return from any call. When the only thing you want to do on errors is abort the program, it's really tedious to write that same "if err, exit" after every function call. But perhaps the golang people's answer would be that for those kinds of quick-and-dirty programs, I should be using a shell script anyway, not Go? Or maybe Perl, which does require an explicit check, but uses a compact idiom for it, f() or die;
Yeah, I'd quite like an `or die;` equivalent, as I've run into the same thing as you: scripts that can't do anything if the chain of commands fails anywhere. I have written functions that do the same thing: xOrDie(), but it's a bit sucky.
As far as "Why Go for shell scripts?" I actually think Go is pretty well suited to shell scripts (aside from no or die): getting stdout/stderr pipes set up is pretty trivial with the exec package. There must be anecdotal law somewhere that states that all shell scripts tend to Turing completeness over time: what starts with "oh, a small shell script would do this" always ends up growing to a full blown 1000+ line program with multiple code paths. Writing the first script in Go is a piece of defensive programming so that when it inevitably grows, it's growing into a language that better supports its size (static typing, readability, libraries etc.) It's probably overkill for personal stuff, but it is probably the right hammer for the job over time when it comes to corporate work.
The higher level primitives that Go provides aren't suitable to be used when implementing the runtime. The subset of Go suitable for runtime implementation is pretty close to C in most respects.
It may also be an artifact of the automated translation process. I reckon it probably produces pretty "C-like" Go code. Later, when they go over it manually, some things might get cleared up more idiomatically.
I would guess it is the `if err` lines and other such gofmt artifacts that expand the LOC. Go is higher-level, but it's not terse. It's deliberately pretty explicit. IMHO 100 lines of Go might well do the same as 100 lines of C, but the Go will be much more readable code.
If we judge for ourselves we will only be checking our opinion.
Could you provide a readability algorithm in some form of executable that we can run against the 100 lines of c and Go code — then we'll be able to judge correctly.
It surprises me, because from what I've seen Go seems to be much higher level language. Or are those just all the `if err != nil` lines?