Now, not everything else has been all good (mostly minor issues with community libs), but the one thing that never ceases to amaze me with go is that: You hammer out a few hundred lines of code, compile, fix those few syntax errors, compile again and 9 out of 10 times your code just works. The simplicity of the language is the key. It's a tool that feels right and gets the damn job done.
This is why I find it unbelieveable when Go users tell me "I never need generics". I look at their code and see
if err = logit(FrobulatingMessage); err != nil {
return err
}
repeated over and over again and can't help it but cringeAlso, the "I never need generics" made me smile. Sure, one can get by without them, but sometimes, as I said above, it would be really nice to have them.
I found it hard coming from a world where IDE support was available in other languages that do autocompletion and things like that and development just moves faster. In go, there is some level of support in sublime text, go for vim etc, but it is not nearly as full featured as say, IntelliJ. Want to learn about the javadoc - Command + J. Want to refactor code, much easier than in go. So tooling is a big problem I encountered.
Next in line is lack of reusable data structures. Sure, embedding of structs is supported, but lets see...what will you do with a person struct (name, age, gender) that should be part of a employee struct and also the executive struct. You have 2 options 1) copy paste the person struct fields into each of the other structs or 2) you have interfaces and implementations of those interfaces so you can only deal with it through interfaces using embedded structs. What we really want is a flattened struct (just like inheritance). Most time people use inheritance not because its the right thing to do for that piece of functionality, but because it allows easily flattening out a data structure so you have reuse of a common data structure with common properties across other data structures. This one killed it for me with go. I can't reuse. I am not google to have loads of dollars and when I try to make things work, I need to be able to keep an eye out for bugs that can creep in with go where re-use is artificial or takes excessive work to get.
All in all, maybe go has its niche, but for a small shop that runs on scanty resources and needs to build robust and reliable applications, a heavy weight like Java or .Net is still ruling the roost.
Being able to fire up a fully formed, non-handicapped environment consisting of only vim and some command line tools is great. I've tried repeatedly on the JVM to accomplish this and always end up back with bloated IntelliJ and the vim plugin as my only option.
I would say that in the last 15 years I've used inheritance correctly a handful of times, embedded structs are nearly always the correct solution to data structure reuse problems. That Go prioritizes composition over inheritance for data structure reuse is one of its fundamental value propositions, that anyone that has used Java extensively thinks otherwise is baffling to me.
If Go had a longer history I'd probably argue the exact opposite conclusion of you. If you are a small shop with scanty resources and need to build practical business solutions Go seems like a great choice. Conversely, if you are able to afford the best developers and have massive enterprise software needs, maybe Java or .Net makes more sense.
Bloated it may be but helps me get the job done faster...much faster than I can do it in vim. I work on a mac with 16 GB RAM and thats sufficient for lots of processes. Every bit of the way, I have documentation I can lookup right within as I type, I have autocomplete that always works, I have debugger support to catch little things I missed, tons of libraries and plugins that have stabilized over the years...whats not to like? The downsides (and the reason I looked at go) are both Java and .Net are memory hogs. I needed something more lighter that would offer the same level of productivity during development.
That's what we call struct embedding. Check this http://talks.golang.org/2014/go4java.slide#33 for more details.
This is not to say inheritance is better. I am just illustrating how reuse is harder with go because it expects a lot more code to do a simple thing.
I'd note that all the replies at this time argue the point about data structures, but none address the tooling.
I want my autocompletetion, dammit! And I don't want to use Emacs or Vi to get it.
The lack of refactoring support was what ended up making me switch back to Java+Dropwizard. I'm just much quicker at evolving services because of the better tooling.
That seems to be the opposite usual scenario for "heavyweight" enterprise frameworks.
I actually think Go hits the sweetspot - faster to develop in than Java/.NET, but much more robust, reliable and faster than the scripting languages.
This is not to say go is bad at all. Its been designed by people 1000x smarter than me. But it isn't helping small shops go any faster or be more productive than they are with current setup. Talk about progress of the 21st century programming language...can't find much.
I don't know about you but I'd rather work with people that understand the tools they are using and when it's OK to do fun stuff and when it is important to exercise restraint and "dumb it down" for the good of the team. Using the language to solve the problem of uneven programmer ability feels a bit off. It's something out of 1984. You can't say "great" in Go you can only say "good++".
If we understand the domain and understand what we are building then we can afford to be innovative on the technology. If we are trying to be innovative in what we are building then we need to choose proven (aka boring) technology.
Visually: http://www.adlinktech.com/solution/img/20131121-1.jpg
New domain => use known technology.
Known domain => play with new technology.
In my experience really good developers don't see it like that, they see it more like the Brian Kernighan quote:
"Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?"
It isn't that they are worried that "lesser" programmers will make a mess using "clever" code, but rather they are worried how long it will take them to debug their own "clever" code, or just decipher such code they produced themselves in the future after they haven't looked at it in 6 months.
Or, less anecdotally, I maintain about twelve services in Go, including web services, proxies, and an analytics engine, and I have never been woken up in the middle of the night with a failure. That was certainly not true when I was writing Python or Javascript. Erlang or Swift might offer comparable reliability, but it comes at the cost of a lot of complexity.
Of course for toy or small services, go is fine. Erlang certainly could use the "build a binary run it anywhere" distribution model of Go tool.
But reading all these pro-go articles, it strikes me that none of them seem to be written by people who really understand concurrency.
Believe me, I wish Go was written by people who had understood erlang. There's a lot to like about it and it has momentum.
Look at the examples on the page. Would you really rather see the Go one at 3AM? It's twice as long, and the superficial similarity of each if(err...) stanza obscures the important differences. On a large codebase that adds up. Maybe the "complexity" meant the Swift took longer to write (though I'd dispute that too) - but if it's more readable and more maintainable, that's a positive tradeoff.
Also, your "less anecdotally" is by definition pretty anecdotal.
It could also be that he realizes that he is a PL snob/geek, and that makes him more likely to pick up and learn weirder/'more powerful' languages/paradigms. Other programmers (arguably most programmers) aren't PL geeks, not for a lack of ability, but for a lack of interest. Choosing to use more advanced languages may be great for him, but may just cramp the style of other people that aren't PL geeks.
This belies a multitude of real problems Go doesn't solve, like generics or preventing data races
This should be evidenced by the fact that Go is the only mainstream statically typed language without parametric polymorphism. Worse, trying to bolt it on after the fact has generally lead to ugly solutions, like C++ templates or Java's generics.
I expect Go will eventually follow Java's lead and bolt on generics awkwardly.
You don't need anything beyond assembly language, really.
The thing with most tools and abstractions is that you don't appreciate them until you use them -- when you truly use them, not merely when you learn about them. Then you wonder how you ever lived without them. You don't know if failing to use an abstraction hasn't cost you a significant amount of time until you've embraced their use.
To me, this is a variant of the Blub paradox at work.
Wikipedia has a nice description:
https://en.wikipedia.org/wiki/Go_(programming_language)#Race...
What is with you? The article is talking about languages, not the category of problems people are trying to solve using those languages. (In principle, NASA could have written the Mars rover code in brainfuck).
> enterprise features like exceptions and generics
What is an "enterprise feature"? Sounds like a Java-world word though.
I also don't understand how generics and exceptions "ensure consistency across the platform".
"Go feels under-engineered because it only solves real problems" "and so you build real solutions rather than finding excuses to use your beautiful tools"
The implication from reading the article is that those of us that rely on those so called exotic features aren't doing so for serious business and technical reasons. And it seems to be a common thread amongst many Go users.
And generics allow you to reuse existing components much cleaner and exceptions allow you to handle errors in a consistent way across the system. You can build error handling classes but often handling errors explicitly doesn't scale.
I think what the grandparent poster meant to say was:
>Working in the enterprise, features like exceptions and generics make it easier [...]
There are plenty of go fanboys out there who will rage about go getting any kind of criticism, but this was a really thoughtful take on why go is a good practical language despite the problems.
It's fine to say for economic or organizational reasons you're not moving to Go, but don't say it's because you need exceptions or generics unless you've spent a serious amount of time trying it the other way.
I'm getting interested in Nimrod (or Nim as I think it's planning to become). Compiles to native binaries via C, C++ or ObjectiveC. Even compiles to JavaScript. So it will run on all consumer and server platforms, on microcontrollers and in browser.
And it has generics, exceptions, macros, inheritance, and (optional, time-boxed) garbage-collection.
It's a tiny community which hasn't even managed to get a Wikipedia page to stay up, but I'm barracking for it.
And? iOS and Android supports are on their way in case you're not following recent developments. In case you're interested in writing programs for mobile devices, there's already a supporting go.mobile repository with (mainly targeting Android at the moment).
> And it has generics, exceptions, macros, inheritance, and (optional, time-boxed) garbage-collection.
Sigh... this "where's my feature!" argument almost always comes up.
It is not reasonable to expect that feature X that is very important to you has to carry the same weight for other people.
Some people think that it is unthinkable to write programs without feature X. If you think that way, then Go is probably not a language for you. Note however that there are many people who do not think that absence of feature X is a crippling thing, and do enjoy writing programs in Go.
> It's a tiny community [...]
in total contrast with... Nimrod community?
I'll make it simple. Nimrod has one feature - only ONE - which differentiates it from Go. It's not generics, it's not inheritance, it's not proper error handling (cos they're all just fancy features which nobody really needs, right?), it's not even optional garbage collection (although that's a part of it, Go is not suitable for constrained real time applications because of its opinionated lack of optionality in this space).
It's REACH.
You know, the thing that has made JavaScript the most widely used language on the planet - and nobody's claiming THAT's got the greatest feature set.
> iOS and Android supports are on their way in case you're not following recent developments.
Yes I am, and the closest I came up with was this:
https://bitbucket.org/minux/goios/wiki/Home
Seriously? I mean, have you tried this? Have you even tried to make sense of the build instructions?
If you have the inside line on some secret Google plans for Go then good on you. But if you're going to make public claims like this - in a forum where people might be interested to hear about tools that help them DO cross-platform development rather than just dream about doing it one day - you should be prepared to back them up.
Challenge: you implement a cross platform library in Go, I'll do one in Nimrod, we'll upload working XCode and Android projects that use our shared library and that compile to App Store / Play Store eligible apps to Github. I'm up for it - are you?
> in total contrast with... Nimrod community?
He _was_ referring to the Nimrod community here.
Yes, but it remains to be seen how Go's view on data structures map Objective-C and Java APIs.
As for Android support, the Android team doesn't seem to care any little bit about it, given their statements on Google IO.
So you have developers of a Google language trying to target a Google platform, where the platform owners just want to support Java (NDK is a kind of stepchild).
Well, you can if you MUST: https://bitbucket.org/minux/goios/wiki/Home
> Or your Swift to Linux.
I suspect that'll be a different story next year.
A function named "frobulate" - what is frobulate? I dunno. The function calls: thingsToFrobulate, logit, cleanupOldest, processOld, doNewThing, cleanup and somehow FrobulatingMessage is set on the way.
Honestly; you can do the most clever functional programming in the world but if you naming is like this then your code is just going to be bananas.
And BTW: both Swift and Go are missing exceptions; I think those would be very helpful here.
- Type system needs to be improved e.g. generic code
- Verbosity, duplication of code are painful
- Lack of functional features
- Tooling
- Maturity
I haven't had an issue with code duplication at all. If you do, you might just not have gotten deep enough into how interfaces work yet.
When you use the standard library it's clear it was designed by people who have been programming computers since the Plan 9 days, I consider it much more mature than Python's equivalents.
In terms of tooling, having go fmt run on every save is wonderful, your code is always and instantly formatted perfectly. Beyond that, I haven't needed much.
For me, the biggest pain point is, to be honest, dealing with json. json in Go is not as fast as you would expect, due to the overhead of runtime reflection. Parsing "loose/dirty" json is also painful. If you cant be sure ahead of time if a value is `"1"` or `1` (int or string of int), and have to support both, you are going to have a bad time.
> If you cant be sure ahead of time if a value is `"1"` or
> `1` (int or string of int)
...then your data provider is _broken_ and you need to take it up with them :)I personally struggled with the json parsing issue a fair bit, but persevering resulted in me having a mostly static typed setup which has ended up being much better than when I've used JS or Python.
Why? Go types (without generics) are much stronger than in Python aren't they?
In python, every function is as generic as it can be.
For me, that means every time I attempt to write code in Go my nose is rubbed in the "this language was built by assholes who have no respect for you".
I guess it does take some of the aesthetic or artistic quality out of it, but in practice it's never bothered me. On the contrary, not having the option removes quite a bit of mental overhead on what (to me) comes down to a fairly religious but ultimately inconsequential viewpoint.