News for hackers. Stuff that matters.
Re:The Zen of Go by masklinn on Sunday February 23, 2020 @10:51AM (#22397399)
Don't forget this absolute banger:

> Obviously Go chose a different path. Go programmers believe that robust programs are composed from pieces that handle the failure cases before they handle the happy path.

A function which only returns an error can have its result ignored without any warning.

Re:The Zen of Go by tomlu on Sunday February 23, 2020 @12:41PM (#22398217)
> A function which only returns an error can have its result ignored without any warning.

It should perhaps be an error to not assign an error to a variable. Internally, Google has linters that enforce this.

Re:The Zen of Go by throwaway894345 on Sunday February 23, 2020 @11:14AM (#22397571)
I don’t think that paragraph was referencing compiler guarantees.
Re:The Zen of Go by coldtea on Sunday February 23, 2020 @12:27PM (#22398113)
It should refer to them or address them.

Since, given this, Go is no better than a language with unchecked expressions nobody handles...

Re:The Zen of Go by stouset on Sunday February 23, 2020 @01:24PM (#22398520)
There’s other reasons too! I’ve written the following:

    if v, err = func(); err != nil {
        nil, err
    }
… and then went on to use `v`. Thanks to `v`s zero value being legitimate (and not nil like a pointer would be), the program continues on as if everything is okay. In case you didn’t catch it, I forgot the `return`.

Rust takes a much better approach with Result, where the return value is either `Ok(v)` or `Err(e)`, and there’s no way to access a meaningless value for the other possibility.

Re:The Zen of Go by coldtea on Sunday February 23, 2020 @02:19PM (#22398882)
Yeah, and this is so simple a change (compiler wise) and far more stronger a guarantee I don't see why Go didn't implement it...

At least then errors as return values would be solid.

Of course now they make programmers do all the extra error wrapping thing in 1.14 to pass "richer" errors...

Re:The Zen of Go by pm90 on Sunday February 23, 2020 @03:09PM (#22399209)
Eh. It’s verbose but I like it. It makes me think about the code a bit when I have to write a descriptive error wrap. Kind of annoying I guess... I haven’t written ultra large go codebases though so ymmv.
Re:The Zen of Go by coldtea on Sunday February 23, 2020 @06:49PM (#22400423)
>It’s verbose but I like it. It makes me think about the code a bit when I have to write a descriptive error wrap.

Having the compiler force you, as is my suggestion, would make you think even more -- or not be able not to think and skip the error check or miss it.

Re:The Zen of Go by earthboundkid on Monday February 24, 2020 @10:49AM (#22405030)
Your example doesn't compile: https://play.golang.org/p/KQwXqTZHSPF

Go doesn't allow values to just be referenced without having some use, e.g., JavaScript's `"use strict";` hack could not be done.

In general, I have never seen a bug caused by accidentally ignoring an error. It's a theoretical concern, but not a real world problem.

Re:The Zen of Go by stouset on Monday February 24, 2020 @12:16PM (#22406007)
Don’t know what to tell you, I have personally made this mistake and not had this caught by the compiler. I haven’t used go in several years at this point, so it’s entirely possible this is a newly-caught scenario by the compiler.

Regardless, the fundamental point stands. Using tuples to return “meaningless” values alongside errors allows developers to mistakenly use those meaningless values.

Re:The Zen of Go by throwaway894345 on Tuesday February 25, 2020 @07:26PM (#22419079)
I do wish Go would adopt sum types, but in practice errors like you describe are vanishingly rare. It’s mostly a theoretical problem.
Re:The Zen of Go by closeparen on Sunday February 23, 2020 @02:42PM (#22399034)
Any serious Go shop would have errcheck as one of the linters in CI.
Re:The Zen of Go by masklinn on Sunday February 23, 2020 @04:39PM (#22399724)
Apparently linters are bad and that’s why go literally refuses to compile if you have unused imports. But crap like this? No problem, flies right through.
Re:The Zen of Go by Vendan on Monday February 24, 2020 @10:44AM (#22404970)
Linters aren't bad (Go basically has one as `go vet` that checks for all kinds of "this is probably wrong", like the common "closing over a loop variable")

Warnings are bad, specifically when the warning is unambiguous (importing a package you aren't using is always wrong, though it makes debugging frustrating at times) The idea is that warnings that don't "stop" the build generally get ignored. Build most non-trivial C++ projects and count how many warnings flow past the top of your screen for an example of what they were trying to prevent.

Re:The Zen of Go by earthboundkid on Monday February 24, 2020 @10:54AM (#22405091)
What drives people crazy about Go is the laser-like focus of the designers on real world problems over theoretical problems.

Theoretical problem: Someone might mutate a variable intend to be constant.

Go designers: Then put a comment saying not to do that.

Real problem: People ignore compiler warnings.

Go designers: Then eliminate warnings.

Real problem: Exceptions can happen anywhere and often go unchecked.

Go designers: Then call exceptions "panics" and encourage people not to use them.

Theoretical problem: Someone might ignore an error return value.

Go designers: Let paranoid people write linters.

Etc. etc.

Re:The Zen of Go by masklinn on Monday February 24, 2020 @01:26PM (#22406785)
Yes, laser focus on real-world problems like unused variables (don't matter) or unused imports (matter even less).

> Theoretical problem: Someone might mutate a variable intend to be constant.

> Go designers: Then put a comment saying not to do that.

One can only wonder why they even bothered writing a compiler when comments can solve it all.

> Real problem: Exceptions can happen anywhere and often go unchecked.

> Go designers: Then call exceptions "panics" and encourage people not to use them.

> Theoretical problem: Someone might ignore an error return value.

> Go designers: Let paranoid people write linters.

Because that way it's even easier to ignore than exceptions, and that's… good apparently?

Also create `append` where not using the return value just right (with no help from the compiler but that's OK because comments are where it's at) doesn't just create a bug in your program it can create two or more, what relentlessly efficient focus on real-world problems.

Re:The Zen of Go by stouset on Monday February 24, 2020 @12:23PM (#22406069)
I can emphatically confirm that this is not what annoys me about go, and what does annoy me are the real-world issues I ran into it through multiple pieces of production software developed with multiple teams of skill levels ranging from intern to senior.
Re:The Zen of Go by earthboundkid on Monday February 24, 2020 @09:51PM (#22410539)
Can you link to a write up? I’d like to read what went wrong.
Re:The Zen of Go by stouset on Monday February 24, 2020 @10:55PM (#22410790)
It’s been at least three years so it’s difficult to do a real write-up. In a lot of ways it was death by a thousand cuts. But some things off the top of my head:

Having to rewrite or copy/paste data structures for different types, given the lack of generics. As I understand it, even Google now has tools that generate go source from “generic” templates. This is absurd.

Defer to free resources (e.g., closing files) is a terrible construct because it requires you to remember to do this. You have lambdas! Use them so that the APIs can automatically free resources for you, like Ruby and Rust. It’s insanely hard to debug these kinds of issues because you run out of file descriptors and now you have to audit every open to ensure matching closes.

Casting to interface{}. The type system is so anemic that you have to resort to switching over this, and now you lose type safety. Combine this with the compiler not caring about exhaustive switch statements. And combine this with interfaces being implemented implicitly, and it’s a mine field for bugs.

I literally had a go maintainer waffle on adding support to calculate SSH key fingerprints because “users can just read the RFC and do it themselves if needed”. This is an indefensible perspective on software development.

Despite “making concurrency easy”, having to implement concurrency patterns by hand for your different use-cases is nuts. I have lots of feelings here, most are summed up by https://gist.github.com/kachayev/21e7fe149bc5ae0bd878

Tulpe returns feel like they were bolted on to the language. If I want to write a function that does nothing more than double the return value of a function that might error (insert your own trivial manipulation here), I have to pull out the boilerplate error handling stanza when all I want to do is pass errors up the stack.

This is the 5% that I remembered off the top of my head years later. All in all, the design of go as a “simple” language just means that my code has to be more complex.

Re:The Zen of Go by Vendan on Monday February 24, 2020 @11:05AM (#22405232)
Interestingly, the one time I introduced someone to Go without really "realizing" it (during a coding interview, got to pick the language I used), his first comment was actually that he liked how explict the error return was. (strconv.Atoi, to be specific). That pretty much sums it all up to me: `if err != nil` seems like annoying boilerplate, but then when you see stuff that's not just doing `return err` inside that conditional, you realize that it can actually be a benefit.