Golang Diaries II

Search

I still haven’t written a thousand lines of Go; but what I have created
does useful work and (considering I had to learn a language and a bunch of
libraries along the way) didn’t burn that much time. Herewith another batch
of
programming-permanoob
reportage.

Isn’t it pathetic that so many allegedly-mainstream languages don’t have
HTTP libraries that are this natural and idiomatic?

Other Good Stuff ·
Just like everyone says, Go makes concurrency a lot easier, without having
to think about monads or actors or transactions. Just write simple linear
code (like that HTTP stuff above) and farm it out with go-routines and
channels.

This is great... these all go do their thing and send the results back
whenever they get them (the WebFist flow
involves two different HTTP round-trips). Then I watch the results trickle
in, bail on a time-out (currently 2 seconds, hmm), exit if I get an
authoritative result, otherwise select from among the others based on a bunch
of heuristics; I don’t spend a microsecond thinking about concurrency
issues.

Some of the important virtues of Erlang here, without the dorky syntax and
general weirdness.

Happiness ·
Matz wrote Ruby to make programmers happy, and it makes me happy. Go
doesn’t particularly, but I’ll probably keep using it.

In Ruby code I find the smallest semantic gap between the image of the
problem in my head and the code on my screen. In C, I find the smallest
semantic gap between the code on the screen and my understanding of what the
computer does.

Go gets real close to C in terms of the mapping onto the underlying
machine. There’s no reason that Go shouldn’t be as fast as C, and given the
quality of the team working on it, I’m sure it will be.

Go isn’t nearly as close as Ruby to the model in my head, but it’s a whole
hell of a lot closer than C is. This seems to me like a decent trade-off.

I stumbled across
Quotes About Go Programming at
cat-v.org, and while the enthusiasts are kind of boring, I found I was
resonating with some of the more balanced takes, such as If I had to
describe Go with one word it’d be “sensible”. and Why would you have a
language that is not theoretically exciting? Because it’s very useful.

Type -= Ceremony ·
Static typing is so much less painful when you have good type
inference, as Go has. I’m wondering how much of my cursing at Java
is really at all the declaration ceremony; it gets in the way of the work I’m
trying to do. Sometimes it’s helpful for readability to make a type visible,
and Go has the
var facility for doing that.

And Last, the Gripes ·
It really irritates me, that in a modern programming
language, if I have an array full of type Foo, and a function
that converts Foo to Bar, there isn’t a
map() method that just gives me an array full of
Bar. And then a separate concurrentMap(), which
does the obvious.

Golang is sort of half-pregnant; it provides the incredibly-useful
append()
method, that appends to any type of array.

No, this is not a plea for generics! I just want some functional
goodies.

Speaking of missing goodies, a little introspection would be nice. If you
glance at that findIDP code fragment above, it’s obvious that I have a lot of
different chunks of software that offer what you might call a
Searcher interface. Why can’t I have them all in a directory
or package or somewhere and let the program figure out how many there are and
fire them all off? Quite possibly it can and I just haven’t got there yet.

I'm afraid that I'm not well-versed in FP nor am I much more than a beginner with Go, but I wanted to comment on your mention of a map() function in Go.

If you define a slice as a variant type by using an empty interface ( interface{} ) you can then define a function that will operate on a slice of variants returning a slice of variants. Each element of the slice can then hold any type.

In the main() function, I create a slice of three strings and apply the toIntTimesTwo() function on each element converting each from string to int, then doubling the value before that value is appended to a new slice. When the slices are displayed using the dumpSlice() function, you'll see that the slice of strings is converted to a slice of ints.

The myMap() function can accept a slice of interface{} elements and a reference to a function ( I hope I'm using the right nomenclature when I say "reference" ) that accepts one interface{} value and returns one interface{} value.

I don't think it's terribly pretty, but I think what you were referring to can be done.

I think Go is well on its way to replace Python. I know, it sounds counter-intuitive, but every positive review I've read of Go came from Python (and to some extent, Ruby) developers. Bit of a surprise, but if a statically typed language gets Python developers to say things like "Because of Go, I haven't written a line of Python in six months", you know something is afoot.

Apart from that, I still cringe at Go's error handling with its "err, ok := Foo(); if err return failure" every other ten lines which brings back such bad memories of this kind of error handling (HRESULT nightmares, anyone?).

Go is a higher productivity language that C for most tasks (systems, library, etc.) It's not a cure-all and won't replace X or Y completely, but it has a clear utility as being better than C for the majority of systems tasks. It would be interesting to see a large-scale OS kernel or database written primarily in Go.

>> Why can’t I have them all in a directory or package or somewhere and let the program figure out how many there are and fire them all off? Quite possibly it can and I just haven’t got there yet.

You can do this in a slightly different way, by provideing a way for the "searchers" to register themselves. Then have each "Searcher" register itself in the "init" function of it's package/file, then use the "import for side-effects only" feature to include the package, which in turn will register your Searcher. e.g.