Skip to main content

Some Go Irks and Quirks

Now that Jump Start MySQL is published, I’m taking advantage of the spare time I have on my hands while it lasts. I’ve helped organize the Syracuse PHP Users Group, reconnected with some old friends, and gave some love to Kiwi, my forever-project programming language. Moreover, I decided to rewrite Kiwi using Go as it’s one of those languages I found interesting but never had a reason to use in any serious fashion. And now that I’ve got some real experience with it, while I still find myself impressed by some of Go’s features, some things have become really annoying.

I still really like Go’s data typing; it’s static, but it feels dynamic because the compiler is smart enough to deduce a value’s type. If you write your code well then you’ll rarely see a type name outside of a function signature or struct or interface definition. It’s nice to have type safety without the verbosity (yes I’m looking at you, PHP7).

I wish := behaved slightly different, though. Instead of always an allocation, it’d be nice if it could also perform basic assignments. Then we could write code like this:

foo, bar := baz()
foo.x, fizz := quux()
But as it is now, the best we can do is:
foo, bar := baz()
var fizz MyType
foo.x, fizz = quux()
If there’s a go-ism that works around this that you know of, feel free to let me know.

The dangling comma in a list, but only when its closing brace is on a new line, is also irritating. No, it’s not a formatting issue; gofmt won’t enforce one brace placement over the other. Rather, the presence or lack of a comma is a parsing error. We can write:

{foo,
bar,
baz}
And we can write:
{foo,
bar,
baz,
}
But we can’t write:
{foo,
bar,
baz
}
Perhaps it was because I was writing my own parser at the time that this bothered me. It should be trivial to accommodate the desired pattern, especially since structs and interface definitions are brace-delimited and don’t use commas at all.

Go elides some traditional constructs, for example for handles for, foreach, and while loops, so why make and new still exist side-by-side, even when Rob Pike proposed merging them, leaves me scratching my head. &Foo{} is equivalent to new(Foo), so if there’s no need for while then there’s no need for new.

I recognize these gripes are largely syntactic, but the syntax of a language is its API. Programmers are immersed in it every day and it can have an effect on how we think about things.

Surprisingly though, and perhaps this is my biggest complaint, the tooling around Go is still immature. In the 6+ years after its release there is still no killer IDE. Code coverage can only be generated for one package at a time, not and entire project. It’s possible to script coverage for project-wide results but that’s just a hack. Debugging with GDB is brutal and I could not get Delve to work for me.

None of these irks will stop me from using Go in the future if I have the opportunity, but I’d like to suggest Go at work as the go to language (pun intended) for some of the work we do now in C. I can probably make some good technical arguments to sway our old-time C programmers, yet convincing management and the programmers fresh out of college to use Go without viable tooling is going to be a hard sell.

Comments

  1. It actually has a happy side effect:
    http://dave.cheney.net/2014/10/04/that-trailing-comma

    ReplyDelete
    Replies
    1. In that case, yes :) But if you have the brace on the same line as the last item then it becomes a 2-line fix. Gofmt has no preference on the brace placement so there's still the possibility for style variation here.

      Delete

Post a Comment

Popular posts from this blog

Writing a Minimal PSR-0 Autoloader

An excellent overview of autoloading in PHP and the PSR-0 standard was written by Hari K T over at PHPMaster.com , and it's definitely worth the read. But maybe you don't like some of the bloated, heavier autoloader offerings provided by various PHP frameworks, or maybe you just like to roll your own solutions. Is it possible to roll your own minimal loader and still be compliant? First, let's look at what PSR-0 mandates, taken directly from the standards document on GitHub : A fully-qualified namespace and class must have the following structure \<Vendor Name>\(<Namespace>\)*<Class Name> Each namespace must have a top-level namespace ("Vendor Name"). Each namespace can have as many sub-namespaces as it wishes. Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system. Each "_" character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR . The "_" character has no special ...

What's Wrong with OOP

Proponents of Object Oriented Programming feel the paradigm yields code that is better organized, easier to understand and maintain, and reusable. They view procedural programming code as unwieldy spaghetti and embrace OO-centric design patterns as the "right way" to do things. They argue objects are easier to grasp because they model how we view the world. If the popularity of languages like Java and C# is any indication, they may be right. But after almost 20 years of OOP in the mainstream, there's still a large portion of programmers who resist it. If objects truly model the way people think of things in the real world, then why do people have a hard time understanding and working in OOP? I suspect the problem might be the focus on objects instead of actions. If I may quote from Steve Yegge's Execution in the Kingdom of Nouns : Verbs in Javaland are responsible for all the work, but as they are held in contempt by all, no Verb is ever permitted to wander about ...

Learning Prolog

I'm not quite sure exactly I was searching for, but somehow I serendipitously stumbled upon the site learnprolognow.org a few months ago. It's the home for an introductory Prolog programming course. Logic programming offers an interesting way to think about your problems; I've been doing so much procedural and object-oriented programming in the past decade that it really took effort to think at a higher level! I found the most interesting features to be definite clause grammars (DCG), and unification. Difference lists are very powerful and Prolog's DCG syntax makes it easy to work with them. Specifying a grammar such as: s(s(NP,VP)) --> np(NP,X,Y,subject), vp(VP,X,Y). np(np(DET,NBAR,PP),X,Y,_) --> det(DET,X), nbar(NBAR,X,Y), pp(PP). np(np(DET,NBAR),X,Y,_) --> det(DET,X), nbar(NBAR,X,Y). np(np(PRO),X,Y,Z) --> pro(PRO,X,Y,Z). vp(vp(V),X,Y) --> v(V,X,Y). vp(vp(V,NP),X,Y) --> v(V,X,Y), np(NP,_,_,object). nbar(nbar(JP),X,3) --> jp(JP,X). pp(pp(PREP,N...