Live data from Hacker News

Declined Proposal: A built-in Go error check function, “try”

github.com

271–280 of 425 posts

Re: Declined Proposal: A built-in Go error check function, “try”

#271

Earlier quoted context omitted.

> Do I particularly like managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects. So long as we can all agree that it feels super bad, I guess this is fine. But it does sort of mean that Golang approaches the Java world back with checked exceptions where principle trumped ergonomics. That lead to a world where folks felt "forced" to use Java, and that's a sti…

Literally the first non-trivial code I wrote in go (running a bunch of goroutines to download a ton of files from a website in parallel)... I knew exactly where and how things could fail and where things were failing just by looking at the code. Coming from C++ and C# and Python, there was no comparison. I had never been so confident in the code I'd written, even though I was a newbie at Go and a veteran of the other…

I'm never more confident than when I'm a newbie.

Re: Declined Proposal: A built-in Go error check function, “try”

#272
post #129

Earlier quoted context omitted.

> But it results in still less cumbersome code, since you only need scoping for the error handling portions.) There isn't a meaningful difference in cumbersomeness between having two try-catch blocks and two if-err blocks. There is a meaningful difference in cumbersomeness between what Go has today and "try foo(try bar())". Which is why it's so unfortunate that the community killed the try proposal. > But forgetting…

