Thursday, December 2, 2010

Should I stay or should I Go?

The last couple of months I've been playing around with Go. I got curious about the language because it had lightweight threads and message passing concurrency. Since the project (MUSQ) I'm working on with a friend wasn't really working out for the both of us, we decided to change direction. For both of us it meant changing languages. Randy switched to completely doing the front-end in Javascript and HTML5 with the Canvas tag. I rewrote the back-end in Go to get a feel for the language.

We're now 3 months in working with the new project. My thoughts on Go so far, I'll start with the negative points:
  • Sometimes there's code bloat. Especially when working with side-effects and you have to catch/prepare for errors, you write a lot of "if err != nil { return bla, err }". After a while the source gets crowded with it and it gets a bit harder to read. Maybe I'm doing something wrong, but for now I can't really see another way to do it. (without using up more resources)
Hmm. That's it. Can't seem to think of anything else that _really_ bugs me.
    Things I need to get used to some more:
    • No real OO. Sometimes Object Orientation is really the right way to go, and since I do a lot of it at work, it has shaped the way I think about certain things. This is not a problem, it's merely something I need to work on. The interfaces in Go are very powerful and can solve stuff quite elegantly.
    • No debugger. Ok I admit it, I'm spoiled working in VS.NET at work and using Erlang's tools. So for now in Go, it's debug print statements. It's not a big deal. If anything, it makes you think harder about what you wrote. But it slows the debugging process a bit. 
    • Pointers. This is the first language I _really_ use with pointers. You can't do pointer arithmetic so you can't do the really ugly stuff, but still, they trip me up sometimes.
    • Mutable state everywhere, especially when using pointers. Of course, it's no different at work, but compared to Erlang,... it will need more discipline from me to write clean code.
    • No generics. But how often do I actually use that anyway? Go has a lot of built-in stuff (copy, append) that takes care of 90% of the situations where I would use them. Besides, I don't think the question is "Will Go get generics?", I think it's: "When will Go get generics?".
    The good stuff:
    • First class functions, closures, feels like a functional language! (no, really)
    • Message passing concurrency. I have to say, I like the way Go does this. Channels you can pass around, limit their reading/writing depending on the situation. Very nice. Makes for very clean code.
    • The library is awesome. I only need 1 external library (for Redis) but I'm writing my own version of that and I like it better.
    • Very high productivity. I'm amazed at how fast I can sometimes write code that works.
    • Easy to refactor. What a joy this is in Go. I've encountered situations where it would take me an hour to refactor properly in C#, but it only took 10 minutes in Go.
    • It's so simple. Go fits entirely in my head. This is really important to me. I'm pretty good at Erlang, but I doubt I know the entire language, let alone C#, I don't know half of it probably. In Go, there's no obscure language feature I haven't heard of, reading other people's code is very easy. This is of course because the language is so young, but still, it's very nice.
    • I understand the stuff in the mailing list. Yeah, go ahead, laugh. But for me, this is really nice. I can keep up with the language development and not feel completely overwhelmed by the academic stuff. Good for my self esteem! :-)
    • It gives me a feeling of being 'closer to the metal'. Closer in the sense of: I've never been this close before. All the previous languages I tried are very high level. Go forces me to think a bit differently about problems.
    Go also made me think about functional programming. It's a bit strange to use languages that have no mutable state when the machine that runs it is inherently about mutable state. Ok, a functional language will hide that from you, so you can focus on writing good code. I appreciate the value in this, but it comes at a cost. Either the performance will go down, or you have to be really great with the FP stuff so you can use Haskell properly.

    In any case, as with every new language I learn, after a while, Erlang starts calling out to me. So I've decided to port the current state of my project to Erlang to compare the two. The one I like best stays. So far, Go has the advantage, but that's because my Erlang is rusty ;-)