• Request Bio 7.4k Views
As someone who gets paid to write software, Go is beautiful to me in the way that a good truck is beautiful to a construction worker. Go:makes the relatively hard problem of concurrent network programming dirt-simple allows me to produce well performing, reliable programs with relatively low memory footprints allows me to produce readable code supports all the modularity I need to make well-structured libraries and programs compiles extremely quickly to let me iterate on my work produces statically linked binaries that are easy to deploy without external dependencies and that can even be cross-compiled quite easily
Yes, generics would be nice, and yes, maybe tuples would be a nicer construct than multiple return values. But for most of the work I do, I'm not actually inventing new data and control structures, I'm just shoveling around bytes.
Clearing Up Confusion about Zero Values
The OP may have misunderstood how zero values work in Go. Go has values and pointers to values. All types of values have a zero value, including user-defined types. To wit:
v1 and v2 both refer to the zero values of their respective types, which are:
It just so happens that most uses of user-defined types actually use pointers. For example:
This function has a receiver type of *mystruct, so to use it one has to call it on a pointer to mystruct, e.g.:
Until we initialize v3 with a new mystruct, its value is nil, which makes perfect sense since it's an uninitialized pointer. The same thing is incidentally true for pointers to built-in types:
Slices are really just smart pointers to an array, and as such it makes intuitive sense to me that uninitialized slices are nil.
I don't miss Type Inference
The auto-declaration feature with := significantly reduces verbosity inside function bodies, and I actually like having type annotations in function declarations because they immediately tell me what types a function expects and returns, without having to infer them myself (or write them in a comment somewhere for consumers of my functions).
Written 79w ago • View Upvotes
More Answers Below.
Is there anyone at Valve using golang?
Why are fewer developers using Golang?
What's the history of golang's syntax?
Has Quora given any thought to using Golang?
Is Golang ready for business?• Request Bio 7.3k Views
I don't think I've ever started learning a language and didn't find some part of it ugly. I stayed away from Python for years because of the indentation-as-syntax aspect and it STILL bothers me today even though Python has been my primary language for the past 8 years.
There are definitely parts of Go that bother me, but after having used it regularly for the past 6 months, those things have faded into the background (as they usually do when you become fluent in a language) and I just see the code.
Written 82w ago • View UpvotesTikhon Jelvis , studied programming languages and did research on program synthesis
17.3k Views • Upvoted by Jelle Zijlstra , software engineerYes
My main overall impression of Go is that its design feels arbitrary : its features are just whatever the designers felt like adding, however they felt like making them. It lacks the underlying simplicity, elegance and holistic design that I really look for in a programming language.
And that's ugly.
The first place that stands out as ugly and arbitrary is error handling . They decided to forgo exceptions in favor of passing errors through return values. And that's a great decision! It simplifies the language and makes error handling less of a special case, unlike exceptions.
So, if you're going to pass errors through a function's return value, there's a very logical way to do it: a function can return either a correct result or an error. After all, if there's an error, no correct result can make sense. And if there was no error, well, there was no error.
So what does Go do? It returns both . If you had an error, the real result is garbage; if you don't have an error, it's.
And, instead of returning both as a tuple, it does it in a magical, built-in way that cannot be reused for anything else .
Zero Values and Nil
Go's error handling fracas also forced them to add two more ugly, arbitrary warts to the language: nil and, for a Java-esque set of primitive types, zero values .
Nil is just their incarnation of Tony Hoare's Billion Dollar Mistake. Because I guess we still don't know any better. Having nil everywhere is adding an extra vector for mistakes, bugs and confusion to every part of your program for very little gain. It's ugly because nil often doesn't make any sense but you still always have to worry about the possibility!
But if having nil everywhere is bad, having nil almost everywhere is even worse. It makes the language inconsistent. You have to remember that a handful of built-in "primitive" types behaves differently from everything else. More special cases! It also means that any types the programmer creates are going to be second-class citizens compared to these built-in types. This theme actually gets repeated a few times in Go's design.
But given Go's error handling—and uninitialized memory, which is ugly all on its own—we need to have some default garbage value for primitive types. So Go just arbitrarily defines "zero" values for these built-in primitive types. The problem is that there is no single natural default value for things like integers, so Go's choice of 0 is relatively arbitrary—why not 1?
Zero values are another example of Go forcing any type you define to be a second-class citizen: only built-in types can have them.
The fact that strings are primitive values and cannot be nil is also odd. If everything else, like arrays/slices, have nils, why not strings? I could see ints/floats sort of making sense because they're probably unboxed, but strings aren't. In fact, strings shouldn't be too different from arrays/slices/other collections. And yet they are, to the point of being primitive. Special cases again...
One thing that's particularly annoying about all this is that there is already a well-known, better design for return value error handling: variant types . Variant types let you express "returns either the correct value or an error" directly , without being specific to error-handling. They're a very useful feature for a lot of other things, which means you could replace Go's arbitrary error handling with something simpler, neater and more general.
Moreover, variants would let you avoid having nil everywhere by making it easy to define an option type like in Scala, OCaml, Haskell...etc. So variants would not just subsume error handling but also nils. And since an option type can be based on any underlying type, you could have int options, float options and so on, obviating the need for zero values! It would be great.
More interestingly, variants are not an arbitrary design at all. In fact, they are the dual of structs, which Go already has. That means variants and structs are symmetric in a structural sort of way . Just like in physics, I figure symmetry means you're onto something . It's also a great example of what I would consider a beautiful language feature since structs and variants go so together.
Go doesn't have type inference. And why? I really don't know. It haswhich is better than nothing, but I don't see why it couldn't have f ull type inference . OCaml has similar type system features—and more—and has no problems at all with full inference.
Go doesn't have generics. This, by itself, makes the language pretty ugly. It's not just a little thing they left out, it's a major problem.
For one, it means you can't really create your own data types. Which, you know, is kind of important. This is the biggest contributor to the pervasive second-class citizen feel of Go: you can never write something like the built in map type! What if you want a tree-based map? Or a set? Or one of the many trees that are so useful? Queues? You get the idea...
Maps magically have generics, but in a weird way that is not reusable at all. Yet another special case.
The lack of generics also forces you to cast toall over the place. This is ugly by itself but also throws away a lot of the advantages of static typing by explicitly turning otherwise static errors into runtime errors. So you get more verbose code that's also less safe. Wow.
So yeah: Go is ugly .An interesting language to contrast with Go is OCaml. Despite its wonky syntax, OCaml is actually quite nice. It has many of the same features as Go but, with the exception of concurrency stuff, does all of them much better . It has structural subtyping, no nulls, variants, efficient generics, tuples, pattern matching, full type inference... And it predates Go by 13 years
Written 81w ago • View UpvotesAnonymous 1.1k Views
There basically two things here : 1. If the language is beautiful and gracious and 2. if the language is worth using to solve a problem. I see that some people mix these two things up. While there is no question that it makes sense to use this language and that is very efficient, saying is beautiful is definitely a biased opinion of the people that find it useful and got used to it's rougher edges.
Coming from C++ and Python and just starting learning it the syntax often looks *really* strange but I would definitely use it instead of either of them when faced with a performance critical problem that requires multithreading and not enough time or patience to implement everything in C++
Written 26w ago • View UpvotesSteve Wood , Retired, and living the good live in Puerto Vallarta, Mexico 2.5k Views
As a Go newbie who has been digging into it for less than two months, I don't find it ugly. I find it different. In almost every case the differences are for a reason... i.e. not arbitrary. Developers who dig deeply enough to understand the reason for each difference are likely to adopt Go as a useful tool.
I suggest that most of the negative issues mentioned are based on resistance to anything that significantly diverges from what the writer finds familiar. Developers with that mind set are unlikely to adopt Go... and that's OK.
Written 51w ago • View UpvotesMore