News for hackers. Stuff that matters.
Re:New in Go 1.20: wrapping multiple errors by cube2222 on Sunday December 11, 2022 @09:06AM (#33943272)
Implicit interfaces are one of the defining features of the language that make it so great, I love them. Calling them borderline insane without any supporting arguments does make me question whether you ever gave idiomatic Go a chance. What do you dislike about them?

Re error handling, I've been looking at the proposals and haven't yet seen a satisfying one.

Sure, the current error handling is a bit verbose (three lines after each erroring function call), but it's a completely irrelevant problem to me in my day to day, and I much prefer it to exceptions as it makes you think about each error and makes people wrap errors with helpful context everywhere.

In general, I like the approach of the Go team of only accepting proposals that are good and actually widely requested, as opposed to accepting "something" because "our story for this isn't great to some".

Re:New in Go 1.20: wrapping multiple errors by Smaug123 on Sunday December 11, 2022 @09:13AM (#33943342)
> I much prefer it to exceptions as it makes you think about each error and makes people wrap errors with helpful context everywhere…

This would be absolutely fine, for the reasons you state, if Go made you deal with the error. But because it will silently allow you to completely ignore the error, your statement that it "makes you think about each error" is quite optimistic. In an exceptionful language, the runtime will let you know loudly and fatally when you've got garbage; in a language with a type system that admits a Result type, the compiler will forbid compilation unless you note that you're throwing away the error (which might be a single character of syntactic sugar, it need not be verbose!). But Golang and C and friends are the languages where you silently get garbage if you forget to do the due diligence that machines are perfectly capable of doing for you, and it makes me extremely sad every time I see a bug of this nature.

Re:New in Go 1.20: wrapping multiple errors by cube2222 on Sunday December 11, 2022 @09:19AM (#33943411)
That is a fair point and it's why I use errcheck[0].

[0]: https://github.com/kisielk/errcheck

Re:New in Go 1.20: wrapping multiple errors by Smaug123 on Sunday December 11, 2022 @09:50AM (#33943648)
Magic! I just checked, and this found the bug in a Go tool I use that bit me a couple of months ago, which I'm still smarting from. Thanks!
Re:New in Go 1.20: wrapping multiple errors by cube2222 on Sunday December 11, 2022 @09:57AM (#33943708)
Glad I could help!

In general, I recommend using golangci-lint[0], which aggregates a ton of useful linters like this one.

[0]: https://github.com/golangci/golangci-lint

Re:New in Go 1.20: wrapping multiple errors by cjglo on Sunday December 11, 2022 @10:27AM (#33943949)
I don’t like Go error handling, but exceptions are terrible and not better.

Rust/Zig/Swift approach is definitely the best.

Re:New in Go 1.20: wrapping multiple errors by kaba0 on Sunday December 11, 2022 @03:44PM (#33947288)
Exceptions are much better, especially checked ones (which are analogous to Rust-style result types).
Re:New in Go 1.20: wrapping multiple errors by cjglo on Monday December 12, 2022 @11:17AM (#33956388)
Not analogous.

Rust-style result types continue the normal control flow.

Any exception thrown deep into a function can be very hard to debug. The normal line of execution is stopped, even without a return, and if it’s a checked exception it can “bubble up” to higher functions despite nothing signifying a return, just a marker saying somewhere this can throw an exception.

Exceptions are terrible.

Re:New in Go 1.20: wrapping multiple errors by kaba0 on Tuesday December 13, 2022 @05:38AM (#33966992)
This is literally the exact same thing. Exceptions are not gotos. They bubble up one method at a time, and can be handled at any level you want. Matching on a result type is literally the same thing as putting in inside a try-catch block. Putting a ? macro at the end is literally the default behavior. You can handle it on as tight/wide scope as you wish, plus you also get a must-have stacktrace — so your debugging is just looking at where the exception originated from.
Re:New in Go 1.20: wrapping multiple errors by p-e-w on Sunday December 11, 2022 @09:21AM (#33943428)
> What do you dislike about them [implicit interfaces]?

Implicitly implemented interfaces can lead to problems where you're "implementing" an interface because your methods happen to be named the same, but the functionality doesn't adhere to the contract the interface is supposed to represent. Not every contract can be described by the type system, especially not by a type system as limited as Go's.

Method names like "Write", "Get", or "Execute" are very common, yet in Go you have to be careful because suddenly you're implementing an interface that is intended for things that have nothing to do with what your code actually does.

Simply put, it's an enormous weakening of contract safety, for essentially zero benefit. After all, spelling out that your type implements a certain interface really isn't a lot of work.

Re:New in Go 1.20: wrapping multiple errors by cube2222 on Sunday December 11, 2022 @09:29AM (#33943502)
You call it an "enormous weakening of contract safety", I call it an issue I've never once had happen in practice.

Sometimes you can't spell out that your type implements a certain interface, because it's not a type controlled by you.

Moreover, this completely kills the use-case of "define your own small interface with the subset that you actually require, instead of accepting the whole thing", which is a big part of the value-add. See my other comment[0].

[0]: https://news.ycombinator.com/item?id=33943352

Re:New in Go 1.20: wrapping multiple errors by Someone on Sunday December 11, 2022 @11:14AM (#33944433)
> Sometimes you can't spell out that your type implements a certain interface, because it's not a type controlled by you.

Dynamically inferred interfaces only help there if function names and arguments happen to exactly match those of the interface. So if, for example, a method is called ‘Run’ rather than ‘Execute’, or you have ‘Run(string, int)’ and ‘Run(int, string)’ methods, that won’t work.

Some languages that require explicit interfaces (and, I think, most modern ones) allow you to specify that mapping at run time, and also allow you to retroactively make all code (including third party code) that implements FatInterface implement your SmallInterface that’s a subset of it.

Golang chooses to not require programmers to do such work and, I think, hopes programmers will keep names and argument type order identical for common methods, so that those problems occur less often. I don’t think that will work in large code bases, but then, I don’t have experience with large golang code bases.

Re:New in Go 1.20: wrapping multiple errors by masklinn on Sunday December 11, 2022 @12:09PM (#33945012)
It also leads to easily fucking up interface implementations because that's not checked, some folks actually put "interface assertions" above the interface methods to ensure they're not forgetting anything and did not screw up any signature e.g.

    var _ Iface = (*someStruct)(nil)
will fail to compile if someStruct does not correctly and fully implement Iface.