News for hackers. Stuff that matters.
Re:What's New in Python 3.11? by usrbinbash on Monday June 27, 2022 @08:04AM (#31893352)
> Why?

Because unless the caller of foo uses a catchall, it may not actually catch the exception raised by bar. Lets say bar opens a file, and callerOfFoo says `except FileNotFoundError:` ... what if bar opens a file that exists with insufficient Permissions? Then it's `PermissionError`, and callerOfFoo won't catch it.

Sure, its possible that callerOfFoo is prepared for that, but my point is, I don't know that unless I check its code.

Re:What's New in Python 3.11? by joshuamorton on Monday June 27, 2022 @11:55AM (#31896344)
But again, why do you care?
Re:What's New in Python 3.11? by dementiapatien on Tuesday June 28, 2022 @07:37AM (#31906430)
Because I can visualize Go errors completely. They're simple links from one place to another. They are straight fibers connecting my modules and functions to each other. They always work exactly like I expect them to.

With python and other exception based languages? I have made hundreds of commits in my lifetime after being surprised that some random 3rd party library throws a nonstandard exception and breaks all sensible control flow that everybody assumed was happening.

Re:What's New in Python 3.11? by joshuamorton on Wednesday June 29, 2022 @04:43AM (#31917790)
This is the reverse of the issue that the parent mentioned though!

Consider a go function foo which returns some value and an error. What can you do with that error? You mention control flow being broken by python and others, but the control flow of

    def myfunc():
        if foo():
            do_a()
        else:
            do_b()
and

    def myfunc():
        try:
            cond = foo()
        except:
            raise
        
        if cond:
            do_a()
        else:
            do_b()
and

    func myfunc() err {
        cond, err := foo()
        if err != nil {
            return err
        }
        if cond {
            do_a()
        } else {
            do_b()
        }
Are all the same! And you can't do anything different in them, because in go, you have no knowledge about the error. Is it aa temp error you should retry? Who knows, are you going to parse the error string to figure it out? The only think you can do in go to an error from some library function is pass the error, possibly adding some additional context, because otherwise you may be mishandling the error.

In exception based languages the "pass the error" case is done for you, but if you do want to retry retriable errors, you can actually use a language feature to know that. In go, you have to hope the library creator created an interface (and that all of the possible errors that could percolate up have compatible error-extension interfaces!) that includes some kind of type information, which almost no one does.

You're talking about "sensible" control flow, but go doesn't have it!

Re:What's New in Python 3.11? by dementiapatien on Thursday June 30, 2022 @08:33AM (#31931583)
I argue that errors.Wrap and errors.Is from the Go stdlib solves this problem. Libraries can export their own error types and you can check if they threw that error type. I use this pattern all the time to handle special errors differently. Used it to implement optimistic locking which does ~not~ simply propagate all errors upwards!

https://gosamples.dev/check-error-type/

  cond, err := foo()
  if errors.Is(err, ErrFooHadTemporaryFailure) {
    // retry
  } else if errors.Is(err, ErrFooHostOffline) {
    // switchFooHost() 
  } else if err != nil {
    // propagate unhandled error upwards
    return nil, fmt.Errorf("foo unhandled err: %w", err)
  }

Of course it is up to the package author (or yourself) to write functions that return specific wrapped error types. Otherwise we're stuck in the situation your comment describes.

What do you mean by creating an error interface? It's a one liner to make a new error case:

  var ErrFooHadTemporaryFailure = errors.New("temporarily failure, retry later")
Re:What's New in Python 3.11? by usrbinbash on Thursday June 30, 2022 @12:05PM (#31934521)
I can define error values, even wrap them, and check against them, which also works on wrapped errors without having to unwrap them first:

https://go.dev/play/p/C_Yv5s6USma