Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-11 Thread Konstantin Khomoutov
On Mon, Sep 11, 2017 at 08:49:30PM +1200, Tim Uckun wrote:

> | However, what's great for avoiding straightforward failures becomes a
> | nightmare when your goal is to guarantee that no undefined behaviour
> | happens
> 
> It seems to me that if this is your goal other languages are more suitable.
> Erlang for example is famous for it's error handling capability,
> elm guarantees no runtime errors, and some other functional languages can
> be proven mathematically at compile time.

That's not what the author used the term "no undefined behaviour" for;
he referred to the simpler idea of having all possible code paths in the
program flow being handled.

When you have exceptions, you have two problems:

* When they are handled not right at the spot where they are generated, you
  - Lose track of the points where they may be generated;
  - Have hard time distinguishing between exceptions occured in
different places in the control flow (unless you use super-shallow
and super-wide type hierarchy or encode this information in the
exceptions).
* When new exceptions are added, you have to identify and modify all
  places where they're handled.

That's why typically "exception handling" indeed means having try/catch
somewhere at the top level and displaying an error message dialog box
(or a HTTP 500 Internal Error page) to the user which is not error
handling but "avoiding straightforward failures".

As to your particular examples, I'm not familiar with Elm but Erlang
stands out for two reasons:

- It has the so-called "pattern matching" which, coupled with
  Erlang's typelessness, allows to implement something which works like
  "algebraic types".  That is, it's easy to write code which asserts
  specific "shapes" and contents of the values at runtime, and crashes
  when these expectatiosn are not met.  While this is very neat, pretty
  much of this is covered by Go's static types.

- It implements the so-called "supervision trees" which allow you to
  construct hierarchies of "processes" in which parents get notified
  when the children crash, and policies for restarting those processes
  which crashed.

  While, again, being very neat, their ultimate usefullness is something
  disputable: when you have a panic in your Go code, this means you
  have a bug, and given the fact Go is a compiled language, this may
  mean your whole runtime is an unknown state.

  All in all, implementation of supervision trees for Go do exist.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-11 Thread Tim Uckun
| However, what's great for avoiding straightforward failures becomes a
| nightmare when your goal is to guarantee that no undefined behaviour
| happens

It seems to me that if this is your goal other languages are more suitable.
Erlang for example is famous for it's error handling capability, elm
guarantees no runtime errors, and some other functional languages can be
proven mathematically at compile time.

Go doesn't take that route which is one of the reasons why it's more
popular than those languages :)

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-11 Thread Konstantin Khomoutov
On Wed, Sep 06, 2017 at 11:00:08PM -0700, Tim Uckun wrote:

> Totally not a go programmer but here are my worthless two cents.
> 
> I don't see anything wrong with the try catch paradigm, you can choose your 
> granularity. If you want to check every call then you can, if you want to 
> let a few cluster together you can. You guys make is sound like go style 
> error handling is the only way to catch errors at every step. That's not 
> true at all.  
[...]

Actually, I do think there are cases when you don't care which error has
actually happened, and where -- you just want to abort processing and
quit.  Unfortunately, this only works for "batch-style" processing, like
shell scripts -- where you want the whole thing to be done, or to fail
ASAP should any problem be detected (well, sometimes, though quite much
more rarely, you'd even want to merely log errors and continue to chug
away with the operations).

I have a goto writeup on exceptions bookmarked, which I invite you to
read [1].

The key point from it, which pretty much summarizes the idea behind how
error handing is done in Go, is:

| C++ exceptions … are great for guaranteeing that program doesn't
| fail — just wrap the main function in try/catch block and you can
| handle all the errors in a single place.
|
| However, what's great for avoiding straightforward failures becomes a
| nightmare when your goal is to guarantee that no undefined behaviour
| happens. The decoupling between raising of the exception and handling
| it, that makes avoiding failures so easy in C++, makes it virtually
| impossible to guarantee that the program never runs info undefined
| behaviour.

1. http://250bpm.com/blog:4

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-08 Thread 'Axel Wagner' via golang-nuts
The solution to Close returning an error, is to defer Close() and then have
a second Close() with error checking in the happy path.

I just wish the io.Closer contract would require, that this has to be safe
(= not panic). Luckily it is, for the vast majority of Closers at least.

On Fri, Sep 8, 2017 at 6:01 PM,  wrote:

> P.S. someone else proposed wrapper with error handling in defer.
>> IMO it is as bad as watch - spooky, at distance, clunky.
>>
>
> That was me. My background is many years of C++ and it feels natural to me
> (RAII). I follow the pattern: there must be defer Close immediately after
> acquire action, so it is very obvious in code review if there's a resource
> leak or not and if it's panic safe or not. Unfortunately when a defer is
> used, another defer is often necessary.
>
> I read this blog post a while ago: https://joeshaw.org/dont-
> defer-close-on-writable-files/
>
> He seems to agree with you ("Still, I find this pattern to be a little too
> magical."), but his other alternative examples do not seem very
> convincing...
>
> On Friday, September 8, 2017 at 11:03:44 AM UTC+2, ohir wrote:
>>
>> On Thu, 7 Sep 2017 17:03:06 -0700 (PDT)
>> Dorival Pedroso  wrote:
>>
>>
>> > Wouldn't be great to have a "syntactical sugar" to make things (at
>> least a
>> > little bit) simpler in our beloved Go language?
>>
>> No. Proposed (*also by past me*) "watch" construct is bad for anyone
>> reading code, bad for code consistency and is unable to provide any real
>> value in spite of high expectations. I coined it as a freshmen to Go then
>> I gave it up after few tries to "implement" it with code generator just
>> after
>> "spooky action at distance is bad" turned out to be so true.
>>
>> > Simpler would certainly encourage people to handle errors properly
>>
>> "Watch" is NOT simpler. It bears "at distance" burden. It does not give
>> debugging person a way to know which call under watch went wrong.
>> The explicitness of if err!=nil { ... } is.
>>
>> > Of course, we don't need the "watch" command for these. In fact, we
>> need
>> > nothing special in Go to properly handle these errors.
>>
>> Yes. And I have learned it weeks after my "I wanna watch" fool.
>> (The reason for "watch" was porting an ugly code to check validity of
>> many
>> fields in complicated financial messages).
>>
>> Had I have "watch" at hand I would end blindly (albeit automated)
>> rewriting
>> try/catch spaghetti code for each MT. Fortunately I had no "watch" so I
>> got
>> to the table, then to the map (for maintenance reasons. See here map:
>> https://play.golang.org/p/3PDgjCgPMK . Every try/catch block rewritten
>> in
>> Go became simple call of validate(&MT, "ABA","SC","RSN") shape).
>>
>> For SQL call chains you may use "For/Switch" pattern:
>> https://play.golang.org/p/0gWarQ8TL7 .
>>
>> For/Switch is clear and can cope with e.g. retries for a 5 lines more:
>> https://play.golang.org/p/CyhIJabzFn
>>
>> watch:
>> for i = 1; retry < 3; i++ {
>> if err != nil {
>> i--
>> retry++
>> continue
>> }
>> switch i {
>> case 1:
>> err = getData(i)
>> case 2:
>> err = getData(i)
>> case 3:
>> err = getData(i)
>> default:
>> break watch
>> }
>> }
>> if err != nil {
>> // handle common error
>> }
>>
>> All above patterns have single err handling place yet give back
>> information
>> where err was set -- something "watch" knows nothing about.
>>
>> P.S. someone else proposed wrapper with error handling in defer.
>> IMO it is as bad as watch - spooky, at distance, clunky.
>>
>> --
>> Wojciech S. Czarnecki
>>  << ^oo^ >> OHIR-RIPE
>>
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-08 Thread ekocjan

>
> P.S. someone else proposed wrapper with error handling in defer. 
> IMO it is as bad as watch - spooky, at distance, clunky. 
>

That was me. My background is many years of C++ and it feels natural to me 
(RAII). I follow the pattern: there must be defer Close immediately after 
acquire action, so it is very obvious in code review if there's a resource 
leak or not and if it's panic safe or not. Unfortunately when a defer is 
used, another defer is often necessary.

I read this blog post a while 
ago: https://joeshaw.org/dont-defer-close-on-writable-files/

He seems to agree with you ("Still, I find this pattern to be a little too 
magical."), but his other alternative examples do not seem very 
convincing...

On Friday, September 8, 2017 at 11:03:44 AM UTC+2, ohir wrote:
>
> On Thu, 7 Sep 2017 17:03:06 -0700 (PDT) 
> Dorival Pedroso > wrote: 
>
>
> > Wouldn't be great to have a "syntactical sugar" to make things (at least 
> a 
> > little bit) simpler in our beloved Go language? 
>
> No. Proposed (*also by past me*) "watch" construct is bad for anyone 
> reading code, bad for code consistency and is unable to provide any real 
> value in spite of high expectations. I coined it as a freshmen to Go then 
> I gave it up after few tries to "implement" it with code generator just 
> after 
> "spooky action at distance is bad" turned out to be so true. 
>
> > Simpler would certainly encourage people to handle errors properly 
>
> "Watch" is NOT simpler. It bears "at distance" burden. It does not give 
> debugging person a way to know which call under watch went wrong. 
> The explicitness of if err!=nil { ... } is. 
>
> > Of course, we don't need the "watch" command for these. In fact, we need 
> > nothing special in Go to properly handle these errors. 
>
> Yes. And I have learned it weeks after my "I wanna watch" fool. 
> (The reason for "watch" was porting an ugly code to check validity of many 
> fields in complicated financial messages). 
>
> Had I have "watch" at hand I would end blindly (albeit automated) 
> rewriting 
> try/catch spaghetti code for each MT. Fortunately I had no "watch" so I 
> got 
> to the table, then to the map (for maintenance reasons. See here map: 
> https://play.golang.org/p/3PDgjCgPMK . Every try/catch block rewritten in 
> Go became simple call of validate(&MT, "ABA","SC","RSN") shape). 
>
> For SQL call chains you may use "For/Switch" pattern: 
> https://play.golang.org/p/0gWarQ8TL7 . 
>
> For/Switch is clear and can cope with e.g. retries for a 5 lines more: 
> https://play.golang.org/p/CyhIJabzFn 
>
> watch: 
> for i = 1; retry < 3; i++ { 
> if err != nil { 
> i-- 
> retry++ 
> continue 
> } 
> switch i { 
> case 1: 
> err = getData(i) 
> case 2: 
> err = getData(i) 
> case 3: 
> err = getData(i) 
> default: 
> break watch 
> } 
> } 
> if err != nil { 
> // handle common error 
> } 
>
> All above patterns have single err handling place yet give back 
> information 
> where err was set -- something "watch" knows nothing about. 
>
> P.S. someone else proposed wrapper with error handling in defer. 
> IMO it is as bad as watch - spooky, at distance, clunky. 
>
> -- 
> Wojciech S. Czarnecki 
>  << ^oo^ >> OHIR-RIPE 
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-08 Thread Dorival Pedroso
Sure! I'm happy to listen to the experience of you all and to keep working 
using the existent approach. Thanks, everyone. Dorival

On Friday, September 8, 2017 at 10:29:02 PM UTC+10, Marvin Renich wrote:
>
> * Dorival Pedroso  [170908 02:08]: 
> > The "watch" strategy would, of course, allow us to do the important 
> steps 
> > you've mentioned (e.g. clean up and so on). 
> > 
> > For instance: 
> > watch err != nil { 
> > // do the important things 
> > return err 
> > } 
>
> Except that "do the important things" often depends on which step 
> produced the error.  Now you have a switch statement inside the watch 
> statement to handle the different "early exit" cases.  Instead of having 
> individual "do step1; clean up after step1" in a linear sequence, you 
> have "do step1; do step2..." with all of the separate "clean up after 
> stepN" in a switch statement in a different place.  You also have 
> additional code within the "do step1; do step2..." section to allow the 
> watch statement to determine which switch case to invoke.This is 
> much easier to get wrong, harder to modify (especially if you have 
> nested watch statements), and harder to debug. 
>
> I believe that the Go devs want to encourage suggestions like yours for 
> Go 2, but this particular one has already been discussed more than once 
> on this list.  You have numerous experienced programmers who have all 
> used languages with similar constructs telling you that it looks good at 
> the start, but ends up producing much less maintainable code.  Listen to 
> experience. 
>
> In this particular case, it is not the details that are inconsistent 
> with the basic philosophy behind the design of the Go language, it is 
> the entire concept of separating "error" handling from "non-error" 
> handling.  Both are "handling the results" and both belong in the 
> relative vicinity of the code that produced the results, whether the 
> results are considered "errors" or "non-errors". 
>
> ...Marvin 
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-08 Thread Marvin Renich
* Dorival Pedroso  [170908 02:08]:
> The "watch" strategy would, of course, allow us to do the important steps 
> you've mentioned (e.g. clean up and so on).
> 
> For instance:
> watch err != nil {
> // do the important things
> return err
> }

Except that "do the important things" often depends on which step
produced the error.  Now you have a switch statement inside the watch
statement to handle the different "early exit" cases.  Instead of having
individual "do step1; clean up after step1" in a linear sequence, you
have "do step1; do step2..." with all of the separate "clean up after
stepN" in a switch statement in a different place.  You also have
additional code within the "do step1; do step2..." section to allow the
watch statement to determine which switch case to invoke.This is
much easier to get wrong, harder to modify (especially if you have
nested watch statements), and harder to debug.

I believe that the Go devs want to encourage suggestions like yours for
Go 2, but this particular one has already been discussed more than once
on this list.  You have numerous experienced programmers who have all
used languages with similar constructs telling you that it looks good at
the start, but ends up producing much less maintainable code.  Listen to
experience.

