Hacker News new | past | comments | ask | show | jobs | submit login

No matter how smart you are (or think you are), or how much state you can store in your head at once, if you remove some of the mental overhead of a language, then you have more time to think about other things.

So you use a language that makes specifying ownership (and immutability hard)? I always feel Go adds a lot of mental overhead.

E.g., if you have a method that returns, say, a float32 slice. 1. If I return a slice of an array/slice that is a struct member, the caller could modify elements in the slice, breaking struct invariants. 2. Returning a copy of the slice is safe, but adds a lot of overhead. What you'd actually want is to return an immutable slice, but Go does not provide any facilities to do so (apart from wrapping a slice, but the lack of generics and operator overloading makes this tedious).

I guess a lot of Go code will just assume that returned pointers/slices/maps will not be used in a way that breaks invariants. But you usually end up reading the source code of 3rd party packages to see what is safe, whereas in other languages you could just read the method signature.

tl;dr: I think ownership and preserving invariants usually give the most mental overhead and Go does zero in that department.




I agree that mutability constraints are a major weakness of Go. Interestingly, they did make string immutable and added []byte as a mutable alternative. It's unfortunate that string and []byte are so similar and yet it's impossible to treat a []byte as a string without copying (with the exception of looping over runes). This leads to massive code duplication and/or lack of functionality (byteconv where are you??). Just look at the strings, strconv and bytes packages. This whole area of the language is messy.

The funny thing about Go is that it makes up for its long list of weaknesses with essentially one single strength. You can actually read other people's code without much introduction to the concepts used in that codebase, because the number of possible meanings of any particular expression is much smaller than in other languages.

There is so much talk about Go being for dumb, second rate, corporate developers, because that's what Pike essentially said at one point (perhaps without thinking first).

But in fact, it's not the developers who are dumb. It's the process by which large corporations employ and dispose of developers. They are thrown into some project and expected to "hit the ground running". There's no time for explanation. So what they do is read code to acquaint themselves with the codebase and hopefully become productive before they move on to the next job. And that is the one task where Go really shines. Reading arbitrary pieces of code.

Of course powerful abstraction features eventually make reading code easier as well, but only after having learned the abstractions created for that particular problem and codebase and only if those abstractions are very carefully crafted.

Powerful language features help writers of code long before they help readers. And that, I believe, is essentially the dirty secret that Go exploits.

We all want to be brilliant writers of code when in fact we are often readers poking helplessly at half understood code to make something happen. We even forget our own abstractions once we haven't looked at them for a couple of months or even weeks.

The problem with Go is that it not only acknowledges this state of affairs, it also enshrines it.


There's no time for explanation. So what they do is read code to acquaint themselves with the codebase and hopefully become productive before they move on to the next job. And that is the one task where Go really shines. Reading arbitrary pieces of code.

Definitely. This really shines in the standard library, it consists of extremely readable code and is a good way to get up to speed on canonical Go.

We all want to be brilliant writers of code when in fact we are often readers poking helplessly at half understood code to make something happen. We even forget our own abstractions once we haven't looked at them for a couple of months or even weeks.

Definitely, but what are we comparing to? I would agree that e.g. C++ and Haskell have this property. Unless you understand the language and commonly-used abstractions, template-heavy C++ code is difficult to read. However, there are many languages that have more powerful type systems than Go, but where code is still easy to read (ML, Object Pascal, Oberon, Ada, etc.).


I'm comparing to other widely used languges like C++, C#, Swift, Scala, Java or Python. I don't think any of them allow as few possible meanings of any given language expression as Go does. And I don't think any of them requires as little non-local information to find all code that gets called by any particular expression (perhaps with the important exception of Go's structural interfaces).

I wonder whether it is simply a theoretical tautology that the more abstraction features you have in a language, the more different possible meanings any particular syntactical expression can have, and the more effort it requires to figure out its true meaning, assuming you're not familiar with the codebase.

Or is that a false dichotomy? I am unfortunately not familiar with Ada or Oberon and Pascal is but a faint memory.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: