10 comments

[ 2.9 ms ] story [ 34.0 ms ] thread
Most of this article reads to me like “People said Go is simple. I looked at Go. There are concepts I wasn’t familiar with and the syntax looks different and doesn’t match my taste. Go has a learning curve, it is not simple.”
Exactly. I'm curious if the author continued using Go for a bit of time, if they would still write the same article.

Some of the concepts the author took issue with, such as receiver arguments or multiple return values never felt all that unusual for me, but that's probably because I'm quite familiar with a language like Python, where these concepts are pretty common if you've ever written a class or written a function that `return a, b`

The final argument, that Go's concurrency is somehow not concurrency, or all that special is a bit too much for me. That section needs some editing, but if anything, they unintentionally make the point that Go's concurrency IS simple.

Simple language, complex programs.

Complex language, simple programs.

kindof, but not always.

C++ and C# are powerful complex languages. C and Java are simple languages. But I can find lots of elegant programs in C or Java. They don't make the programs feel complex.

Still it depends on the programmer. Programs in any language can vary drastically in readability.

Go is simpler in some cases compared to C++ or Rust, but each targets different best use cases.

I can write concurrent code accessing shared memory in ways that are easier for me that in Python, which most people would consider a simple language.

The same tasks would be harder in C/C++ or Rust for me (memory management for example), but those languages are better suited for some cases.

Simple is relative to the programmer and the task. There is not one language to solve all problems.

  One thing that really surprised me about Go — a supposedly simple language — is
  that you can even do multiple inheritance. And it’s pretty bad. Someone on the
  golang-nuts mailing list discovered, that Go doesn’t handle inheritance
  ambiguities very well. I have adapted the code mentioned therein so that it also
  showcases the well-known ‘Dreaded diamond problem’:
Effective go [1] has this to say about embedding, and if you follow the rules, the results of the demo code don't seem surprising to me - it just takes the least deep 'foo'.

  Embedding types introduces the problem of name conflicts but the rules to
  resolve them are simple. First, a field or method X hides any other item X in a
  more deeply nested part of the type.

  Second, if the same name appears at the same nesting level, it is usually an
  error; it would be erroneous to embed log.Logger if the Job struct contained
  another field or method called Logger. However, if the duplicate name is never
  mentioned in the program outside the type definition, it is OK. This
  qualification provides some protection against changes made to types embedded
  from outside; there is no problem if a field is added that conflicts with
  another field in another subtype if neither field is ever used.
Also, to me it looks more like composition over inheritance. Not sure if that's what he means by multiple inheritance. Maybe thinking about it in terms of properties finding it's way up rather than inheritance being passed down makes more sense anyway.

[1] https://golang.org/doc/effective_go.html#embedding

Unfortunately the author is confused about Go's type system.

Go does not have inheritance, single or otherwise. Embedding is not inheritance and is not equivalent to it.

Really? Sure smells like it despite all the claims its not.
Embedding is basically syntactic sugar for delegation.
Even though he says I am not criticizing the language all he does "is" criticize all it's constructs at length. SMH. The biggest selling point of Go in my opinion is the how it allows one to get off the ground quickly. I love the language among other languages.