In this particular case, it is not the details that are inconsistent
with the basic philosophy behind the design of the Go language, it is
the entire concept of separating "error" handling from "non-error"
handling.  Both are "handling the results" and both belong in the
relative vicinity of the code that produced the results, whether the
results are considered "errors" or "non-errors".

...Marvin

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-08 Thread Wojciech S. Czarnecki
On Thu, 7 Sep 2017 17:03:06 -0700 (PDT)
Dorival Pedroso  wrote:


> Wouldn't be great to have a "syntactical sugar" to make things (at least a 
> little bit) simpler in our beloved Go language?

No. Proposed (*also by past me*) "watch" construct is bad for anyone
reading code, bad for code consistency and is unable to provide any real
value in spite of high expectations. I coined it as a freshmen to Go then
I gave it up after few tries to "implement" it with code generator just after
"spooky action at distance is bad" turned out to be so true.

> Simpler would certainly encourage people to handle errors properly

"Watch" is NOT simpler. It bears "at distance" burden. It does not give
debugging person a way to know which call under watch went wrong. 
The explicitness of if err!=nil { ... } is.

> Of course, we don't need the "watch" command for these. In fact, we need
> nothing special in Go to properly handle these errors.

Yes. And I have learned it weeks after my "I wanna watch" fool.
(The reason for "watch" was porting an ugly code to check validity of many
fields in complicated financial messages).

Had I have "watch" at hand I would end blindly (albeit automated) rewriting
try/catch spaghetti code for each MT. Fortunately I had no "watch" so I got
to the table, then to the map (for maintenance reasons. See here map:
https://play.golang.org/p/3PDgjCgPMK . Every try/catch block rewritten in
Go became simple call of validate(&MT, "ABA","SC","RSN") shape).

For SQL call chains you may use "For/Switch" pattern:
https://play.golang.org/p/0gWarQ8TL7 .

For/Switch is clear and can cope with e.g. retries for a 5 lines more:
https://play.golang.org/p/CyhIJabzFn

watch:
for i = 1; retry < 3; i++ {
if err != nil {
i--
retry++
continue
}
switch i {
case 1:
err = getData(i)
case 2:
err = getData(i)
case 3:
err = getData(i)
default:
break watch
}
}
if err != nil {
// handle common error
}

All above patterns have single err handling place yet give back information
where err was set -- something "watch" knows nothing about.

P.S. someone else proposed wrapper with error handling in defer.
IMO it is as bad as watch - spooky, at distance, clunky. 

-- 
Wojciech S. Czarnecki
 << ^oo^ >> OHIR-RIPE

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Dorival Pedroso
please replace:
"will return immediately to the [...]"
with
"will jump immediately to the [...]"
(sorry)

On Friday, September 8, 2017 at 4:07:35 PM UTC+10, Dorival Pedroso wrote:
>
> Hi Dave,
>
> The "watch" strategy would, of course, allow us to do the important steps 
> you've mentioned (e.g. clean up and so on).
>
> For instance:
> watch err != nil {
> // do the important things
> return err
> }
>
> The watch basically "groups common tasks".
>
> For example, If we have so many tasks, we could do this:
> watch errFiles != nil {
> cleanup() // do cleanups as Dave suggested
> return // this is an synthetic example that doesn't require error 
> propagation (application dependent, of course)
> }
> watch errComputations != nil {
> // nothing to be done here
> return errComputations // return the error because computations failed
> }
> errFiles = fileOperation("a.txt") // will return immediately to the first 
> "watch" if errFiles != nil
> errFiles = fileOperation("a.txt") // will return immediately to the first 
> "watch" if errFiles != nil
> errFiles = fileOperation("a.txt") // will return immediately to the first 
> "watch" if errFiles != nil
> errCompuations = computeWith("a.txt") // will return immediately to the 
> second "watch" if errComputations != nil
> errCompuations = computeWith("a.txt") // will return immediately to the 
> second "watch" if errComputations != nil
> errCompuations = computeWith("a.txt") // will return immediately to the 
> second "watch" if errComputations != nil
>
> Of course, we don't need the "watch" command for these. In fact, we need 
> nothing special in Go to properly handle these errors.
>
> Cheers.
> Dorival
>
>
>
> On Friday, September 8, 2017 at 1:08:47 PM UTC+10, Dave Cheney wrote:
>>
>>
>>> Wouldn't be great to have a "syntactical sugar" to make things (at least 
>>> a little bit) simpler in our beloved Go language?
>>>


>> no, I don't think so. 
>>
>> Something that few in in this thread have focused on is the most 
>> important part of the go error handling story happens *before* the `return 
>> err` statement
>>
>> if err != nil {
>>   // this is the important part
>>   return err // this is not
>> }
>>
>> Specifically, when an error occurs, cleaning up the accumulated state to 
>> that point, removing any temporary items like files on disk, transactions, 
>> etc, so that the caller can attempt to retry the operation if they so 
>> choose.
>>
>> Now it happens that most times, thanks to things like defer, there is 
>> usually nothing to handle in the cleanup phase before returning the error, 
>> but in my opinion does not take anything away from this being the most 
>> important part of Go's error handling story. 
>>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Dorival Pedroso
Hi Dave,

The "watch" strategy would, of course, allow us to do the important steps 
you've mentioned (e.g. clean up and so on).

For instance:
watch err != nil {
// do the important things
return err
}

The watch basically "groups common tasks".

For example, If we have so many tasks, we could do this:
watch errFiles != nil {
cleanup() // do cleanups as Dave suggested
return // this is an synthetic example that doesn't require error 
propagation (application dependent, of course)
}
watch errComputations != nil {
// nothing to be done here
return errComputations // return the error because computations failed
}
errFiles = fileOperation("a.txt") // will return immediately to the first 
"watch" if errFiles != nil
errFiles = fileOperation("a.txt") // will return immediately to the first 
"watch" if errFiles != nil
errFiles = fileOperation("a.txt") // will return immediately to the first 
"watch" if errFiles != nil
errCompuations = computeWith("a.txt") // will return immediately to the 
second "watch" if errComputations != nil
errCompuations = computeWith("a.txt") // will return immediately to the 
second "watch" if errComputations != nil
errCompuations = computeWith("a.txt") // will return immediately to the 
second "watch" if errComputations != nil

Of course, we don't need the "watch" command for these. In fact, we need 
nothing special in Go to properly handle these errors.

Cheers.
Dorival



On Friday, September 8, 2017 at 1:08:47 PM UTC+10, Dave Cheney wrote:
>
>
>> Wouldn't be great to have a "syntactical sugar" to make things (at least 
>> a little bit) simpler in our beloved Go language?
>>
>>>
>>>
> no, I don't think so. 
>
> Something that few in in this thread have focused on is the most important 
> part of the go error handling story happens *before* the `return err` 
> statement
>
> if err != nil {
>   // this is the important part
>   return err // this is not
> }
>
> Specifically, when an error occurs, cleaning up the accumulated state to 
> that point, removing any temporary items like files on disk, transactions, 
> etc, so that the caller can attempt to retry the operation if they so 
> choose.
>
> Now it happens that most times, thanks to things like defer, there is 
> usually nothing to handle in the cleanup phase before returning the error, 
> but in my opinion does not take anything away from this being the most 
> important part of Go's error handling story. 
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Dave Cheney

>
>
> Wouldn't be great to have a "syntactical sugar" to make things (at least a 
> little bit) simpler in our beloved Go language?
>
>>
>>
no, I don't think so. 

Something that few in in this thread have focused on is the most important 
part of the go error handling story happens *before* the `return err` 
statement

if err != nil {
  // this is the important part
  return err // this is not
}

Specifically, when an error occurs, cleaning up the accumulated state to 
that point, removing any temporary items like files on disk, transactions, 
etc, so that the caller can attempt to retry the operation if they so 
choose.

Now it happens that most times, thanks to things like defer, there is 
usually nothing to handle in the cleanup phase before returning the error, 
but in my opinion does not take anything away from this being the most 
important part of Go's error handling story. 

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Dorival Pedroso
Yes, Nigel! try/catch in Python may at times looks uglier that err != nil. 
I think the reason try/catch didn't bother us in C++ is that we had lots of 
macros to simplify the work...

In Go, we don't have macros but we don't need to wrap things with "try" and 
just need to "recover" panics, I think. That's why I prefer Martin's first 
suggestion (no "wrappings").

Wouldn't be great to have a "syntactical sugar" to make things (at least a 
little bit) simpler in our beloved Go language?

Simpler would certainly encourage people to handle errors properly too as 
Axel pointed out.

Cheers!



On Friday, September 8, 2017 at 9:34:24 AM UTC+10, Nigel Tao wrote:
>
> On Thu, Sep 7, 2017 at 4:00 PM, Tim Uckun > 
> wrote: 
> > I don't see anything wrong with the try catch paradigm, 
>
> Try-catch makes for shorter code when you're just passing the buck, 
> but it can be quite complicated when you actually need to handle the 
> buck. 
>
> My showcase example for this is the exception-ridden code in PEP 380 just 
> after 
>
> "The statement 
> RESULT = yield from EXPR 
> is semantically equivalent to" 
>
> https://www.python.org/dev/peps/pep-0380/ 
>
> I find that Python snippet very hard to understand. In contrast, 
> writing all those "if err != nil { return nil, err }" might seem 
> verbose, but I find the control flow much easier to grok, especially 
> when reviewing somebody else's Go code, or even code written by 
> 6-months-ago me. 
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Nigel Tao
On Thu, Sep 7, 2017 at 4:00 PM, Tim Uckun  wrote:
> I don't see anything wrong with the try catch paradigm,

Try-catch makes for shorter code when you're just passing the buck,
but it can be quite complicated when you actually need to handle the
buck.

My showcase example for this is the exception-ridden code in PEP 380 just after

"The statement
RESULT = yield from EXPR
is semantically equivalent to"

https://www.python.org/dev/peps/pep-0380/

I find that Python snippet very hard to understand. In contrast,
writing all those "if err != nil { return nil, err }" might seem
verbose, but I find the control flow much easier to grok, especially
when reviewing somebody else's Go code, or even code written by
6-months-ago me.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Wojciech S. Czarnecki
On Thu, 7 Sep 2017 05:00:18 -0700 (PDT)
martin.r...@programmfabrik.de wrote:

> lhow about this, and it is a construct which can  be used not only for
> errors:
 
> watch err != nil {
> yo1, err = do_stuff1()
> yo2, err = do_stuff2()
> yo3, err = do_stuff3()
> } then {
> // handle your error
> }

Without language change

watch:
for i := 0; err == nil; i++ {
switch i {
case 0:
err, yo1 = doSomething(i)
case 1:
err, yo2 = doSomething(i)
case 2:
err, yo3 = doSomething(i)
default:
break watch
}
}
if err != nil {
// on error do something
}

https://play.golang.org/p/s6xh1qM4sx

> This statement could be used for other cases as well, it is easy to read 
> and understand, and it saves the programmer from line duplication.

Above at least gives to the reader visual breaks (with 'case' lines ;)

> Martin
> 

-- 
Wojciech S. Czarnecki
 << ^oo^ >> OHIR-RIPE

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread 'Axel Wagner' via golang-nuts
On Thu, Sep 7, 2017 at 2:41 PM, Tim Uckun  wrote:

> >I *like* the way go does error passing, *because* it's constrained to
> handle errors explicitly.
>
> But it doesn't though. You can completely ignore the errors if you want. >
>

This seems to be, at best, a nit-picky uncharitable reading of what I
wrote. The context here isn't on whether the compiler should enforce error
checks or not, but what the error passing mechanism should be (also note
the difference between "being constrained to smth" and "being forced to do
smth").

Derailing isn't a particularly good strategy for a discussion, if your
objective is to convince the other party.

I was proposing that there should be a language construct called errors.
> This would be an array. As exceptions are raised the program would push the
> errors into this array. At any time you could examine the array to see if
> there were errors and if so what they were. When I said "err.pop" I was
> indicating that the program would remove the latest error from the stack to
> examine it and act on it.
>

FTR, this isn't a good design (leaving the actual question here, whether we
need a new/separate/less explicit error passing mechanism aside). It means
that a function can now "return" anything between 0 and infinitely many
errors with no way to know statically which. For example

func Foo() {
for i := 0; i < 1000; i++ {
f := os.Open(fmt.Sprintf("%d.txt", i))
if f != nil { f.Close() }
}
}

How would a caller of Foo know how many errors to pop? Or the caller of the
caller of Foo?

But again, bikeshedding about how an implicit error passing mechanism would
look isn't particularly useful, until there is an agreement that it's
needed. So far, there doesn't seem to be a consensus on that (and that
doesn't seem to be due to a lack of proposals).

This would eliminate a lot of boilerplate but conceptually be the same kind
> of error handling. Instead of returning a value, err pair you simply return
> the value or you raise an exception.  The called can check if an error was
> raised by calling some method to indicate whether or not the errors array
> is empty.
>
> For example
>
> x = someMethod()
> // if there was an error in there it would populate the array but we don't
> have to explicitly receive the err in the return.
> ifErr {
>// fetch the error
> err = errors.pop()
>something()
> }
>
> Something like that.
>
> I also realize that sometimes you may want to halt the app on errors so
> there should be a way to bypass this by some kind of declaration.
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread snmed
Hi Tim

If you want halt the app, you should call panic, that's already a go 
built-in. Think it would apply to your proposal as well, despite i do not 
agree with it.

Cheers snmed

Am Donnerstag, 7. September 2017 14:42:12 UTC+2 schrieb Tim Uckun:
>
> >I *like* the way go does error passing, *because* it's constrained to 
> handle errors explicitly.
>
> But it doesn't though. You can completely ignore the errors if you want. >
>
> >TBH, no. Not only do I not know what this is supposed to be doing 
> (err.pop? of what? Why are we assigning to error? What is happening here?), 
> at best the code seems equivalent to the current code, to me. There is a 
> function call, a conditional to check for error and then some error 
> handling. When skimming that code, it would look pretty much identical to 
> the current idiom.
>
>
> I guess I should have explained it more clearly.
>
> I was proposing that there should be a language construct called errors. 
> This would be an array. As exceptions are raised the program would push the 
> errors into this array. At any time you could examine the array to see if 
> there were errors and if so what they were. When I said "err.pop" I was 
> indicating that the program would remove the latest error from the stack to 
> examine it and act on it. 
>
> This would eliminate a lot of boilerplate but conceptually be the same 
> kind of error handling. Instead of returning a value, err pair you simply 
> return the value or you raise an exception.  The called can check if an 
> error was raised by calling some method to indicate whether or not the 
> errors array is empty. 
>
> For example
>
> x = someMethod()
> // if there was an error in there it would populate the array but we don't 
> have to explicitly receive the err in the return.
> ifErr { 
>// fetch the error
> err = errors.pop()
>something()
> }
>
> Something like that. 
>
> I also realize that sometimes you may want to halt the app on errors so 
> there should be a way to bypass this by some kind of declaration.
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Tim Uckun
>I *like* the way go does error passing, *because* it's constrained to
handle errors explicitly.

But it doesn't though. You can completely ignore the errors if you want. >

>TBH, no. Not only do I not know what this is supposed to be doing
(err.pop? of what? Why are we assigning to error? What is happening here?),
at best the code seems equivalent to the current code, to me. There is a
function call, a conditional to check for error and then some error
handling. When skimming that code, it would look pretty much identical to
the current idiom.


I guess I should have explained it more clearly.

I was proposing that there should be a language construct called errors.
This would be an array. As exceptions are raised the program would push the
errors into this array. At any time you could examine the array to see if
there were errors and if so what they were. When I said "err.pop" I was
indicating that the program would remove the latest error from the stack to
examine it and act on it.

This would eliminate a lot of boilerplate but conceptually be the same kind
of error handling. Instead of returning a value, err pair you simply return
the value or you raise an exception.  The called can check if an error was
raised by calling some method to indicate whether or not the errors array
is empty.

For example

x = someMethod()
// if there was an error in there it would populate the array but we don't
have to explicitly receive the err in the return.
ifErr {
   // fetch the error
err = errors.pop()
   something()
}

Something like that.

I also realize that sometimes you may want to halt the app on errors so
there should be a way to bypass this by some kind of declaration.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Tamás Gulácsi
I'd hate to debug this: which function has returned the error? What failed, 
what succeeded?

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread martin . rode
On Tuesday, September 5, 2017 at 10:39:05 AM UTC+2, Rob 'Commander' Pike 
wrote:
>
> If you find that lines like if err != nil are a significant fraction 
> of non-test code, your code probably needs a better error handling 
> strategy, not a language change. I have done measurements in the past 
> and although people complain a lot about the presence of that 
> statement, it shows up much less often in practice than people claim, 
> and when it does appear a lot it's usually because the programmer is 
> not thinking enough about how errors should work. 
>

Well, I can try to find more examples, but whenever you interact with say 
SQL or other libraries, errors can occur at each call into that library.

Very often it is enough to check the errors for one block (think try... 
catch)

The problem with all suggested solutions so far is, that it requires 
wrapping function calls of some sort.

Personally, I don't like this. There are calls (say to interact with an SQL 
library), and once you start wrapping them in order for an improved error 
management, the solution is very local and personal and less readable.

This does not support Go's idea of producing readable code across 
developers and styles.

After all the responses in this thread, I thought about my proposal a 
little more carefully, so how about this, and it is a construct which can 
be used not only for errors:


watch err != nil {
yo1, err = do_stuff1()
yo2, err = do_stuff2()
yo3, err = do_stuff3()
} then {
// handle your error
}

This statement could be used for other cases as well, it is easy to read 
and understand, and it saves the programmer from line duplication.

Martin

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread 'Axel Wagner' via golang-nuts
On Thu, Sep 7, 2017 at 8:00 AM, Tim Uckun  wrote:

> I don't see anything wrong with the try catch paradigm, you can choose
> your granularity. If you want to check every call then you can, if you want
> to let a few cluster together you can. You guys make is sound like go style
> error handling is the only way to catch errors at every step. That's not
> true at all.
>

But the argument is specifically that since you should consider and handle
every error specifically, that making *not* doing that easier is bad. Good
error handling (even with a try-catch like mechanism) will end up looking
pretty much the same as it does today - and bad error handling is something
I want to see discouraged.

This is akin to someone coming to Haskell and complaining about all the
boilerplate they have in their code. "Why do I have to have this 'IO'
everywhere? Can't we just make that implicit? And get some loop-constructs
up in here, I don't want to have to think about expressing myself via
recursion all the time. All other modern languages have iteration concepts,
side-effects and mutable data. Maybe be open to some new ideas, instead of
assuming everyone else is wrong?"

How would you react to that? By saying "oh, yeah, good point, let's build
in implicit side-effects and loops and variables"? I don't think so. You'd
tell them that functional programming is about carefully containing
side-effects. To not have mutable state. And that if they are passing an IO
argument everywhere, they should think about restructuring their code and
contain IO to the outermost core that actually needs it, while keeping the
rest purely functional.

I *like* the way go does error passing, *because* it's constrained to
handle errors explicitly. And I think there is a good argument to be made,
that restructuring your program and rethinking your error handling strategy
might help you see it similarly.

Surely something can be done about the boilerplate if err != nil  maybe
> shorten that to iferr or something like that. In fact why can't "err" be a
> language construct where you raise something and it goes into an err[]
> array. At any time you can check to see what's in there. That would clean
> up the code so much.
>
> result = doSomething()
> iferr {
>error = err.pop()
> }
>
> Isn't that so much more readable?
>

TBH, no. Not only do I not know what this is supposed to be doing (err.pop?
of what? Why are we assigning to error? What is happening here?), at best
the code seems equivalent to the current code, to me. There is a function
call, a conditional to check for error and then some error handling. When
skimming that code, it would look pretty much identical to the current
idiom.

And even if we would, for the sake of argument, assume this is more
readable; this doesn't mean it justifies a new language construct. The
current error-passing mechanism is implemented with basic language
primitives that are already there anyway. That's one of its beauties.

You could even create checkpoints
>
> raiseErrors()
> // from now on all errors are raised and the program halts
> do()
> some()
> tasks()
> collectErrors()
> // from now on program doesn't halt but err[] array is populated
> do()
> other()
> things()
> dealWithErrArray() // it's global so need to pass it in
> raiseErrors()
> // back to raising them.
>
> As I said none of these are particularly nice.  Elixir gives you both ways
>
>
> def register({email, password}) do
>   {:ok, pid} = Membership.connect()
>   sql = "select * from membership.register($1, $2);"
>
>   case Postgrex.Connection.query(pid, sql, [email, password]) do
> {:ok, res} ->
>   cols = res.columns
>   [first_row | _] = res.rows
>   [new_id, validation_token, auth_token, success, message] = first_row
>   {:ok, %RegistrationResult{
> success: success,
> message: message,
> new_id: new_id,
> authentication_token: auth_token,
> validation_token: validation_token
> }}
>
> {:error, err} -> {:error, err}
>   end
> end
>
>
> try do
>   opts
>   |> Keyword.fetch!(:source_file)
>   |> File.read!
> rescue
>   e in KeyError -> IO.puts "missing :source_file option"
>   e in File.Error -> IO.puts "unable to read source file"
> end
>
> As somebody who has just started learning go I can't find any
> justification for the insane amount of boilerplate go error handling
> inflicts on the programmer.  Surely there is a a better way.
>
>
>
> On Wednesday, September 6, 2017 at 8:54:38 PM UTC+12, Henry wrote:
>>
>> I use what I would call as *error context*.
>>
>> Here is the simple definition of the *error context*:
>>
>> type ErrorContext interface {
>> ContainsError() bool
>> SetError(err error)
>> Error() error
>> }
>>
>> Here is how you would use it inside the error-prone function:
>>
>> func FragileFunction(ctx ErrorContext) {
>> if ctx.ContainsError() {
>> return
>> }
>>
>> //some processing ...
>> //if there is an error
>> ctx.Se

[go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Dorival Pedroso
Agreed, Tim.

This discussion helped me to realise that try/catch is pretty good; e.g. we 
never even bothered discussing this topic in our C++ 
code http://mechsys.nongnu.org/ at all...

In the end of the day, we want to treat ALL errors (obviously...).

Go is great that we have two approaches.

Right now I'm changing my code to panic/recover and it's looking good (so 
far): 
https://github.com/cpmech/gosl/commit/16924f154a848e01a070dc7f86d7f4a3962a0af8

Cheers.
Dorival

On Thursday, September 7, 2017 at 6:37:21 PM UTC+10, Tim Uckun wrote:
>
> Totally not a go programmer but here are my worthless two cents.
>
>
>
> I don't see anything wrong with the try catch paradigm, you can choose 
> your granularity. If you want to check every call then you can, if you want 
> to let a few cluster together you can. You guys make is sound like go style 
> error handling is the only way to catch errors at every step. That's not 
> true at all.  
>
> Surely something can be done about the boilerplate if err != nil  maybe 
> shorten that to iferr or something like that. In fact why can't "err" be a 
> language construct where you raise something and it goes into an err[] 
> array. At any time you can check to see what's in there. That would clean 
> up the code so much.
>
> result = doSomething()
> iferr {
>error = err.pop()
> }
>
> Isn't that so much more readable? 
>
> You could even create checkpoints
>
> raiseErrors()
> // from now on all errors are raised and the program halts
> do()
> some()
> tasks()
> collectErrors()
> // from now on program doesn't halt but err[] array is populated
> do()
> other()
> things()
> dealWithErrArray() // it's global so need to pass it in
> raiseErrors()
> // back to raising them.
>
> As I said none of these are particularly nice.  Elixir gives you both ways 
>
>
> def register({email, password}) do  
>   {:ok, pid} = Membership.connect()
>   sql = "select * from membership.register($1, $2);"
>
>   case Postgrex.Connection.query(pid, sql, [email, password]) do
> {:ok, res} ->
>   cols = res.columns
>   [first_row | _] = res.rows
>   [new_id, validation_token, auth_token, success, message] = first_row
>   {:ok, %RegistrationResult{
> success: success,
> message: message,
> new_id: new_id,
> authentication_token: auth_token,
> validation_token: validation_token
> }}
>
> {:error, err} -> {:error, err}
>   end
> end  
>
>
> try do
>   opts
>   |> Keyword.fetch!(:source_file)
>   |> File.read!
> rescue
>   e in KeyError -> IO.puts "missing :source_file option"
>   e in File.Error -> IO.puts "unable to read source file"
> end
>
> As somebody who has just started learning go I can't find any 
> justification for the insane amount of boilerplate go error handling 
> inflicts on the programmer.  Surely there is a a better way.
>
>
>
> On Wednesday, September 6, 2017 at 8:54:38 PM UTC+12, Henry wrote:
>>
>> I use what I would call as *error context*.
>>
>> Here is the simple definition of the *error context*:
>>
>> type ErrorContext interface {
>> ContainsError() bool
>> SetError(err error)
>> Error() error
>> }
>>
>> Here is how you would use it inside the error-prone function:
>>
>> func FragileFunction(ctx ErrorContext) {
>> if ctx.ContainsError() {
>> return
>> }
>>
>> //some processing ...
>> //if there is an error
>> ctx.SetError(errors.New("some error"))  
>> return
>> }
>>
>>
>> It allows you to do this:
>>
>> ctx := NewErrorContext()
>>
>> fridge := GetFridge(ctx)
>> egg := GetEgg(fridge, ctx) 
>> mixedEgg := MixAndSeason(egg, ctx)
>> friedEgg := Fry(mixedEgg, ctx)
>>
>> if ctx.ContainsError() {
>> fmt.Printf("failed to fry eggs: %s", ctx.Error().Error())
>> }
>>
>> Or you can even do this:
>>
>> ctxA := NewErrorContext()
>> ctxB := NewErrorContext()
>> ignored := NewErrorContext()
>>
>> a := DoSomethingOne(ctxA)
>> b := DoSomethingTwo(a, ctxA)
>> c,d := DoSomethingThree(b, ctxB) //different context
>> if ctxB.ContainsError() {
>>c = 1
>>d = 2
>> }
>> e := DoSomethingFour(c, d, ctxA)
>> if ctxA.ContainsError() {
>> fmt.Println("Failed To do A")
>> }
>>
>> DoSomething(e, ignored) //error is ignored
>>
>> It is up to you how you would implement the error context.
>>
>>
>> On Tuesday, September 5, 2017 at 1:27:20 AM UTC+7, 
>> marti...@programmfabrik.de wrote:
>>
>>> Hi guys,
>>>
>>> at first I though I really like the idea of how Go deals with error 
>>> management and handling, but the more Go code I look at or try to program, 
>>> the more I get scared about checking errors every second line in every 
>>> given block of code.
>>>
>>> Take a look at this example here from "Build Web Application with 
>>> Golang":
>>>
>>> // insert
>>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>>> created) values(?,?,?)")
>>> if err != nil {
>>>   // handle error
>>> }
>>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>>> if err != nil {
>

[go-nuts] Re: error handling needs syntactical sugar

2017-09-07 Thread Tim Uckun
Totally not a go programmer but here are my worthless two cents.



I don't see anything wrong with the try catch paradigm, you can choose your 
granularity. If you want to check every call then you can, if you want to 
let a few cluster together you can. You guys make is sound like go style 
error handling is the only way to catch errors at every step. That's not 
true at all.  

Surely something can be done about the boilerplate if err != nil  maybe 
shorten that to iferr or something like that. In fact why can't "err" be a 
language construct where you raise something and it goes into an err[] 
array. At any time you can check to see what's in there. That would clean 
up the code so much.

result = doSomething()
iferr {
   error = err.pop()
}

Isn't that so much more readable? 

You could even create checkpoints

raiseErrors()
// from now on all errors are raised and the program halts
do()
some()
tasks()
collectErrors()
// from now on program doesn't halt but err[] array is populated
do()
other()
things()
dealWithErrArray() // it's global so need to pass it in
raiseErrors()
// back to raising them.

As I said none of these are particularly nice.  Elixir gives you both ways 


def register({email, password}) do  
  {:ok, pid} = Membership.connect()
  sql = "select * from membership.register($1, $2);"

  case Postgrex.Connection.query(pid, sql, [email, password]) do
{:ok, res} ->
  cols = res.columns
  [first_row | _] = res.rows
  [new_id, validation_token, auth_token, success, message] = first_row
  {:ok, %RegistrationResult{
success: success,
message: message,
new_id: new_id,
authentication_token: auth_token,
validation_token: validation_token
}}

{:error, err} -> {:error, err}
  end
end  


try do
  opts
  |> Keyword.fetch!(:source_file)
  |> File.read!
rescue
  e in KeyError -> IO.puts "missing :source_file option"
  e in File.Error -> IO.puts "unable to read source file"
end

As somebody who has just started learning go I can't find any justification 
for the insane amount of boilerplate go error handling inflicts on the 
programmer.  Surely there is a a better way.



On Wednesday, September 6, 2017 at 8:54:38 PM UTC+12, Henry wrote:
>
> I use what I would call as *error context*.
>
> Here is the simple definition of the *error context*:
>
> type ErrorContext interface {
> ContainsError() bool
> SetError(err error)
> Error() error
> }
>
> Here is how you would use it inside the error-prone function:
>
> func FragileFunction(ctx ErrorContext) {
> if ctx.ContainsError() {
> return
> }
>
> //some processing ...
> //if there is an error
> ctx.SetError(errors.New("some error"))  
> return
> }
>
>
> It allows you to do this:
>
> ctx := NewErrorContext()
>
> fridge := GetFridge(ctx)
> egg := GetEgg(fridge, ctx) 
> mixedEgg := MixAndSeason(egg, ctx)
> friedEgg := Fry(mixedEgg, ctx)
>
> if ctx.ContainsError() {
> fmt.Printf("failed to fry eggs: %s", ctx.Error().Error())
> }
>
> Or you can even do this:
>
> ctxA := NewErrorContext()
> ctxB := NewErrorContext()
> ignored := NewErrorContext()
>
> a := DoSomethingOne(ctxA)
> b := DoSomethingTwo(a, ctxA)
> c,d := DoSomethingThree(b, ctxB) //different context
> if ctxB.ContainsError() {
>c = 1
>d = 2
> }
> e := DoSomethingFour(c, d, ctxA)
> if ctxA.ContainsError() {
> fmt.Println("Failed To do A")
> }
>
> DoSomething(e, ignored) //error is ignored
>
> It is up to you how you would implement the error context.
>
>
> On Tuesday, September 5, 2017 at 1:27:20 AM UTC+7, 
> marti...@programmfabrik.de wrote:
>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in lar

[go-nuts] Re: error handling needs syntactical sugar

2017-09-06 Thread Henry
I use what I would call as *error context*.

Here is the simple definition of the *error context*:

type ErrorContext interface {
ContainsError() bool
SetError(err error)
Error() error
}

Here is how you would use it inside the error-prone function:

func FragileFunction(ctx ErrorContext) {
if ctx.ContainsError() {
return
}

//some processing ...
//if there is an error
ctx.SetError(errors.New("some error"))  
return
}


It allows you to do this:

ctx := NewErrorContext()

fridge := GetFridge(ctx)
egg := GetEgg(fridge, ctx) 
mixedEgg := MixAndSeason(egg, ctx)
friedEgg := Fry(mixedEgg, ctx)

if ctx.ContainsError() {
fmt.Printf("failed to fry eggs: %s", ctx.Error().Error())
}

Or you can even do this:

ctxA := NewErrorContext()
ctxB := NewErrorContext()
ignored := NewErrorContext()

a := DoSomethingOne(ctxA)
b := DoSomethingTwo(a, ctxA)
c,d := DoSomethingThree(b, ctxB) //different context
if ctxB.ContainsError() {
   c = 1
   d = 2
}
e := DoSomethingFour(c, d, ctxA)
if ctxA.ContainsError() {
fmt.Println("Failed To do A")
}

DoSomething(e, ignored) //error is ignored

It is up to you how you would implement the error context.


On Tuesday, September 5, 2017 at 1:27:20 AM UTC+7, 
marti...@programmfabrik.de wrote:

> Hi guys,
>
> at first I though I really like the idea of how Go deals with error 
> management and handling, but the more Go code I look at or try to program, 
> the more I get scared about checking errors every second line in every 
> given block of code.
>
> Take a look at this example here from "Build Web Application with Golang":
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
> values(?,?,?)")
> if err != nil {
>   // handle error
> }
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> if err != nil {
>   // handle error
> }
> id, err := res.LastInsertId()
> if err != nil {
>   // handle error
> }
> fmt.Println(id)
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> if err != nil {
>   // handle error
> }
> res, err = stmt.Exec("astaxieupdate", id)
> if err != nil {
>   // handle error
> }
> affect, err := res.RowsAffected()
> if err != nil {
>   // handle error
> }
>
>
> Seriously? And yes, I have read https://blog.golang.org/errors-are-values.
> ..
>
> The best case reduction I found is:
>
> ...
> res, err = stmt.Exec("astaxieupdate", id)
> checkError(err)
> ...
>
> Still, I need this after each line of calling a function which may return 
> an error.
>
> I bet this is not pleasant to do in larger code bases and it also takes 
> away focus from what is actually happening.
>
> 50-80% of all lines of code in my example deal with error handling?
>
> This is not good. Seriously.
>
> And don't get me wrong, there is a lot of things I really like, love and 
> adore about Go, but catching errors needs an improved syntax!
>
> And I am not proposing try...catch here. 
>
> How about introducing a new piece of syntax 
>
> "watch if   " 
>
> which tells the compiler to watch out for changes in a given SimpleStmt
>
> The same code as above would look like this:
>
> var err Error
>
> watch if err != nil {
>   // handle error(s)
> }
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
> created) values(?,?,?)")
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> id, err := res.LastInsertId()
> fmt.Println(id)
>
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> res, err = stmt.Exec("astaxieupdate", id)
> affect, err := res.RowsAffected()
>
>
>- The "watch if" would be executed after each assignment of any of the 
>variables used in SimpleStmt of the statement.
>- Multiple "watch if" would be executed in order or appearance
>- The "watch if" could be used like "defer..." inside functions
>- The "watch if" would work in its full scope of the watched variables
>
> I am not a language expert, so may be there is a saner way of expression 
> what I want to achieve.
>
> But bottom line is, there should by an easier to read and write way to 
> deal with errors in Go.
>
>
> Martin
>
>
>
>
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Hi Michael,

I fully agree with handling each single error ("health issue") as they are 
discovered.

The idea of "watch" is NOT to replace this procedure.

It's just a "syntactic sugar" to do what you are doing already.

Cheers.
Dorival 

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Michael Jones
...Go is not perfect. But there is subtle magic in this error business.
Developers should look closely at errors. Imagine handling them as if you
were a doctor and the error was a child's symptom or a test result. Choices:

1. Ask them how they feel, ignore it. Do a test, ignore it. Effectively you
are saying "you are well" even if they're not breathing.

x, _ := ResultAndErr(a,b,c)


2. Ask them if they feel great and if all test results are normal. If not,
send them home.

x, err := ResultAndErr(a,b,c)
if err != nil {
return
}


3. Ask them if they feel great and if all test results are normal. If not,
send them to a hospital where they can talk to a real doctor.

x, err := ResultAndErr(a,b,c)
if err != nil {
log.Error(err, a,b,c) // or return err
}


4. Ask them how the feel and if not good, do tests. Then TREAT THEIR
CONDITION.


x, err := ResultAndErr(a,b,c)
if err ==FirstPossibleProblem {
// HANDLE error1 // reset power, wait, etc.
} else if err ==SecondPossibleProblem {
// HANDLE error2 // lower temperature, send text, start siren, ...
}
:


These four kinds of doctors closely parallel four kinds of programmers.

On Tue, Sep 5, 2017 at 3:47 PM, Dorival Pedroso  wrote:

> Since *defer* "is the last thing to happen", I think this code is all
> right:
>
> func something() (x int, err error) {
> watch err != nil {
> return
> }
> res, err = acquireResource()
> defer func() {
> if err == nil {
> err = res.Close()
> }
> }()
> err = abc1()
> err = abc2()
> err = abc3()
> err = abc4()
> }
>
> Also, I'd like to make a general comment (not specific to this case). The
> *watch* command doesn't seem (to me) a bad idea. And it could be used for
> other purposes too (e.g. as the "watch expression" feature in debuggers or
> for logging---yeah we don't really need it...).
>
> For instance:
>
> func calculations() {
> x := 100.0
> watch x < 0 {
> fmt.Printf("hey, x is negative (%d)\n", x)
> fmt.Printf("...no worries...\n")
> }
> x = compute(1,2,3)
> x = compute(3,2,1)
> x = compute(1,3,2)
> }
>
> It's of course NOT needed at all. Above, we can do the same thing in a
> different (probably better) way.
>
> In fact, *Go is perfect the way it is* and doesn't need any change at all!
>
> Also, the mechanics (implementation) of *watch* may be "impossible", "too
> hard", "confusing" or at least "inefficient"---I don't know (no idea...).
>
> With an opportunity to work on the Go language implementation, I would
> rather spend some time tweaking things to be faster...
>
> Cheers!
> Dorival
>
> On Wednesday, September 6, 2017 at 1:11:36 AM UTC+10, eko...@gmail.com
> wrote:
>
>> I've been doing something like this for long chains where "handle error"
>> is the same:
>>
>> func something() (x int, err error) {
>> defer func() {
>> if err != nil {
>> // handle error
>> }
>> }()
>> res, err = acquireResource()
>> if err == nil {
>> defer func() {
>> if e := res.Close(); err == nil {
>> err = e
>> }
>> }()
>> err = abc1()
>> }
>> if err == nil {
>> err = abc2()
>> }
>> if err == nil {
>> err = abc3()
>> }
>> if err == nil {
>> err = abc4()
>> }
>> }
>>
>> How would watch interact with defer?
>>
>> On Monday, September 4, 2017 at 8:27:20 PM UTC+2,
>> marti...@programmfabrik.de wrote:
>>>
>>> Hi guys,
>>>
>>> at first I though I really like the idea of how Go deals with error
>>> management and handling, but the more Go code I look at or try to program,
>>> the more I get scared about checking errors every second line in every
>>> given block of code.
>>>
>>> Take a look at this example here from "Build Web Application with
>>> Golang":
>>>
>>> // insert
>>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>>> created) values(?,?,?)")
>>> if err != nil {
>>>   // handle error
>>> }
>>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>>> if err != nil {
>>>   // handle error
>>> }
>>> id, err := res.LastInsertId()
>>> if err != nil {
>>>   // handle error
>>> }
>>> fmt.Println(id)
>>> // update
>>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>>> if err != nil {
>>>   // handle error
>>> }
>>> res, err = stmt.Exec("astaxieupdate", id)
>>> if err != nil {
>>>   // handle error
>>> }
>>> affect, err := res.RowsAffected()
>>> if err != nil {
>>>   // handle error
>>> }
>>>
>>>
>>> Seriously? And yes, I have read https://blog.golang.org/e
>>> rrors-are-values...
>>>
>>> The best case reduction I found is:
>>>
>>> ...
>>> res, err = stmt.Exec("astaxieupdate", id)
>>> checkError(err)
>>> ...
>>>
>>> Still, I need this after each line of calling a function which may
>>> return an error.
>>>
>>> I bet this is not pleasant to do in larger code bases and it also takes
>>> away focus from what is actually happenin

[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Since *defer* "is the last thing to happen", I think this code is all right:

func something() (x int, err error) {
watch err != nil {
return
}
res, err = acquireResource()
defer func() {
if err == nil {
err = res.Close()
}
}()
err = abc1()
err = abc2()
err = abc3()
err = abc4()
}

Also, I'd like to make a general comment (not specific to this case). The 
*watch* command doesn't seem (to me) a bad idea. And it could be used for 
other purposes too (e.g. as the "watch expression" feature in debuggers or 
for logging---yeah we don't really need it...).

For instance:

func calculations() {
x := 100.0
watch x < 0 {
fmt.Printf("hey, x is negative (%d)\n", x)
fmt.Printf("...no worries...\n")
}
x = compute(1,2,3)
x = compute(3,2,1)
x = compute(1,3,2)
}

It's of course NOT needed at all. Above, we can do the same thing in a 
different (probably better) way.

In fact, *Go is perfect the way it is* and doesn't need any change at all!

Also, the mechanics (implementation) of *watch* may be "impossible", "too 
hard", "confusing" or at least "inefficient"---I don't know (no idea...).

With an opportunity to work on the Go language implementation, I would 
rather spend some time tweaking things to be faster...

Cheers!
Dorival

On Wednesday, September 6, 2017 at 1:11:36 AM UTC+10, eko...@gmail.com 
wrote:
>
> I've been doing something like this for long chains where "handle error" 
> is the same:
>
> func something() (x int, err error) {
> defer func() {
> if err != nil {
> // handle error
> }
> }()
> res, err = acquireResource()
> if err == nil {
> defer func() {
> if e := res.Close(); err == nil {
> err = e
> }
> }()
> err = abc1()
> }
> if err == nil {
> err = abc2()
> }
> if err == nil {
> err = abc3()
> }
> if err == nil {
> err = abc4()
> }
> }
>
> How would watch interact with defer?
>
> On Monday, September 4, 2017 at 8:27:20 PM UTC+2, 
> marti...@programmfabrik.de wrote:
>>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in larger code bases and it also takes 
>> away focus from what is actually happening.
>>
>> 50-80% of all lines of code in my example deal with error handling?
>>
>> This is not good. Seriously.
>>
>> And don't get me wrong, there is a lot of things I really like, love and 
>> adore about Go, but catching errors needs an improved syntax!
>>
>> And I am not proposing try...catch here. 
>>
>> How about introducing a new piece of syntax 
>>
>> "watch if   " 
>>
>> which tells the compiler to watch out for changes in a given SimpleStmt
>>
>> The same code as above would look like this:
>>
>> var err Error
>>
>> watch if err != nil {
>>   // handle error(s)
>> }
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>> created) values(?,?,?)")
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> id, err := res.LastInsertId()
>> fmt.Println(id)
>>
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> res, err = stmt.Exec("astaxieupdate", id)
>> affect, err := res.RowsAffected()
>>
>>
>>- The "watch if" would be executed after each assignment of any of 
>>the variables used in SimpleStmt of the statement.
>>- Multiple "watch if" would be executed in order or appearance
>>- The "watch if" could be used like "defer..." inside functions
>>- The "watch if" would work in its full scope of the watched variables
>>
>> I am not a language expert, so may be there

[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Hi, yes we need the check condition you had before in defer. That seems fine. 
But there may be some other problems I haven't thought of. Cheers 

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
What about?

func something() (x int, err error) {
watch err != nil { // this is only required to watch out in case "err" 
ever becomes non-nil
return // the error will propagate outside (same as "return err")
}
res, err = acquireResource() // will return straightway (because we 
cannot close the resource...)
defer func() {
e := res.Close()
return 0, e
}()
err = abc1() // if err != nil, the "watcher" would return right here 
with the most recent error (message)
err = abc2() // This seems better than "accumulating" the error in 
an internal data structure
err = abc3() // because abc2() and so on wouldn't even work if 
abc1() had failed
err = abc4() // But of course, another err1, err2, ... could be 
used instead
}

(Again, just an idea...)
Cheers!

On Wednesday, September 6, 2017 at 1:11:36 AM UTC+10, eko...@gmail.com 
wrote:
>
> I've been doing something like this for long chains where "handle error" 
> is the same:
>
> func something() (x int, err error) {
> defer func() {
> if err != nil {
> // handle error
> }
> }()
> res, err = acquireResource()
> if err == nil {
> defer func() {
> if e := res.Close(); err == nil {
> err = e
> }
> }()
> err = abc1()
> }
> if err == nil {
> err = abc2()
> }
> if err == nil {
> err = abc3()
> }
> if err == nil {
> err = abc4()
> }
> }
>
> How would watch interact with defer?
>
> On Monday, September 4, 2017 at 8:27:20 PM UTC+2, 
> marti...@programmfabrik.de wrote:
>>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in larger code bases and it also takes 
>> away focus from what is actually happening.
>>
>> 50-80% of all lines of code in my example deal with error handling?
>>
>> This is not good. Seriously.
>>
>> And don't get me wrong, there is a lot of things I really like, love and 
>> adore about Go, but catching errors needs an improved syntax!
>>
>> And I am not proposing try...catch here. 
>>
>> How about introducing a new piece of syntax 
>>
>> "watch if   " 
>>
>> which tells the compiler to watch out for changes in a given SimpleStmt
>>
>> The same code as above would look like this:
>>
>> var err Error
>>
>> watch if err != nil {
>>   // handle error(s)
>> }
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>> created) values(?,?,?)")
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> id, err := res.LastInsertId()
>> fmt.Println(id)
>>
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> res, err = stmt.Exec("astaxieupdate", id)
>> affect, err := res.RowsAffected()
>>
>>
>>- The "watch if" would be executed after each assignment of any of 
>>the variables used in SimpleStmt of the statement.
>>- Multiple "watch if" would be executed in order or appearance
>>- The "watch if" could be used like "defer..." inside functions
>>- The "watch if" would work in its full scope of the watched variables
>>
>> I am not a language expert, so may be there is a saner way of expression 
>> what I want to achieve.
>>
>> But bottom line is, there should by an easier to read and write way to 
>> deal with errors in Go.
>>
>>
>> Martin
>>
>>
>>
>>
>>
>>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
What about the following?

func something() (x int, err error) {
watch err != nil { // this is only required to watch out in case "err" 
ever becomes non-nil
return // the error will propagate outside (same as "return err")
}
res, err = acquireResource() // will return straightway (because we 
cannot close the resource...)
defer func() {
e := res.Close() // if err != nil, the "watcher" would return the 
message
return 0, e
}()
err = abc1() // if err != nil, the "watcher" would return right here 
with the most recent error (message)
err = abc2() // This seems better than "accumulating" the error in 
an internal data structure
err = abc3() // because abc2() and so on wouldn't even work if 
abc1() had failed
err = abc4() // But of course, another err1, err2, ... could be 
used instead
}

