> That aspect of this idea seems similar to the try proposal ( https://go.dev/issue/32437).
Yes, I read over that proposal and the comments; it seemed like the biggest objections were: 1. handle() is very similar to defer/recover but not quite the same, which could be confusing (e.g. that a defer() inside a block is just a normal defer, while a handle() inside a block does not apply outside of that block) 2. It's confusing to take the previous if err != nil {} blocks that were obviously in response to the preceding line and have the actual handling code be earlier and far away, and 3. It would encourage people to just pass errors up without modification, because it's easier to just add a bunch of try's to your code and use the default handler. My proposal doesn't have these issues - the handler goes with the try block so there's no separate function being deferred and no ambiguity about what code a given handler applies to, the handle block always comes right after the block being try'd, and there is no "default handler" - you can't use check to avoid having any error handling, only to consolidate several error handlers that would be identical. > In that issue there was considerable resistance to having flow of control change as part of an expression. No other part of Go works that way: flow of control change is always a keyword, or a call to panic which can only occur in statement context. This is not true - testing.TB.Fatal, log.Fatal, etc. affect control flow, as do numerous expressions like nil dereferences or zero divisions, and of course any function call that triggers any of those (and in extreme cases like running out of memory practically ANY expression could trigger a control flow change). The link I provided earlier to the Ondatra package demonstrates that real-world Go programmers already ARE using expressions for control flow, by (in this example) calling functions that take a testing.TB and call t.Fatal() if anything goes wrong; the authors clearly decided that this was more readable than using idiomatic error handling. I see panic/TB.Fatal as being somewhat analogous to Java's unchecked exceptions: they change control flow without warning and you can't be sure what functions trigger them. Errors-as-return-values is analogous to checked exceptions: you explicitly mark things you know could go wrong and the compiler will yell at you if you don't address those possibilities. Java's single biggest mistake (IMO) was making unchecked exceptions easier to use than checked exceptions - as a result many developers just didn't do any error handling at all. Go has mostly avoided this because checking errors is *usually *easier to write and read than using any of the aforementioned unchecked methods, but the t.Fatal examples make it clear that there still are cases where unchecked errors make code easier to read and write. I'm proposing to fix that, not by making unchecked errors harder to use or by turning checked errors into unchecked ones, but rather by streamlining the worst cases in proper error checking, primarily the all-too-common case where "if ComputeSomething(t, FetchThingOne(t), FetchThingTwo(t)) > 1" is so, so much easier to read and write than the equivalent properly checked version (which requires many more lines and several extra variables). Dan -- 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/CAAViQtjfE2FdauJ888bu1HC%2BZPPCiff5Bz5_N%3DeM2%3DVtx2fFsg%40mail.gmail.com.