> Most functions are called more than once in a program, so adding
> context to the implementation itself would benefit every caller: they 
don't
> need to add the context themselves.

This is highly questionable assumption. Context outside is obviously 
superior:

   - Your assumption just does not work. Imagine a generic function like 
   *os.Open*, it cannot provide really sensible and easy to read context.
   - Context outside means finer control, the annotation can tell exactly 
   what you meant. With *try* you only can achieve the same with numerous 
   tiny functions of one use and this payload hugely overweights these *if 
   err != nil*

I really glad this strange proposal was rejected. I was voting for better 
error handling, but I meant better error handling, not this nonsense. I 
would like to have something that will not allow to pass error handling by 
mistake, not the way to save 3 or 2 lines of code in one place just to have 
additional 6 lines to achieve the same error annotations detais.




среда, 29 июля 2020 г. в 01:01:34 UTC+3, mbohu...@gmail.com: 

> I've been thinking a lot about this Russ's comment 
> <https://github.com/golang/go/issues/32437#issuecomment-503297387> from 
> the try
> proposal:
>
> > But before we get to try, it is worth making sure we're all on the
> > same page about appropriate error context. The canonical example
> > is os.Open. Quoting the Go blog post “Error handling and Go”:
> >
> > > It is the error implementation's responsibility to summarize the
> > > context.  The error returned by os.Open formats as "open /etc/passwd:
> > > permission denied," not just "permission denied."
> >
> > See also Effective Go's section on Errors.
>
> Specifically, this quote:
>
> > There is lots of code following the Go convention today, but there
> > is also lots of code assuming the opposite convention. It's too
> > common to see code like:
> >
> > f, err := os.Open(file)
> > if err != nil {
> > log.Fatalf("opening %s: %v", file, err)
> > }
>
> I'd say, from the comments on the try proposal and other proposals
> related to error handling, as well as from various different blog posts
> and podcasts, that there's more cases that follow the *opposite*
> *convention*, i.e. it is the caller rather than the implementation that is
> adding context.
>
> Most functions are called more than once in a program, so adding
> context to the implementation itself would benefit every caller: they don't
> need to add the context themselves.
>
> This brings me back to the try proposal, which, as far as I know,
> was trying to solve the most common problem: removing boiler plate
> code when the caller has no additional context to add. In my estimate,
> this is roughly 50 % of the cases in a typical codebase. A number
> of commenters were arguing that the try proposal doesn't make it
> easier to add context to the error, but that wasn't the problem it
> was trying to solve. It's already quite easy to add context on the
> caller's side: just use if/switch statements or other mechanisms.
> (Errors are values.)
>
> So despite being sceptic at first, I ended up being in support of
> the try proposal. It solves the biggest issue with error handling,
> and it solves it well. Specifically it:
>
> 1. encourages the right convention to add context on the callee's side,
> 2. and makes the code more clear and expressive for roughly 50 % of the 
> cases.
>
> In my view, the only valid arguments against this proposal were outlined 
> in the
> decline comment 
> <https://github.com/golang/go/issues/32437#issuecomment-512035919> by 
> Robert:
>
> > As far as technical feedback, this discussion has helpfully identified
> > some important considerations we missed, most notably the implications
> > for adding debugging prints and analyzing code coverage.
>
> As I see it, the first step in the journey to better error handling
> is to make most Go code agree on which convention to use: whether
> it is the implementation, or the caller who is responsible for adding
> context.
>
> --------
>
> Since the recent changes to the Generics proposal make it more
> realistic that Go might one day get generics, I was thinking whether
> the try proposal could be implemented using them. This is what I
> come up with:
>
> // Package eh implements functions for error handling.
> package eh
>
> func Check(err error) { … }
>
> func Try[type T](v T, err error) T { … }
>
> func Try3[type T, U](v T, w U, err error) (T, U) { … }
>
> func Catch(errp *error) { … }
>
> func Catchf(errp *error, format string, args ...interface{}) { … }
>
> 1. First off, the package name should be short since the package
>    would be used a lot in practice.
> 2. We don't need that many variants for the different argument
>    counts: most functions returning errors return 2 values. There might
>    be some with 3 values. We might add Try4 or even Try5 if that would
>    prove to be useful.
> 3. The name Check seemed to fit better for error-only checking.
> 4. In order for this to work the package would need to use panic;
>    thus, every function using this kind of error handling would *need*
>    to defer calling to either Catch or Catchf. This would probably
>    require some sort of vet check to prevent misuse.
> 5. This package combines variants of the proposed built-in function
>    "try" as well as the helper methods as proposed by Russ in
>    https://github.com/golang/go/issues/32676. I chose Catch and Catchf
>    without further consideration; that's not the point of this post.
>
> Some examples derived from the try proposal:
>
> func CopyFile(src, dst string) (err error) {
> defer eh.Catchf(&err, "copy %s %s", src, dst)
>
>         r := eh.Try(os.Open(src))
>         defer r.Close()
>
>         w := eh.Try(os.Create(dst))
>         defer func() {
>                 w.Close()
>                 if err != nil {
>                         os.Remove(dst)
>                 }
>         }()
>
>         eh.Try(io.Copy(w, r))
>         eh.Check(w.Close())
>         return nil
> }
>
> func printSum(a, b string) (err error) {
> defer eh.Catch(&err)
> x := eh.Try(strconv.Atoi(a))
> y := eh.Try(strconv.Atoi(b))
> fmt.Println("result:", x+y)
> return nil
> }
>
> There are really 2 questions I want to ask:
>
> 1. How to motivate people to use the Go convention (let the
>    implementation add the context). Is that the right convention?
> 2. Do Generics enable implementing a package for try-like error
>    handling, or am I missing something?
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f4f6e332-e22e-4170-8c56-2dedd4f38336n%40googlegroups.com.

Reply via email to