(again, just an idea...)
Cheers!


On Wednesday, September 6, 2017 at 1:11:36 AM UTC+10, eko...@gmail.com 
wrote:
>
> I've been doing something like this for long chains where "handle error" 
> is the same:
>
> func something() (x int, err error) {
> defer func() {
> if err != nil {
> // handle error
> }
> }()
> res, err = acquireResource()
> if err == nil {
> defer func() {
> if e := res.Close(); err == nil {
> err = e
> }
> }()
> err = abc1()
> }
> if err == nil {
> err = abc2()
> }
> if err == nil {
> err = abc3()
> }
> if err == nil {
> err = abc4()
> }
> }
>
> How would watch interact with defer?
>
> On Monday, September 4, 2017 at 8:27:20 PM UTC+2, 
> marti...@programmfabrik.de wrote:
>>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in larger code bases and it also takes 
>> away focus from what is actually happening.
>>
>> 50-80% of all lines of code in my example deal with error handling?
>>
>> This is not good. Seriously.
>>
>> And don't get me wrong, there is a lot of things I really like, love and 
>> adore about Go, but catching errors needs an improved syntax!
>>
>> And I am not proposing try...catch here. 
>>
>> How about introducing a new piece of syntax 
>>
>> "watch if   " 
>>
>> which tells the compiler to watch out for changes in a given SimpleStmt
>>
>> The same code as above would look like this:
>>
>> var err Error
>>
>> watch if err != nil {
>>   // handle error(s)
>> }
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>> created) values(?,?,?)")
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> id, err := res.LastInsertId()
>> fmt.Println(id)
>>
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> res, err = stmt.Exec("astaxieupdate", id)
>> affect, err := res.RowsAffected()
>>
>>
>>- The "watch if" would be executed after each assignment of any of 
>>the variables used in SimpleStmt of the statement.
>>- Multiple "watch if" would be executed in order or appearance
>>- The "watch if" could be used like "defer..." inside functions
>>- The "watch if" would work in its full scope of the watched variables
>>
>> I am not a language expert, so may be there is a saner way of expression 
>> what I want to achieve.
>>
>> But bottom line is, there should by an easier to read and write way to 
>> deal with errors in Go.
>>
>>
>> Martin
>>
>>
>>
>>
>>
>>

-- 
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.
For more options, vi

[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
What about the following?

func something() (x int, err error) {
watch err != nil { // this is only required to watch out in case "err" 
ever becomes non-nil
return // the error will propagate outside (same as "return err")
}
res, err = acquireResource() // will return straightway? (because we 
cannot close the
 // resource...)
defer func() {
e := res.Close() // if err != nil, the "watcher" would return the 
message
return 0, e
}()
err = abc1() // if err != nil, the "watcher" would return right here 
with the most recent error (message)
err = abc2() // This seems better than "accumulating" the error in 
an internal data structure
err = abc3() // because abc2() and so on wouldn't even work if 
abc1() had failed
err = abc4() // But of course, another err1, err2, ... could be 
used instead
}

There might be something wrong in the code above (sorry)... don't know...
Again...just an idea...
Cheers.
Dorival



On Wednesday, September 6, 2017 at 1:11:36 AM UTC+10, eko...@gmail.com 
wrote:
>
> I've been doing something like this for long chains where "handle error" 
> is the same:
>
> func something() (x int, err error) {
> defer func() {
> if err != nil {
> // handle error
> }
> }()
> res, err = acquireResource()
> if err == nil {
> defer func() {
> if e := res.Close(); err == nil {
> err = e
> }
> }()
> err = abc1()
> }
> if err == nil {
> err = abc2()
> }
> if err == nil {
> err = abc3()
> }
> if err == nil {
> err = abc4()
> }
> }
>
> How would watch interact with defer?
>
> On Monday, September 4, 2017 at 8:27:20 PM UTC+2, 
> marti...@programmfabrik.de wrote:
>>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in larger code bases and it also takes 
>> away focus from what is actually happening.
>>
>> 50-80% of all lines of code in my example deal with error handling?
>>
>> This is not good. Seriously.
>>
>> And don't get me wrong, there is a lot of things I really like, love and 
>> adore about Go, but catching errors needs an improved syntax!
>>
>> And I am not proposing try...catch here. 
>>
>> How about introducing a new piece of syntax 
>>
>> "watch if   " 
>>
>> which tells the compiler to watch out for changes in a given SimpleStmt
>>
>> The same code as above would look like this:
>>
>> var err Error
>>
>> watch if err != nil {
>>   // handle error(s)
>> }
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>> created) values(?,?,?)")
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> id, err := res.LastInsertId()
>> fmt.Println(id)
>>
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> res, err = stmt.Exec("astaxieupdate", id)
>> affect, err := res.RowsAffected()
>>
>>
>>- The "watch if" would be executed after each assignment of any of 
>>the variables used in SimpleStmt of the statement.
>>- Multiple "watch if" would be executed in order or appearance
>>- The "watch if" could be used like "defer..." inside functions
>>- The "watch if" would work in its full scope of the watched variables
>>
>> I am not a language expert, so may be there is a saner way of expression 
>> what I want to achieve.
>>
>> But bottom line is, there should by an easier to read and write way to 
>> deal with errors in Go.
>>
>>
>> Martin
>>
>>
>>
>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from thi

[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread ekocjan
I've been doing something like this for long chains where "handle error" is 
the same:

func something() (x int, err error) {
defer func() {
if err != nil {
// handle error
}
}()
res, err = acquireResource()
if err == nil {
defer func() {
if e := res.Close(); err == nil {
err = e
}
}()
err = abc1()
}
if err == nil {
err = abc2()
}
if err == nil {
err = abc3()
}
if err == nil {
err = abc4()
}
}

How would watch interact with defer?

On Monday, September 4, 2017 at 8:27:20 PM UTC+2, 
marti...@programmfabrik.de wrote:
>
> Hi guys,
>
> at first I though I really like the idea of how Go deals with error 
> management and handling, but the more Go code I look at or try to program, 
> the more I get scared about checking errors every second line in every 
> given block of code.
>
> Take a look at this example here from "Build Web Application with Golang":
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
> values(?,?,?)")
> if err != nil {
>   // handle error
> }
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> if err != nil {
>   // handle error
> }
> id, err := res.LastInsertId()
> if err != nil {
>   // handle error
> }
> fmt.Println(id)
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> if err != nil {
>   // handle error
> }
> res, err = stmt.Exec("astaxieupdate", id)
> if err != nil {
>   // handle error
> }
> affect, err := res.RowsAffected()
> if err != nil {
>   // handle error
> }
>
>
> Seriously? And yes, I have read https://blog.golang.org/errors-are-values.
> ..
>
> The best case reduction I found is:
>
> ...
> res, err = stmt.Exec("astaxieupdate", id)
> checkError(err)
> ...
>
> Still, I need this after each line of calling a function which may return 
> an error.
>
> I bet this is not pleasant to do in larger code bases and it also takes 
> away focus from what is actually happening.
>
> 50-80% of all lines of code in my example deal with error handling?
>
> This is not good. Seriously.
>
> And don't get me wrong, there is a lot of things I really like, love and 
> adore about Go, but catching errors needs an improved syntax!
>
> And I am not proposing try...catch here. 
>
> How about introducing a new piece of syntax 
>
> "watch if   " 
>
> which tells the compiler to watch out for changes in a given SimpleStmt
>
> The same code as above would look like this:
>
> var err Error
>
> watch if err != nil {
>   // handle error(s)
> }
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
> created) values(?,?,?)")
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> id, err := res.LastInsertId()
> fmt.Println(id)
>
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> res, err = stmt.Exec("astaxieupdate", id)
> affect, err := res.RowsAffected()
>
>
>- The "watch if" would be executed after each assignment of any of the 
>variables used in SimpleStmt of the statement.
>- Multiple "watch if" would be executed in order or appearance
>- The "watch if" could be used like "defer..." inside functions
>- The "watch if" would work in its full scope of the watched variables
>
> I am not a language expert, so may be there is a saner way of expression 
> what I want to achieve.
>
> But bottom line is, there should by an easier to read and write way to 
> deal with errors in Go.
>
>
> Martin
>
>
>
>
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread prades . marq
Or you know, just panic ... errors as value are a convention, not a 
language construct.

