Earlier quoted context omitted.
Go impedes its own readability by encourage or even requiring such huge volumes of code. (And Go ain't very good at concurrency. At least they should have let you mark values as immutable, or communicated entirely via copying like Erlang.) Yes, tuples are a really weird thing with Go. If they had completely left them, that would be bad but sort of defendable. But instead they give you a half-baked implementation of s…
Go is incredibly readable I find. Yes, you tend to find yourself writing a lot of code because of the lack of generics, but that is being fixed as we speak. Generics has a draft and it looks nice from a Go developers perspective. And Go let's you communicate by copying. That's what a Channel is. Pass a struct and that is copied. Pass a pointer and the pointer is copied. The thing it points to isn't copied for glaring…
I'm not sure what those glaringly obvious reasons are. In Erlang, you just send a copy of the whole struct. Not some kind of references or pointers.
See eg https://play.golang.org/p/P3qUtFenp2q
But as I am saying, if you want to send pointers (or references) over a channel, they should support marking things as immutable.
> And what would you suggest is a good alternative for returning multiple parameters. Currently this basically forces you to handle any possible errors and results in software you can very easily reason about.
Go doesn't force you to handle errors at all. The compiler will happily mix up the branches of your `if` that checks for errors, or let you get away without checking anything at all.
My suggestion would be eg algebraic data types. Especially sum-types. Or in more C inspired terms: tagged unions plus pattern matching. Or 'an enum with parameters'.
> Not sure what you mean about human reviewers needing to check errors.
In a language without any checking at all like JavaScript, human authors and reviewers have to make sure that you don't accidentally eg add a string to an int. Or otherwise, have to make sure that at least you have enough test coverage.
In Go, the compiler can yell at you when you are trying to add an int to a string.
In OCaml or Haskel or Rust (or any language with algebraic data types), the compiler can make sure that you check your errors. So in eg Haskell syntax that looks like this:
case someFunctionThatMightGoWrong(someParameter) of
Error errorDetails -> handleErrors(errorDetails)
Success someValue -> doSomethingSensible(someValue)
Crucially, `someValue` is only in scope in the branch where we match the right pattern. So you can't accidentally go on computing with that variable in the wrong branch.Does this make sense? If not, I can try to explain in some other way.