News for hackers. Stuff that matters.
Re:An Open Letter to the Go Team About Try by ngngngng on Tuesday July 02, 2019 @07:29PM (#20340310)
Bill helped me with my resume once in the Go slack channel. Great guy. I also happen to agree wholeheartedly that introducing try would be disastrous to the mostly consistent codebases Go is currently able to painlessly produce.

Personally I don't want error handling changed at all. It's very repetitive in it's current state, but clearer than in any other language I've used.

Re:An Open Letter to the Go Team About Try by asdkhadsj on Tuesday July 02, 2019 @08:06PM (#20340521)
Eh, I feel like Go errors are a mess, personally. Though, I'm not sure how to solve them. Mind you, this is after ~5 years of use, so it's not from "an outsider" - I hope, at least lol.

Most of blame for the mess is that the error interface throws away meaningful information. Then the caller is left mentally checking how to handle the error. Do I value check? Type cast? String check? Does the library expose a function to check, or do I do it myself? Can I get stack traces in some cases without introducing a production cost?

I'm not sure if Go needs a different type of error interface (ie diff methods), or if it needs Generics to solve this properly in my view. But, I just know I've hated the experience.

After I switched to Rust it all felt so familiar, and yet so different. I believe Rust and Go share error patterns. Yet in Rust I'm never left wondering what an error is, what I should do with it, how I check for specific types. This is largely due to awesome enum support and of course generics. Does Go need this feature set to "fix" my complaints with errors? Probably not.. but I do think it needs something.

Though I will agree, I don't think the `if err != nil` is fundamentally the problem with Go's errors, at all. Sure, the UX could be improved, but that's another story all together imo.

Re:An Open Letter to the Go Team About Try by praseodym on Wednesday July 03, 2019 @04:01AM (#20342489)
There is an ‘error inspection’ proposal for Go 2.0 which will hopefully solve this issue: https://go.googlesource.com/proposal/+/master/design/go2draf...

The proposal has been partially accepted and implemented in Go 1.13: https://github.com/golang/go/issues/29934#issuecomment-48968...

Re:An Open Letter to the Go Team About Try by hermitdev on Tuesday July 02, 2019 @08:46PM (#20340707)
Honest question as a non Go user: how would generics (from a C# perspective) help? I assume that Go generics would be analogous those in C#.

Edit: spelling, genetics to generics.

Re:An Open Letter to the Go Team About Try by Nullabillity on Tuesday July 02, 2019 @09:58PM (#20340962)
Rust has a wrapper type `Result<ReturnType, ErrorType>`[0] that essentially works the same was as Go's `return value, err` idiom, but is safer because the type is defined so that you can't access the returned value unless you also handle the error condition, and it can have a convenience syntax for chaining since it is a dedicated unambiguous type. The compiler also specifically warns you about unused `Result`s, to avoid unhandled errors, and the API is structured so that nonsensical states such as `(nil, nil)` or `(value (!= nil), error (!= nil))` are impossible (unless specifically opted into).

Without generics you would have to either throw away the type information, reimplement a `Result` type for every value type, or copy/paste the implementation at each usage site (the common Go pattern).

Go's support for multiple returns itself is also a hack around the lack of support for tuples (which would be trivial to implement if you had generics).

[0]: https://doc.rust-lang.org/std/result/enum.Result.html

Re:An Open Letter to the Go Team About Try by Cthulhu_ on Thursday July 04, 2019 @07:36AM (#20353632)
That reminds me of Scala's `Either` type, which I'm sure is also present in other languages (and more functional circles which I'm not familiar with at all).

I think the important part there - and the contrast with e.g. exceptions - is that an error is treated as normal, as one possible outcome of calling a method, instead of exceptional as exception-based languages seem to be. I mean yeah of course a file can not be available to open, that can be expected. (That is the simple use case of course, I'm sure there's much more complicated situations).

Re:An Open Letter to the Go Team About Try by mappu on Wednesday July 03, 2019 @02:23AM (#20342076)
> a hack around the lack of support for tuples (which would be trivial to implement if you had generics)

To a first approximation, the purpose of Go is to stop every codebase from reinventing its own tuples or Result<> type.

Go does have generics, the Go compiler could add a chaining syntax for trailing err interfaces (like rust ? / try!) without needing to allow user-defined generic types.

Re:An Open Letter to the Go Team About Try by asdkhadsj on Wednesday July 03, 2019 @08:22AM (#20343631)
> To a first approximation, the purpose of Go is to stop every codebase from reinventing its own tuples or Result<> type.

Rust has this too. You can throw away type information and incur a runtime cost just like with Rust by using "Trait Objects", which are Rusts version of interfaces, basically. Luckily most choose not to use this for error communication.

However I struggle to understand that throwing type information away and incurring runtime cost is the pinnacle of error communication.

Furthermore, the idea that this somehow prevents codebases from "reinventing" anything is absolute nonsense. Basically every Go lib out there has different error handling. Hell, I wrote a library of my own (similar to pkg/errors). The very items I listed in my OP showed how every lib has it. You have no idea how each Go lib reinvented the wheel to know how you handle their errors. All with runtime checking. Madness.

Re:An Open Letter to the Go Team About Try by mrgriffin on Wednesday July 03, 2019 @02:53AM (#20342182)
I hope it's not literally to prevent people reinventing these simple data structures.

The ecosystem exerts a lot of pressure on developers to not reinvent fundamental things, in Haskell I practically never reach for a StrictTuple or StrictEither even when I'd like strictness specifically because they are clunkier and less well integrated with other libraries.

Scala is the only language that comes to mind with this issue (scalaz vs Cats) and my impression is that even they have mostly converged.

I would say Go has much stronger idioms than either of these languages, and wouldn't need to be afraid of people inventing their own fundamental types provided they're included in the standard library.

Re:An Open Letter to the Go Team About Try by majewsky on Wednesday July 03, 2019 @04:21AM (#20342571)
> Scala is the only language that comes to mind with [the issue of needlessly reinvented fundamentals]

C/C++ is another example. There are a plethora of string types mostly tied to which base set of libraries you're using. If you're using the C++ stdlib, you have std::string. But if you're using Qt, you're using QByteArray and QString instead. And probably similar for GLib/GTK.

(Does std::string even have any encoding support yet? When I last used it, it was just a string of bytes without any encoding awareness.)

Re:An Open Letter to the Go Team About Try by apta on Tuesday July 02, 2019 @11:14PM (#20341307)
> so it's not from "an outsider" - I hope, at least lol.

I used golang at an employer and you're right, it's a huge mess (and error handling is just one part of it).

Re:An Open Letter to the Go Team About Try by asdkhadsj on Wednesday July 03, 2019 @08:26AM (#20343648)
It's a shame too. The language is actually quite nice. They made a lot of decisions that simplify and improve code quality, large code bases, etc.

However a few decisions are huge signals that they didn't really think through them. Error handling and the now-solved package management are two big ones.

Re:An Open Letter to the Go Team About Try by apta on Wednesday July 03, 2019 @09:42AM (#20344179)
> They made a lot of decisions that simplify and improve code quality, large code bases, etc.

I keep seeing those claims (e.g. "programming in the large"), but in my experience, practically all the decisions in the language make it more awkward and difficult, even unnecessarily so, to deal with large code bases.

golang's interfaces for instance, are optimized for a small use case, at the expense of them being useless for actually useful things, like tagging and fast code search. The way "methods" are assigned to structs is overly verbose, and makes it easy to have to jump around even several files to figure out all functions that are tied to a struct. The list is too large to list here.

Re:An Open Letter to the Go Team About Try by asdkhadsj on Wednesday July 03, 2019 @12:13PM (#20345651)
So, in the large codebases I've been a part of I think Go makes it easier.. BUT, it's an asterisk "easier*". The asterisk being I think it's easier to reason about Go projects, large and small, in a "local sense" only. That is to say, I think you can wander around Go code with less context on the whole project and have a better idea on what that tiny piece of code is doing.

Compared to my Rust code bases, I feel like you need a larger picture of the project to understand what smaller code pieces do.

Is that a good thing though? Not sure, honestly. Should I really feel I understand what a function does, without understanding the functions role on the project itself? How can I truly understand a function without understanding its role?

Go feels like it's easier to understand the implementation, but not the context/purpose. Arguably, this may not be good.

I still prefer Rust, fwiw.

Re:An Open Letter to the Go Team About Try by apta on Wednesday July 03, 2019 @01:47PM (#20346660)
> That is to say, I think you can wander around Go code with less context on the whole project and have a better idea on what that tiny piece of code is doing.

Again, what specifically about golang that makes it that way, other than errors vs. exceptions (keeping in mind that any line in golang can panic)? And what's preventing you from writing similar code in another language? I used Scala before and we had Option and Result types, and treated exceptions as panics. The same applies to Rust.

I found that because of golang's verbosity, it actually made it harder to understand what the entire project was doing. e.g. code bases I worked with were littered with one off functions that amounted to what basically was a map or map+filter, where this would have been a one liner in any modern language, including Java, C#, Kotlin, etc.

Basically, I'm agreeing with the rest of your comment. I find that a "denser" language (to a certain extent) allows you to understand the overall project quicker. There's probably a sweet spot somewhere, and I feel that languages like Java and C# are quite close to it. Keeping in mind that you want a high level overview of a project when you start off anyway, there's no magic solution that will give you that.

It's just that I keep seeing the same claims repeated so many times, and it really seems that they're just being repeated without any basis at all, and repeated just because what the golang author's claimed. So far, almost everything I've seen has been hype.

Re:An Open Letter to the Go Team About Try by pixelrevision on Tuesday July 02, 2019 @09:41PM (#20340896)
I really think how you are using the language had a large effect on how you are going to view all this. If you are building a commandline utility then the way go deals with errors is great you just panic and send back a message. If you are building a long running web service you want a whole lot more info to go into your logs for when things go wrong. I dunno what the solution is but try/catch doesn’t seem to be the right thing to focus on.
Re:An Open Letter to the Go Team About Try by eloff on Tuesday July 02, 2019 @11:09PM (#20341294)
Despite the name, there's really nothing in common with try/catch. It's just sugar for if err != nil { return }.
Re:An Open Letter to the Go Team About Try by pfarnsworth on Wednesday July 03, 2019 @02:09AM (#20342015)
Try is a terrible choice for a name exactly because of try/catch, I don't know why they decided on that.
Re:An Open Letter to the Go Team About Try by qtplatypus on Tuesday July 02, 2019 @09:18PM (#20340812)
Personally I find that go’s error handeling adds a lot of noise that hides what the code is doing. Basically you have to mentally filter out a whole lot of the “if err == nil” before you can work out that bit of code’s functionality.

Also computing is all about eliminating or automating repeaditve tasks. having to write out (almost) the same code after almost every function call goes against the core usefulness of computing.

Re:An Open Letter to the Go Team About Try by cpuguy83 on Tuesday July 02, 2019 @09:28PM (#20340847)
How you handle errors is just as important (if more more) as the rest of the code.
Re:An Open Letter to the Go Team About Try by codr7 on Wednesday July 03, 2019 @12:10AM (#20341526)
There's a difference between handling and propagating errors, most Go-code I've come across/written is pretty much using exceptions, but with 10x the noise and none of the convenience. Which might be fine, different languages have different goals; maybe simplicity is more important. But pretending it's somehow superior isn't fooling anyone.
Re:An Open Letter to the Go Team About Try by cpuguy83 on Wednesday July 03, 2019 @03:20PM (#20347701)
An exception interrupts the entire flow of the program.

In go if something is truly exceptional then you can panic, but most of the time an error is non-fatal outside of a particular request (request not just related to a web request).

I agree, many people do errors incorrectly, but `try` does not make them suddenly correct either.

It's quite healthy for the community to have this discussion because this is introducing not just a new built-in function/expressiony thing, but also a means of flow control.

Re:An Open Letter to the Go Team About Try by codr7 on Wednesday July 03, 2019 @05:43PM (#20349146)
Unconditionally returning on errors all the way has exactly the same effect. Arguing that it's wrong isn't very constructive given that everyone seems to be doing it.

panic() is just another symptom of the same disease.

Exceptions are a very useful tool, and so is pattern matching and support for multiple returns. There is no one true way to handle errors.

Re:An Open Letter to the Go Team About Try by cpuguy83 on Wednesday July 03, 2019 @06:52PM (#20349737)
> Unconditionally returning on errors all the way has exactly the same effect.

No, an uncaught exception crashes the program. I guess you can generically catch all exceptions and get the same affect.

> panic() is just another symptom of the same disease.

Not sure what you mean here

> There is no one true way to handle errors.

Never said there was. I only made a comment that `try` does not fix how people are handling errors.

Re:An Open Letter to the Go Team About Try by qtplatypus on Tuesday July 02, 2019 @10:40PM (#20341173)
Sure it is important but I have had functions looked like this

   func foo() error {
      a, err := bar()
      if err != nil {
         return err
      }

      b, err := baz(a)
      if err != nil {
         return err
      }
     ...
    }
In some code this error handeling is 3/4 of the function lines. Sure the error behavior is important but is it 3 times more important then the logic of what you are writing?

The if nill construct contributes to cognitive load and detracts from code plainly tells you what it does. And speaking from a practical perspective I’m going to be far more productive if 3 lines of commonly used code is turned into five characters.

Re:An Open Letter to the Go Team About Try by marcus_holmes on Wednesday July 03, 2019 @02:38AM (#20342130)
Yes, that's how Go code looks, it has a rhythm of "do something, check for errors, do something, check for errors". This is a great idea, because checking for errors is explicit, and dealing with them is immediate.

After a while of working in Go, you get used to the rhythm and you stop noticing the "check for errors" part unless it does something different. You also notice when the check is missing.

And having most of your code devoted to error handling makes total sense. There are usually lots of errors states and only one "golden path" state - properly handling all the possible errors your code could generate will mean writing more error-handling code than logic code because there are more error states than non-error states it can get into.

Re:An Open Letter to the Go Team About Try by qtplatypus on Wednesday July 03, 2019 @04:47PM (#20348616)
All “try” does is allow you to write those three lines as five characters. In natural languages the more frequent used a word is the shorter that word tends to be. “Check for errors and return” is something that is frequently said in go, following from those principles it should be something that it short to write.
Re:An Open Letter to the Go Team About Try by marcus_holmes on Thursday July 04, 2019 @09:44AM (#20354553)
I see that, but it breaks the rhythm, and introduces an alternative syntax that makes it harder, not easier, to read. And code should be easier to read than to write, because we're going to read it way more than we write it.

Instead of "do something, check for errors, do something, check for errors" we would have "do something, check for errors, try something, do something, check for errors" (assuming not all errors are going to be "try"d, and some will need to be wrapped).

It stops being obvious when I've missed an error-check. That's bad.

Re:An Open Letter to the Go Team About Try by qtplatypus on Friday July 05, 2019 @01:59AM (#20360172)
How can you miss an error check?

Either you have used try and therefor there has been a check for errors.

Or you have not used try and therefor you had to assign to err and therefor you have to use a check for errors.

Any assignment to err indicates you need to check for errors just like it is currently.

Re:An Open Letter to the Go Team About Try by ben_jones on Tuesday July 02, 2019 @07:42PM (#20340373)
Been using Go for ~4 years and I agree - although I would like to see more documentation about scaling error handling in production codebases however.

Controversially I do support generics in go2.