panic/defer ARE a language construct. I personally give the choice in my 
API, Must prefixed methods that panic or regular methods that return an 
error.
The obvious advantage of panics is that the developer actually gets a stack 
trace for free, not need for 50 different packages  that wrap errors just 
to get a stack trace.



Le mardi 5 septembre 2017 11:17:13 UTC+2, Dorival Pedroso a écrit :
>
> Thanks again, Rob.
>
> The blog post (https://blog.golang.org/errors-are-values) does shed some 
> light.
>
> One of the ideas is to hold the *err* variable in a structure. I will 
> definitively use this more often (I do have many structures and never 
> thought of doing this!)---Thanks!
>
> The other idea is to create a wrapping structure (e.g. type errWriter struct 
> {w io.Writer; err error}) just to keep hold of the *err* variable. In 
> this case, I'd prefer to return *err* in my "pure function" (I also have 
> many of those; e.g. for "mathematical computations"). In this case, I 
> actually don't mind returning and checking the err variable as long as I 
> don't need the wrapper.
>
> Now, this piece of code:
>
> ew := &errWriter{w: fd}
> ew.write(p0[a:b])
> ew.write(p1[c:d])
> ew.write(p2[e:f])
> // and so on
> if ew.err != nil {
> return ew.err
> }
>
>
> could easily (?, I don't know) be replaced by:
>
> *watch* err != nil {
>
> return err
>
> }
> err = fd.write(p0[a:b])
> err = fd.write(p1[c:d])
> err = fd.write(p2[e:f])
> // and so on
>
>
> and we wouldn't need the wrapping structure... (sorry for being so lazy ;-)
>
> By the way, maybe one day I'll attend a GoCon and will bring a laptop for 
> sure...
>
> Cheers.
> Dorival
>
>
> On Tuesday, September 5, 2017 at 6:39:05 PM UTC+10, Rob 'Commander' Pike 
> wrote:
>>
>> If you find that lines like if err != nil are a significant fraction 
>> of non-test code, your code probably needs a better error handling 
>> strategy, not a language change. I have done measurements in the past 
>> and although people complain a lot about the presence of that 
>> statement, it shows up much less often in practice than people claim, 
>> and when it does appear a lot it's usually because the programmer is 
>> not thinking enough about how errors should work. 
>>
>> Please reread that blog post. 
>>
>> -rob 
>>
>>
>> On Tue, Sep 5, 2017 at 5:45 PM, Dorival Pedroso  
>> wrote: 
>> > Fair enough. This would be perfect. Cheers 
>> > 
>> > 
>> > On Tuesday, September 5, 2017 at 5:42:26 PM UTC+10, 
>> > marti...@programmfabrik.de wrote: 
>> >> 
>> >> Dorival, 
>> >> 
>> >> I think we can celebrate already if we achieve anything with this 
>> >> discussion. Let's not ask for too much, plus let's not make it too 
>> >> complicated. 
>> >> 
>> >> I think your proposed "watch err", hides too much and does too little. 
>> >> 
>> >> You can simply write (the inline code editor is broken, BTW) 
>> >> 
>> >> func ... { 
>> >> var err 
>> >> watch err != nil { 
>> >> // handle error 
>> >> return 
>> >> } 
>> >> // do stuff 
>> >> yo1, err := do_stuff1() 
>> >> yo2, err := do_stuff2() 
>> >> yo3, err := do_stuff3() 
>> >> } 
>> >> 
>> >> 
>> >> Martin 
>> >> 
>> >> 
>> >> On Tuesday, September 5, 2017 at 9:32:50 AM UTC+2, Dorival Pedroso 
>> wrote: 
>> >>> 
>> >>> Hi Martin; 
>> >>> 
>> >>> What about two commands "watch" and "watchif"? 
>> >>> 
>> >>> The first works as the "var" command and the second as the "if" 
>> command. 
>> >>> 
>> >>> "watch" does: 
>> >>> 
>> >>> In a function with error as an output (anywhere): returns in case the 
>> err 
>> >>> declared with watch err (or watch myerror) becomes non-nil. watch err 
>> would 
>> >>> declare err" as var does. Most use cases would put watch err at the 
>> >>> beginning of a function (although this is optional as it is with 
>> defer) 
>> >>> In a test function; aka TestSomething(something *testing.T), watch 
>> err 
>> >>> error would declare err (or watch myerror error) and if an error 
>> occurs, it 
>> >>> would call something.FailNow() after (printing the error 
>> message?---still 
>> >>> need to think this part better) 
>> >>> In the main function: watch err error would print the error message 
>> (or 
>> >>> maybe pipe to stderr) and os.Exist(1) 
>> >>> watchif err != nil {HERE} would be more powerful because it would 
>> allow 
>> >>> us to do other things. But the mechanism is similar (as you proposed 
>> >>> initially): if err becomes non-nil anywhere, the execution in HERE 
>> would 
>> >>> take place. 
>> >>> 
>> >>> Cheers! 
>> >>> 
>> >>> 
>> >>> On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10, 
>> >>> marti...@programmfabrik.de wrote: 
>>  
>>  Hi Dorival, 
>>  
>>  thanks for supporting me with my idea. 
>>  
>>  And yes, after writing my post yesterday I was thinking, "watchif" 
>> or 
>>  even simply "watch". 
>>  
>>  And yes, today I am more in favor of simply "watch". 
>>

Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Thanks again, Rob.

The blog post (https://blog.golang.org/errors-are-values) does shed some 
light.

One of the ideas is to hold the *err* variable in a structure. I will 
definitively use this more often (I do have many structures and never 
thought of doing this!)---Thanks!

The other idea is to create a wrapping structure (e.g. type errWriter struct 
{w io.Writer; err error}) just to keep hold of the *err* variable. In this 
case, I'd prefer to return *err* in my "pure function" (I also have many of 
those; e.g. for "mathematical computations"). In this case, I actually 
don't mind returning and checking the err variable as long as I don't need 
the wrapper.

Now, this piece of code:

ew := &errWriter{w: fd}
ew.write(p0[a:b])
ew.write(p1[c:d])
ew.write(p2[e:f])
// and so on
if ew.err != nil {
return ew.err
}


could easily (?, I don't know) be replaced by:

*watch* err != nil {

return err

}
err = fd.write(p0[a:b])
err = fd.write(p1[c:d])
err = fd.write(p2[e:f])
// and so on


and we wouldn't need the wrapping structure... (sorry for being so lazy ;-)

By the way, maybe one day I'll attend a GoCon and will bring a laptop for 
sure...

Cheers.
Dorival


On Tuesday, September 5, 2017 at 6:39:05 PM UTC+10, Rob 'Commander' Pike 
wrote:
>
> If you find that lines like if err != nil are a significant fraction 
> of non-test code, your code probably needs a better error handling 
> strategy, not a language change. I have done measurements in the past 
> and although people complain a lot about the presence of that 
> statement, it shows up much less often in practice than people claim, 
> and when it does appear a lot it's usually because the programmer is 
> not thinking enough about how errors should work. 
>
> Please reread that blog post. 
>
> -rob 
>
>
> On Tue, Sep 5, 2017 at 5:45 PM, Dorival Pedroso  > wrote: 
> > Fair enough. This would be perfect. Cheers 
> > 
> > 
> > On Tuesday, September 5, 2017 at 5:42:26 PM UTC+10, 
> > marti...@programmfabrik.de wrote: 
> >> 
> >> Dorival, 
> >> 
> >> I think we can celebrate already if we achieve anything with this 
> >> discussion. Let's not ask for too much, plus let's not make it too 
> >> complicated. 
> >> 
> >> I think your proposed "watch err", hides too much and does too little. 
> >> 
> >> You can simply write (the inline code editor is broken, BTW) 
> >> 
> >> func ... { 
> >> var err 
> >> watch err != nil { 
> >> // handle error 
> >> return 
> >> } 
> >> // do stuff 
> >> yo1, err := do_stuff1() 
> >> yo2, err := do_stuff2() 
> >> yo3, err := do_stuff3() 
> >> } 
> >> 
> >> 
> >> Martin 
> >> 
> >> 
> >> On Tuesday, September 5, 2017 at 9:32:50 AM UTC+2, Dorival Pedroso 
> wrote: 
> >>> 
> >>> Hi Martin; 
> >>> 
> >>> What about two commands "watch" and "watchif"? 
> >>> 
> >>> The first works as the "var" command and the second as the "if" 
> command. 
> >>> 
> >>> "watch" does: 
> >>> 
> >>> In a function with error as an output (anywhere): returns in case the 
> err 
> >>> declared with watch err (or watch myerror) becomes non-nil. watch err 
> would 
> >>> declare err" as var does. Most use cases would put watch err at the 
> >>> beginning of a function (although this is optional as it is with 
> defer) 
> >>> In a test function; aka TestSomething(something *testing.T), watch err 
> >>> error would declare err (or watch myerror error) and if an error 
> occurs, it 
> >>> would call something.FailNow() after (printing the error 
> message?---still 
> >>> need to think this part better) 
> >>> In the main function: watch err error would print the error message 
> (or 
> >>> maybe pipe to stderr) and os.Exist(1) 
> >>> watchif err != nil {HERE} would be more powerful because it would 
> allow 
> >>> us to do other things. But the mechanism is similar (as you proposed 
> >>> initially): if err becomes non-nil anywhere, the execution in HERE 
> would 
> >>> take place. 
> >>> 
> >>> Cheers! 
> >>> 
> >>> 
> >>> On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10, 
> >>> marti...@programmfabrik.de wrote: 
>  
>  Hi Dorival, 
>  
>  thanks for supporting me with my idea. 
>  
>  And yes, after writing my post yesterday I was thinking, "watchif" or 
>  even simply "watch". 
>  
>  And yes, today I am more in favor of simply "watch". 
>  
>  And yes, we can constrain this to the context of one function (like 
>  defer), I am ok with that. 
>  
>  What you are describing how you work with errors and how you spent 
> hours 
>  adding 
>  
>  if err != nil 
>  
>  that is exactly my point. 
>  
>  On could nicely write this 
>  
>  ... 
>  watch err!=nil { 
>    handle_sql_error(err) 
>  } 
>  ... 
>  
>  Of course, watch could also be used to not watch out for errors but 
> any 
>  other places where new values to get assigned to variables. 
>  
>  Martin 
> >> 
> >> 
> > -- 
> > You received this message because

Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Exactly: a good amount of "if err != nil" appears in my tests (334 out of 
569). I'll try to re-think the other cases... 
(e.g. https://github.com/cpmech/gosl/blob/master/la/blas2.go)

No complaints here, by the way! Just enjoying this marvellous language!

I'll read the blog post.
Cheers.

On Tuesday, September 5, 2017 at 6:39:05 PM UTC+10, Rob 'Commander' Pike 
wrote:
>
> If you find that lines like if err != nil are a significant fraction 
> of non-test code, your code probably needs a better error handling 
> strategy, not a language change. I have done measurements in the past 
> and although people complain a lot about the presence of that 
> statement, it shows up much less often in practice than people claim, 
> and when it does appear a lot it's usually because the programmer is 
> not thinking enough about how errors should work. 
>
> Please reread that blog post. 
>
> -rob 
>
>
> On Tue, Sep 5, 2017 at 5:45 PM, Dorival Pedroso  > wrote: 
> > Fair enough. This would be perfect. Cheers 
> > 
> > 
> > On Tuesday, September 5, 2017 at 5:42:26 PM UTC+10, 
> > marti...@programmfabrik.de wrote: 
> >> 
> >> Dorival, 
> >> 
> >> I think we can celebrate already if we achieve anything with this 
> >> discussion. Let's not ask for too much, plus let's not make it too 
> >> complicated. 
> >> 
> >> I think your proposed "watch err", hides too much and does too little. 
> >> 
> >> You can simply write (the inline code editor is broken, BTW) 
> >> 
> >> func ... { 
> >> var err 
> >> watch err != nil { 
> >> // handle error 
> >> return 
> >> } 
> >> // do stuff 
> >> yo1, err := do_stuff1() 
> >> yo2, err := do_stuff2() 
> >> yo3, err := do_stuff3() 
> >> } 
> >> 
> >> 
> >> Martin 
> >> 
> >> 
> >> On Tuesday, September 5, 2017 at 9:32:50 AM UTC+2, Dorival Pedroso 
> wrote: 
> >>> 
> >>> Hi Martin; 
> >>> 
> >>> What about two commands "watch" and "watchif"? 
> >>> 
> >>> The first works as the "var" command and the second as the "if" 
> command. 
> >>> 
> >>> "watch" does: 
> >>> 
> >>> In a function with error as an output (anywhere): returns in case the 
> err 
> >>> declared with watch err (or watch myerror) becomes non-nil. watch err 
> would 
> >>> declare err" as var does. Most use cases would put watch err at the 
> >>> beginning of a function (although this is optional as it is with 
> defer) 
> >>> In a test function; aka TestSomething(something *testing.T), watch err 
> >>> error would declare err (or watch myerror error) and if an error 
> occurs, it 
> >>> would call something.FailNow() after (printing the error 
> message?---still 
> >>> need to think this part better) 
> >>> In the main function: watch err error would print the error message 
> (or 
> >>> maybe pipe to stderr) and os.Exist(1) 
> >>> watchif err != nil {HERE} would be more powerful because it would 
> allow 
> >>> us to do other things. But the mechanism is similar (as you proposed 
> >>> initially): if err becomes non-nil anywhere, the execution in HERE 
> would 
> >>> take place. 
> >>> 
> >>> Cheers! 
> >>> 
> >>> 
> >>> On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10, 
> >>> marti...@programmfabrik.de wrote: 
>  
>  Hi Dorival, 
>  
>  thanks for supporting me with my idea. 
>  
>  And yes, after writing my post yesterday I was thinking, "watchif" or 
>  even simply "watch". 
>  
>  And yes, today I am more in favor of simply "watch". 
>  
>  And yes, we can constrain this to the context of one function (like 
>  defer), I am ok with that. 
>  
>  What you are describing how you work with errors and how you spent 
> hours 
>  adding 
>  
>  if err != nil 
>  
>  that is exactly my point. 
>  
>  On could nicely write this 
>  
>  ... 
>  watch err!=nil { 
>    handle_sql_error(err) 
>  } 
>  ... 
>  
>  Of course, watch could also be used to not watch out for errors but 
> any 
>  other places where new values to get assigned to variables. 
>  
>  Martin 
> >> 
> >> 
> > -- 
> > 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...@googlegroups.com . 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


Re: [go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Rob Pike
If you find that lines like if err != nil are a significant fraction
of non-test code, your code probably needs a better error handling
strategy, not a language change. I have done measurements in the past
and although people complain a lot about the presence of that
statement, it shows up much less often in practice than people claim,
and when it does appear a lot it's usually because the programmer is
not thinking enough about how errors should work.

Please reread that blog post.

-rob


On Tue, Sep 5, 2017 at 5:45 PM, Dorival Pedroso  wrote:
> Fair enough. This would be perfect. Cheers
>
>
> On Tuesday, September 5, 2017 at 5:42:26 PM UTC+10,
> marti...@programmfabrik.de wrote:
>>
>> Dorival,
>>
>> I think we can celebrate already if we achieve anything with this
>> discussion. Let's not ask for too much, plus let's not make it too
>> complicated.
>>
>> I think your proposed "watch err", hides too much and does too little.
>>
>> You can simply write (the inline code editor is broken, BTW)
>>
>> func ... {
>> var err
>> watch err != nil {
>> // handle error
>> return
>> }
>> // do stuff
>> yo1, err := do_stuff1()
>> yo2, err := do_stuff2()
>> yo3, err := do_stuff3()
>> }
>>
>>
>> Martin
>>
>>
>> On Tuesday, September 5, 2017 at 9:32:50 AM UTC+2, Dorival Pedroso wrote:
>>>
>>> Hi Martin;
>>>
>>> What about two commands "watch" and "watchif"?
>>>
>>> The first works as the "var" command and the second as the "if" command.
>>>
>>> "watch" does:
>>>
>>> In a function with error as an output (anywhere): returns in case the err
>>> declared with watch err (or watch myerror) becomes non-nil. watch err would
>>> declare err" as var does. Most use cases would put watch err at the
>>> beginning of a function (although this is optional as it is with defer)
>>> In a test function; aka TestSomething(something *testing.T), watch err
>>> error would declare err (or watch myerror error) and if an error occurs, it
>>> would call something.FailNow() after (printing the error message?---still
>>> need to think this part better)
>>> In the main function: watch err error would print the error message (or
>>> maybe pipe to stderr) and os.Exist(1)
>>> watchif err != nil {HERE} would be more powerful because it would allow
>>> us to do other things. But the mechanism is similar (as you proposed
>>> initially): if err becomes non-nil anywhere, the execution in HERE would
>>> take place.
>>>
>>> Cheers!
>>>
>>>
>>> On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10,
>>> marti...@programmfabrik.de wrote:

 Hi Dorival,

 thanks for supporting me with my idea.

 And yes, after writing my post yesterday I was thinking, "watchif" or
 even simply "watch".

 And yes, today I am more in favor of simply "watch".

 And yes, we can constrain this to the context of one function (like
 defer), I am ok with that.

 What you are describing how you work with errors and how you spent hours
 adding

 if err != nil

 that is exactly my point.

 On could nicely write this

 ...
 watch err!=nil {
   handle_sql_error(err)
 }
 ...

 Of course, watch could also be used to not watch out for errors but any
 other places where new values to get assigned to variables.

 Martin
>>
>>
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Fair enough. This would be perfect. Cheers

On Tuesday, September 5, 2017 at 5:42:26 PM UTC+10, 
marti...@programmfabrik.de wrote:
>
> Dorival,
>
> I think we can celebrate already if we achieve anything with this 
> discussion. Let's not ask for too much, plus let's not make it too 
> complicated.
>
> I think your proposed "watch err", hides too much and does too little.
>
> You can simply write (the inline code editor is broken, BTW)
>
> func ... {
> var err
> watch err != nil {
> // handle error
> return
> }
> // do stuff
> yo1, err := do_stuff1()
> yo2, err := do_stuff2()
> yo3, err := do_stuff3()
> }
>
>
> Martin
>
>
> On Tuesday, September 5, 2017 at 9:32:50 AM UTC+2, Dorival Pedroso wrote:
>>
>> Hi Martin;
>>
>> What about two commands "*watch*" and "*watchif*"?
>>
>> The first works as the "*var*" command and the second as the "*if*" 
>> command.
>>
>> "*watch*" does:
>>
>>1. In a function with *error* as an output (anywhere): returns in 
>>case the *err* declared with *watch err* (or *watch myerror*) becomes 
>>non-nil. *watch err* would declare *err*" as *var* does. Most use 
>>cases would put *watch err* at the beginning of a function (although 
>>this is optional as it is with *defer*)
>>2. In a test function; aka TestSomething(something *testing.T), *watch 
>>err error* would declare *err* (or *watch myerror error*) and if an 
>>error occurs, it would call something.FailNow() after (printing the error 
>>message?---still need to think this part better)
>>3. In the main function: *watch err error* would print the error 
>>message (or maybe pipe to stderr) and os.Exist(1)
>>4. *watchif err != nil {HERE}* would be more powerful because it 
>>would allow us to do other things. But the mechanism is similar (as you 
>>proposed initially): if *err* becomes non-nil anywhere, the execution 
>>in *HERE* would take place.
>>
>> Cheers!
>>
>>
>> On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10, 
>> marti...@programmfabrik.de wrote:
>>>
>>> Hi Dorival,
>>>
>>> thanks for supporting me with my idea.
>>>
>>> And yes, after writing my post yesterday I was thinking, "watchif" or 
>>> even simply "watch".
>>>
>>> And yes, today I am more in favor of simply *"watch"*.
>>>
>>> And yes, we can constrain this to the context of one function (like 
>>> defer), I am ok with that. 
>>>
>>> What you are describing how you work with errors and how you spent hours 
>>> adding 
>>>
>>> *if err != nil*
>>>
>>> that is *exactly* my point.
>>>
>>> On could nicely write this
>>>
>>> ...
>>> watch err!=nil {
>>>   handle_sql_error(err)
>>> }
>>> ...
>>>
>>> Of course, watch could also be used to not watch out for errors but any 
>>> other places where new values to get assigned to variables.
>>>
>>> Martin
>>>

>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread martin . rode
Dorival,

I think we can celebrate already if we achieve anything with this 
discussion. Let's not ask for too much, plus let's not make it too 
complicated.

I think your proposed "watch err", hides too much and does too little.

You can simply write (the inline code editor is broken, BTW)

func ... {
var err
watch err != nil {
// handle error
return
}
// do stuff
yo1, err := do_stuff1()
yo2, err := do_stuff2()
yo3, err := do_stuff3()
}


Martin


On Tuesday, September 5, 2017 at 9:32:50 AM UTC+2, Dorival Pedroso wrote:
>
> Hi Martin;
>
> What about two commands "*watch*" and "*watchif*"?
>
> The first works as the "*var*" command and the second as the "*if*" 
> command.
>
> "*watch*" does:
>
>1. In a function with *error* as an output (anywhere): returns in case 
>the *err* declared with *watch err* (or *watch myerror*) becomes 
>non-nil. *watch err* would declare *err*" as *var* does. Most use 
>cases would put *watch err* at the beginning of a function (although 
>this is optional as it is with *defer*)
>2. In a test function; aka TestSomething(something *testing.T), *watch 
>err error* would declare *err* (or *watch myerror error*) and if an 
>error occurs, it would call something.FailNow() after (printing the error 
>message?---still need to think this part better)
>3. In the main function: *watch err error* would print the error 
>message (or maybe pipe to stderr) and os.Exist(1)
>4. *watchif err != nil {HERE}* would be more powerful because it would 
>allow us to do other things. But the mechanism is similar (as you proposed 
>initially): if *err* becomes non-nil anywhere, the execution in *HERE* 
>would take place.
>
> Cheers!
>
>
> On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10, 
> marti...@programmfabrik.de wrote:
>>
>> Hi Dorival,
>>
>> thanks for supporting me with my idea.
>>
>> And yes, after writing my post yesterday I was thinking, "watchif" or 
>> even simply "watch".
>>
>> And yes, today I am more in favor of simply *"watch"*.
>>
>> And yes, we can constrain this to the context of one function (like 
>> defer), I am ok with that. 
>>
>> What you are describing how you work with errors and how you spent hours 
>> adding 
>>
>> *if err != nil*
>>
>> that is *exactly* my point.
>>
>> On could nicely write this
>>
>> ...
>> watch err!=nil {
>>   handle_sql_error(err)
>> }
>> ...
>>
>> Of course, watch could also be used to not watch out for errors but any 
>> other places where new values to get assigned to variables.
>>
>> Martin
>>
>>>


-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-05 Thread Dorival Pedroso
Hi Martin;

What about two commands "*watch*" and "*watchif*"?

The first works as the "*var*" command and the second as the "*if*" command.

"*watch*" does:

   1. In a function with *error* as an output (anywhere): returns in case 
   the *err* declared with *watch err* (or *watch myerror*) becomes 
   non-nil. *watch err* would declare *err*" as *var* does. Most use cases 
   would put *watch err* at the beginning of a function (although this is 
   optional as it is with *defer*)
   2. In a test function; aka TestSomething(something *testing.T), *watch 
   err error* would declare *err* (or *watch myerror error*) and if an 
   error occurs, it would call something.FailNow() after (printing the error 
   message?---still need to think this part better)
   3. In the main function: *watch err error* would print the error message 
   (or maybe pipe to stderr) and os.Exist(1)
   4. *watchif err != nil {HERE}* would be more powerful because it would 
   allow us to do other things. But the mechanism is similar (as you proposed 
   initially): if *err* becomes non-nil anywhere, the execution in *HERE* 
   would take place.

Cheers!


On Tuesday, September 5, 2017 at 4:55:59 PM UTC+10, 
marti...@programmfabrik.de wrote:
>
> Hi Dorival,
>
> thanks for supporting me with my idea.
>
> And yes, after writing my post yesterday I was thinking, "watchif" or even 
> simply "watch".
>
> And yes, today I am more in favor of simply *"watch"*.
>
> And yes, we can constrain this to the context of one function (like 
> defer), I am ok with that. 
>
> What you are describing how you work with errors and how you spent hours 
> adding 
>
> *if err != nil*
>
> that is *exactly* my point.
>
> On could nicely write this
>
> ...
> watch err!=nil {
>   handle_sql_error(err)
> }
> ...
>
> Of course, watch could also be used to not watch out for errors but any 
> other places where new values to get assigned to variables.
>
> Martin
>
>>
>>>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-04 Thread martin . rode
Hi Dorival,

thanks for supporting me with my idea.

And yes, after writing my post yesterday I was thinking, "watchif" or even 
simply "watch".

And yes, today I am more in favor of simply *"watch"*.

And yes, we can constrain this to the context of one function (like defer), 
I am ok with that. 

What you are describing how you work with errors and how you spent hours 
adding 

*if err != nil*

that is *exactly* my point.

On could nicely write this

...
watch err!=nil {
  handle_sql_error(err)
}
...

Of course, watch could also be used to not watch out for errors but any 
other places where new values to get assigned to variables.

Martin

>
>>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-04 Thread martin . rode

On Monday, September 4, 2017 at 10:48:06 PM UTC+2, Tamás Gulácsi wrote:
>
> Why do you Prepare a statement if you don't reuse it? Just use a db.Exec.

 
Just wanted to show a pattern which I see very often in Go code. Its not a 
working example, and I am not asking for improvements in that code. 

But concretes aside: error handling IS important!
>

Yes it is. But as my example shows, it should not get annoying.
 

> But if such code bothers you, create some helper type / function: see one 
> Andy+Brad pair programming video where they create an errWriter struct 
> which is an io.Writer, and just writes to the underlyin Write. Untill the 
> first error. From then on it always returns the fist error.
>

The problem with ANY error handling solution within the existing Go syntax 
will require one of three things:

   - Wrap the call which you need to check the error for
   - Wrap the check into a function, to save code lines
   - Do some tricks to check the error at the end of a block

Neither one of these methods is satisfying for me. I need to be able to 
produce readable, concise code which does the right thing.


-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-04 Thread Dorival Pedroso
I forgot (again) to say that in this case the error would just be returned. 

In other words, `watch err` would just check if `err != nil` and then 
return.

The other cases (test, main) would be as explained earlier (FailNow(), 
Exit(1))

On Tuesday, September 5, 2017 at 10:14:16 AM UTC+10, Dorival Pedroso wrote:
>
> Hi, the `watch err` could also work in "APIs" that already return "error".
>
> For instance:
> package myapi
>
> func First() (err error) {
> watch err
> err = internalFunction(1,2,3)
> err = internalFunction(3,2,1)
> err = internalFunction(1,3,2)
> }
>
>
>
>
> On Tuesday, September 5, 2017 at 4:27:20 AM UTC+10, 
> marti...@programmfabrik.de wrote:
>>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in larger code bases and it also takes 
>> away focus from what is actually happening.
>>
>> 50-80% of all lines of code in my example deal with error handling?
>>
>> This is not good. Seriously.
>>
>> And don't get me wrong, there is a lot of things I really like, love and 
>> adore about Go, but catching errors needs an improved syntax!
>>
>> And I am not proposing try...catch here. 
>>
>> How about introducing a new piece of syntax 
>>
>> "watch if   " 
>>
>> which tells the compiler to watch out for changes in a given SimpleStmt
>>
>> The same code as above would look like this:
>>
>> var err Error
>>
>> watch if err != nil {
>>   // handle error(s)
>> }
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>> created) values(?,?,?)")
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> id, err := res.LastInsertId()
>> fmt.Println(id)
>>
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> res, err = stmt.Exec("astaxieupdate", id)
>> affect, err := res.RowsAffected()
>>
>>
>>- The "watch if" would be executed after each assignment of any of 
>>the variables used in SimpleStmt of the statement.
>>- Multiple "watch if" would be executed in order or appearance
>>- The "watch if" could be used like "defer..." inside functions
>>- The "watch if" would work in its full scope of the watched variables
>>
>> I am not a language expert, so may be there is a saner way of expression 
>> what I want to achieve.
>>
>> But bottom line is, there should by an easier to read and write way to 
>> deal with errors in Go.
>>
>>
>> Martin
>>
>>
>>
>>
>>
>>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-04 Thread Dorival Pedroso
Hi, the `watch err` could also work in "APIs" that already return "error".

For instance:
package myapi

func First() (err error) {
watch err
err = internalFunction(1,2,3)
err = internalFunction(3,2,1)
err = internalFunction(1,3,2)
}




On Tuesday, September 5, 2017 at 4:27:20 AM UTC+10, 
marti...@programmfabrik.de wrote:
>
> Hi guys,
>
> at first I though I really like the idea of how Go deals with error 
> management and handling, but the more Go code I look at or try to program, 
> the more I get scared about checking errors every second line in every 
> given block of code.
>
> Take a look at this example here from "Build Web Application with Golang":
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
> values(?,?,?)")
> if err != nil {
>   // handle error
> }
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> if err != nil {
>   // handle error
> }
> id, err := res.LastInsertId()
> if err != nil {
>   // handle error
> }
> fmt.Println(id)
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> if err != nil {
>   // handle error
> }
> res, err = stmt.Exec("astaxieupdate", id)
> if err != nil {
>   // handle error
> }
> affect, err := res.RowsAffected()
> if err != nil {
>   // handle error
> }
>
>
> Seriously? And yes, I have read https://blog.golang.org/errors-are-values.
> ..
>
> The best case reduction I found is:
>
> ...
> res, err = stmt.Exec("astaxieupdate", id)
> checkError(err)
> ...
>
> Still, I need this after each line of calling a function which may return 
> an error.
>
> I bet this is not pleasant to do in larger code bases and it also takes 
> away focus from what is actually happening.
>
> 50-80% of all lines of code in my example deal with error handling?
>
> This is not good. Seriously.
>
> And don't get me wrong, there is a lot of things I really like, love and 
> adore about Go, but catching errors needs an improved syntax!
>
> And I am not proposing try...catch here. 
>
> How about introducing a new piece of syntax 
>
> "watch if   " 
>
> which tells the compiler to watch out for changes in a given SimpleStmt
>
> The same code as above would look like this:
>
> var err Error
>
> watch if err != nil {
>   // handle error(s)
> }
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
> created) values(?,?,?)")
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> id, err := res.LastInsertId()
> fmt.Println(id)
>
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> res, err = stmt.Exec("astaxieupdate", id)
> affect, err := res.RowsAffected()
>
>
>- The "watch if" would be executed after each assignment of any of the 
>variables used in SimpleStmt of the statement.
>- Multiple "watch if" would be executed in order or appearance
>- The "watch if" could be used like "defer..." inside functions
>- The "watch if" would work in its full scope of the watched variables
>
> I am not a language expert, so may be there is a saner way of expression 
> what I want to achieve.
>
> But bottom line is, there should by an easier to read and write way to 
> deal with errors in Go.
>
>
> Martin
>
>
>
>
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.


[go-nuts] Re: error handling needs syntactical sugar

2017-09-04 Thread Dorival Pedroso
by the way, above, I was thinking of `watch` as a counterpart of `var`...

On Tuesday, September 5, 2017 at 8:56:24 AM UTC+10, Dorival Pedroso wrote:
>
> Hi,
>
> Error management in Go is perfect!
>
> But I like the idea of `watch` (may we drop the `if`?)
>
> So, `watch` would work in the context of a function like `defer`. However, 
> this would effectively become a `catcher` for errors (instead of `panics`) 
> within the `defer` function, right?
>
> Also, I think `watch` would effectively be a "conditioned defer".
>
> Once, I've spent hours adding `if err != nil { ... }` elsewhere in my 
> code. Lately, I've started using two auxiliary functions just for 
> readability:
>
> In tests, I use:
> func status(tst *testing.T, err error) {
> if err != nil {
> tst.Errorf("ERROR: %v\n", err)
> tst.FailNow()
> }
> }
>
> func TestBessel01(tst *testing.T) {
> dat, err := ReadTable("data/as-9-bessel-integer-big.cmp")
> status(tst, err)
> ...
> }
>
> In "main functions", I use:
> func status(err error) {
> if err != nil {
> io.Pf("ERROR: %v\n", err)
> os.Exit(1)
> }
> }
>
> I (try to) check the errors everywhere in the API and these "syntax 
> sugars" are only required at the final stages ("test mode" or "main 
> function").
>
> So, `watch` could be something like:
> func TestBessel01(tst *testing.T) {
> watch err error // the compiler could detect that we're on "test" mode 
> and then return when err != nil
> dat, err := ReadTable("data/as-9-bessel-integer-big.cmp")
> err = ComputeWithData(dat)
> ...
> err = DoSomethingElse(dat)
> ...
> }
>
> In "main functions":
> func main() {
> watch err error // the compiler would detect that we're on "main 
> function" mode and then Exit(1)
> err := ComputeWithData(...)
> }
>
> The command `watch` could even be used for different purposes; e.g. when 
> something that should be  isn't.
>
> Cheers.
> D
>
>
> On Tuesday, September 5, 2017 at 4:27:20 AM UTC+10, 
> marti...@programmfabrik.de wrote:
>>
>> Hi guys,
>>
>> at first I though I really like the idea of how Go deals with error 
>> management and handling, but the more Go code I look at or try to program, 
>> the more I get scared about checking errors every second line in every 
>> given block of code.
>>
>> Take a look at this example here from "Build Web Application with Golang":
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
>> values(?,?,?)")
>> if err != nil {
>>   // handle error
>> }
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> if err != nil {
>>   // handle error
>> }
>> id, err := res.LastInsertId()
>> if err != nil {
>>   // handle error
>> }
>> fmt.Println(id)
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> if err != nil {
>>   // handle error
>> }
>> res, err = stmt.Exec("astaxieupdate", id)
>> if err != nil {
>>   // handle error
>> }
>> affect, err := res.RowsAffected()
>> if err != nil {
>>   // handle error
>> }
>>
>>
>> Seriously? And yes, I have read 
>> https://blog.golang.org/errors-are-values...
>>
>> The best case reduction I found is:
>>
>> ...
>> res, err = stmt.Exec("astaxieupdate", id)
>> checkError(err)
>> ...
>>
>> Still, I need this after each line of calling a function which may return 
>> an error.
>>
>> I bet this is not pleasant to do in larger code bases and it also takes 
>> away focus from what is actually happening.
>>
>> 50-80% of all lines of code in my example deal with error handling?
>>
>> This is not good. Seriously.
>>
>> And don't get me wrong, there is a lot of things I really like, love and 
>> adore about Go, but catching errors needs an improved syntax!
>>
>> And I am not proposing try...catch here. 
>>
>> How about introducing a new piece of syntax 
>>
>> "watch if   " 
>>
>> which tells the compiler to watch out for changes in a given SimpleStmt
>>
>> The same code as above would look like this:
>>
>> var err Error
>>
>> watch if err != nil {
>>   // handle error(s)
>> }
>>
>> // insert
>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
>> created) values(?,?,?)")
>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
>> id, err := res.LastInsertId()
>> fmt.Println(id)
>>
>> // update
>> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
>> res, err = stmt.Exec("astaxieupdate", id)
>> affect, err := res.RowsAffected()
>>
>>
>>- The "watch if" would be executed after each assignment of any of 
>>the variables used in SimpleStmt of the statement.
>>- Multiple "watch if" would be executed in order or appearance
>>- The "watch if" could be used like "defer..." inside functions
>>- The "watch if" would work in its full scope of the watched variables
>>
>> I am not a language expert, so may be there is a saner way of expression 
>> what I want to achieve.
>>
>> But bottom line is, there should by an easier to read and wri

[go-nuts] Re: error handling needs syntactical sugar

2017-09-04 Thread Dorival Pedroso
Hi,

Error management in Go is perfect!

But I like the idea of `watch` (may we drop the `if`?)

So, `watch` would work in the context of a function like `defer`. However, 
this would effectively become a `catcher` for errors (instead of `panics`) 
within the `defer` function, right?

Also, I think `watch` would effectively be a "conditioned defer".

Once, I've spent hours adding `if err != nil { ... }` elsewhere in my code. 
Lately, I've started using two auxiliary functions just for readability:

In tests, I use:
func status(tst *testing.T, err error) {
if err != nil {
tst.Errorf("ERROR: %v\n", err)
tst.FailNow()
}
}

func TestBessel01(tst *testing.T) {
dat, err := ReadTable("data/as-9-bessel-integer-big.cmp")
status(tst, err)
...
}

In "main functions", I use:
func status(err error) {
if err != nil {
io.Pf("ERROR: %v\n", err)
os.Exit(1)
}
}

I (try to) check the errors everywhere in the API and these "syntax sugars" 
are only required at the final stages ("test mode" or "main function").

So, `watch` could be something like:
func TestBessel01(tst *testing.T) {
watch err error // the compiler could detect that we're on "test" mode 
and then return when err != nil
dat, err := ReadTable("data/as-9-bessel-integer-big.cmp")
err = ComputeWithData(dat)
...
err = DoSomethingElse(dat)
...
}

In "main functions":
func main() {
watch err error // the compiler would detect that we're on "main 
function" mode and then Exit(1)
err := ComputeWithData(...)
}

The command `watch` could even be used for different purposes; e.g. when 
something that should be  isn't.

Cheers.
D


On Tuesday, September 5, 2017 at 4:27:20 AM UTC+10, 
marti...@programmfabrik.de wrote:
>
> Hi guys,
>
> at first I though I really like the idea of how Go deals with error 
> management and handling, but the more Go code I look at or try to program, 
> the more I get scared about checking errors every second line in every 
> given block of code.
>
> Take a look at this example here from "Build Web Application with Golang":
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) 
> values(?,?,?)")
> if err != nil {
>   // handle error
> }
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> if err != nil {
>   // handle error
> }
> id, err := res.LastInsertId()
> if err != nil {
>   // handle error
> }
> fmt.Println(id)
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> if err != nil {
>   // handle error
> }
> res, err = stmt.Exec("astaxieupdate", id)
> if err != nil {
>   // handle error
> }
> affect, err := res.RowsAffected()
> if err != nil {
>   // handle error
> }
>
>
> Seriously? And yes, I have read https://blog.golang.org/errors-are-values.
> ..
>
> The best case reduction I found is:
>
> ...
> res, err = stmt.Exec("astaxieupdate", id)
> checkError(err)
> ...
>
> Still, I need this after each line of calling a function which may return 
> an error.
>
> I bet this is not pleasant to do in larger code bases and it also takes 
> away focus from what is actually happening.
>
> 50-80% of all lines of code in my example deal with error handling?
>
> This is not good. Seriously.
>
> And don't get me wrong, there is a lot of things I really like, love and 
> adore about Go, but catching errors needs an improved syntax!
>
> And I am not proposing try...catch here. 
>
> How about introducing a new piece of syntax 
>
> "watch if   " 
>
> which tells the compiler to watch out for changes in a given SimpleStmt
>
> The same code as above would look like this:
>
> var err Error
>
> watch if err != nil {
>   // handle error(s)
> }
>
> // insert
> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, 
> created) values(?,?,?)")
> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
> id, err := res.LastInsertId()
> fmt.Println(id)
>
> // update
> stmt, err = db.Prepare("update userinfo set username=? where uid=?")
> res, err = stmt.Exec("astaxieupdate", id)
> affect, err := res.RowsAffected()
>
>
>- The "watch if" would be executed after each assignment of any of the 
>variables used in SimpleStmt of the statement.
>- Multiple "watch if" would be executed in order or appearance
>- The "watch if" could be used like "defer..." inside functions
>- The "watch if" would work in its full scope of the watched variables
>
> I am not a language expert, so may be there is a saner way of expression 
> what I want to achieve.
>
> But bottom line is, there should by an easier to read and write way to 
> deal with errors in Go.
>
>
> Martin
>
>
>
>
>
>

-- 
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.
For more options, visit https://groups.google.com/d/optout.