>There isn't a meaningful difference in cumbersomeness between having two try-catch blocks and two if-err blocks. There is a meaningful difference in cumbersomeness between what Go has today and "try foo(try bar())". Which is why it's so unfortunate that the community killed the try proposal. Object thing1; try { thing1 = doStuff(); } catch(SameException e) { // handle error 1 } try { return doOtherStuff(thing1); } c…

How often do you actually need to handle those errors differently? In my experience, it is vastly more likely that a function which can throw errors in Java looks like this:

  Stuff foo() throws SameException {
    return doOtherStuff(doStuff())
  }
Whereas in Go the exact same function must be written like this:

  func foo() (Stuff, SameException) {
    thing1, err := doStuff()
    if err != nil {
        return err
    }

    thing2, err := doOtherStuff(thing1)
    if err != nil {
        return err
    }
  }
Propagating is by far the most common "error handling" and Go constantly makes you break the flow of the code to do it.

Re: Declined Proposal: A built-in Go error check function, “try”

#273

With try, Go might have been a language I'd have enjoyed using. It's a shame. Right now, I see Go as being anti-abstraction and anti-cleverness, and I'd rather not work on codebases in which the language of choice is designed to deter creativity and encourage monotony. Heavy use of Go is a big negative when I evaluate potential projects to work on.

Indeed, I like to think of Go as basically the opposite of Lisp.

Its funny that Go keeps going on how simple it is. Which scheme is much more simple then go will ever be.

Re: Declined Proposal: A built-in Go error check function, “try”

#274

Earlier quoted context omitted.

I guess then I have to ask, why would try() make that worse? Because I can't stand Golang error handling. It's repetitive, it's error prone, and other language features interact with it so that when you make a mistake it can be as hard as a double free to track down where the erroneous default value was introduced. On the other hand, using Rust, Ocaml, F# or Haskell I understand how my code composed and I can be conf…

Try makes it worse because it is so easy to miss when reading the code. Because it encourages nesting function calls, which is harder for a human to parse than separate statements across lines. Because it means you can exit the current function from the middle of a line of code, and what runs before or doesn't run before is based on order of operations rather than requiring the exit to be a statement on its own line…

The difference with catch blocks in Java, C++ or Python is that you only need to write them when you actually have something g meaningful to do.

If you only need to propagate the error or cleanup resources then propagate the error, then all you would write is... Nothing. And cleanup+propagation is by far the most common error handling strategy. In Java and Python exceptions even add context for you automatically to help track down what happened.

Re: Declined Proposal: A built-in Go error check function, “try”

#275

Earlier quoted context omitted.

Try makes it worse because it is so easy to miss when reading the code. Because it encourages nesting function calls, which is harder for a human to parse than separate statements across lines. Because it means you can exit the current function from the middle of a line of code, and what runs before or doesn't run before is based on order of operations rather than requiring the exit to be a statement on its own line…

The difference with catch blocks in Java, C++ or Python is that you only need to write them when you actually have something g meaningful to do. If you only need to propagate the error or cleanup resources then propagate the error, then all you would write is... Nothing. And cleanup+propagation is by far the most common error handling strategy. In Java and Python exceptions even add context for you automatically to h…

One foundational principle of Go is that the sad path is at least as important, and maybe more important, than the happy path. The best Go programmers I know write the sad path of their programs first, and then backfill the happy-path logic. So:

> you only need to write [error checking] when you actually have something meaningful to do.

Although it's the subject of a lot of ridicule, `if err != nil { return err }` is actually bad Go code, and not often written by good Go programmers. Errors in Go are, at a minimum, annotated with contextual information before being returned. Frequently, they are programmed-with in other, more sophisticated ways, depending on the domain of the program.

Shifting your mindset to understand errors as something significantly more important than the off-gassing of your program's execution is worthwhile in general, and, in Go, fundamental.

Re: Declined Proposal: A built-in Go error check function, “try”

#276
post #180

Earlier quoted context omitted.

pg wrote a bunch of really good essays about Java vs Python vs Lisp and how those were perceived by programmers. I always remember them when I see Go being compared to Java while still being liked by Hackers. I wonder what he would write about this phenomenon.

pg has a blind spot wrt Java. Lots of hackers liked (and still like) Java ecosystem (see Kotlin for more recent fun). like lisp hackers, they hung out on their own and didn't mingle.

Disclosure: I am not very impressed by Paul Graham as a programmer.

However I think he came by his dislike honestly. When he was actively working, Java was really quite frustrating.

Re: Declined Proposal: A built-in Go error check function, “try”

#277
post #61

Earlier quoted context omitted.

> Do I particularly like managing errors that way? No, but I do think that it improves the transparency and quality of a lot of Go projects. So long as we can all agree that it feels super bad, I guess this is fine. But it does sort of mean that Golang approaches the Java world back with checked exceptions where principle trumped ergonomics. That lead to a world where folks felt "forced" to use Java, and that's a sti…

>So long as we can all agree that it feels super bad, I guess this is fine. Actually, I don't think everyone agrees it feels super bad. I personally like having all of my error handling be explicit, painfully explicit even. >approaches the Java world back with checked exceptions where principle trumped ergonomics. I also have to disagree here. To me, checked exceptions are the worst of both worlds. Here you have addi…

A case could be made that the syntax is somewhat nicer but you're paying for that by losing proper scoping and typing without typed exceptions.

With the amount of boilerplate in go that is simply about bubbling up error codes, it really doesn't seem that much cleaner than Java exceptions. An if block just as many lines as a catch block but again, you lose the typing.

And the more I think about it, the more I think well written Java is cleaner than well written go simply because the throws keyword leads to strictly less boilerplate. I feel like this stigma is simply about how much bad Java exists (and there's a lot). I can't help but feel like a WebSphere written in Go would be just as ugly as its current Java incarnation.

Re: Declined Proposal: A built-in Go error check function, “try”

#278
post #174

Earlier quoted context omitted.

In rust though, you dont have to handle errors all the time. You can just unwrap them, and crash when there's an error.

It's not just that though, GC is also a big part of the equation. I stopped manually managing memory 20 years ago. I'm not interested in going back to that. I get that certain aspects of Rust make that easier (and certainly safer) but I'm not working in a domain where the performance gains of ditching GC matter.

You are hardly managing memory in rust...reference allocation is practically garbage collection and feels as such in rust.

Re: Declined Proposal: A built-in Go error check function, “try”

#279
post #33

This hits at something fundamental about Go, which is what I like the most about it... It's a language intended to have few primitives with an emphasis on code being transparent and errors being values, requiring you to think about what they might be at each point as you're forced to carry them up the chain. Do I particularly like managing errors that way? No, but I do think that it improves the transparency and qual…

> And things like the lack of abstractions and generics are what create a community

> that's less reliant on dependencies. "A little copying is better than a little

> dependency" and you can see it in stark contrast to something like the JS community

> with its require('left-pad') NPM ecosystem.

The dependency-hell of node projects is in no way whatsoever related to sensible, accepted programming paradigms like generics. Their absence from Go is a widely accepted shortcoming of the language. It doesn't make Go a bad language, and it doesn't reflect on you or anyone in the Go community who enjoy using the language, but you don't have to try so hard to rationalise their absence, especially since they're one of the more prominent things in the Go 2 drafts.

Re: Declined Proposal: A built-in Go error check function, “try”

#280
post #167

Earlier quoted context omitted.

Repetition and verbosity in a language can create errors in at least two ways. First, by the developer losing track of which error case is which (and/or copy-pasting error-handling logic) and doing the wrong thing in the error case. Second, by reviewers who have become trained to notice and gloss over error-handling boilerplate not noticing when there's something wrong with a particular case. Concise languages can be…

Interesting perspective. Are you expressing an opinion about "explicit is better than implicit", or is your point on a different axis? I suppose concise / implicit is fine when the thing that's being hidden can't go wrong, like in: [i * 2 for i in 1...10] The loop counter increment logic can't possibly go wrong, so it's fine to not think about it. Regarding error-handling, don't you want to think about? If you're cal…

Concise and implicit are kind of different axes. For example, Python's "x += 1" is more concise than AppleScript's "set variable x to x + 1.", but the exact behavior of the statement is just as clear from reading it, so it is no less explicit.

In this case, I don't think anyone is arguing that error handling should be implicit. They're saying there should be an explicit way of saying "handle this error in the common way." This actually makes the distinction between common and uncommon cases more explicit, because their differences aren't buried in boilerplate.

Post reply on HN