Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
×
Programming Open Source

'Kerfuffle' Erupts Around Newly-Proposed try() Feature For Go Language (thenewstack.io) 210

Matt Klein, a member of the Go steering committee recently apologized for the angst caused to some people by "the try() kerfuffle... Change is hard, but sometimes it's for the best."

Tech columnist Mike Melanson covers the kerfuffle over the newly-proposed feature, while trying "not to over-dramatize what is happening." There is disagreement and conflicting views, but working through those views is how the open source sausage is made, is it not? Of course, in the Go community, how the core team receives those opposing views may be a point of soreness among some who vehemently opposed the vgo package versioning for Go and felt that, in the end, it was rammed through despite their objections. As one Gopher points out, it is better to debate now than summarily accept and then later deprecate...

As Go makes its way to Go 2.0, with Go 1.14 currently taking center stage for debate, there is, again, as Klein points out, some kerfuffle about a newly proposed feature called try(), which is "designed specifically to eliminate the boilerplate if statements typically associated with error handling in Go." According to the proposal, the "minimal approach addresses most common scenarios while adding very little complexity to the language" and "is easy to explain, straightforward to implement, orthogonal to other language constructs, and fully backward-compatible" as well as extensible for future needs.

Much of the disagreement around try() comes in the form of whether or not the resultant code is more or less readable than current implementations of error handling. Beyond that, however, some say that even if try() were accepted, it has faults that would prevent them from recommending or even allowing its use among their teams. Meanwhile, another point of contention is offered in an open letter to the Go team about try by William Kennedy who often writes about Go, and focuses on not style or function, but rather whether or not a solution is needed at all. According to Kennedy, "the perceived error handling complaints are perhaps overblown and these changes are not what the majority of Go developers want or need" and that try() may be a solution searching for a problem, and even the cause of more problems than it solves."Since this new mechanic is going to cause severe inconsistencies in code bases, disagreements on teams, and create an impossible task for product owners to enforce consistent guidelines, things need to be slowed down and more data needs to be gathered," Kennedy writes.

He goes on to point out those very sensitivities that may have lingered from previous discussions in the Go community. "This is a serious change and it feels like it's being pushed through without a concerted effort to understand exactly what those 5% of Go developers meant when they said they wanted improved error handling...."

This discussion has been archived. No new comments can be posted.

'Kerfuffle' Erupts Around Newly-Proposed try() Feature For Go Language

Comments Filter:
  • by SuperKendall ( 25149 ) on Saturday July 06, 2019 @05:41PM (#58883644)

    Fro decades now error handling has seen so many forms, from exceptions, to return values, to special return types that wrap either results or errors depending on which you have, to in-out error params that get populated on result of an error...

    It all just seems to go around and around again. And even mechanisms that are supposed to force people to handle errors seem to end up a lot of time in println.

    • by phantomfive ( 622387 ) on Saturday July 06, 2019 @06:17PM (#58883784) Journal
      The problem is there are different error mechanisms for different use cases. For example, if you're writing web APIs, then you mostly don't care what the error is, you can just let the exception float up to the top and return an error to the client or whatever. Maybe log something. Exceptions are really nice for that use case, really easy to write code with.

      If you are writing OS code, you need to know when an error happens, and you need to deal with it. For that use case, return values work well, and unchecked exceptions are very, very hard to use effectively (so difficult that when Microsoft wrote a kernel in C#, they added checked exceptions to the language).

      So there's no error reporting mechanism that fits every use case perfectly. And even in the best case, error handling code is a pain and rarely tested.
      • Comment removed based on user account deletion
        • 99% of the case when you're processing a 'POST' - that is, you're going to process and store the results - you probably need to write a whole fallback/rollback process (which the frameworks are generally shitty at, go figure.)

          That's something that memory transactions could theoretically help you with, yet vendors like Intel apparently screwed up their hardware that was supposed to do that.

        • 99% of the case when you're processing a 'POST' - that is, you're going to process and store the results - you probably need to write a whole fallback/rollback process

          If your framework rolls back transactions on exceptions, then 95% of the time you don't have to worry about it. Occasionally there are more complex POSTs that also need complex error handling, but those are rare.

          Of course, if your framework doesn't roll back transactions on exceptions, then you need to write that code yourself.

        • which the frameworks are generally shitty at, go figure.
          In Java they are excellent, e.g. spring-boot. But it has other drawbacks where I wonder who was involved in the design.

      • The problem is there are different error mechanisms for different use cases.

        I think it's even more complex than that as there are also different desires at different times to say what should truly "handle" an error - should it just go to a log? Should it go to the person using the application to pass along to someone else? Should it be rigorously handled and alternative code run instead as a backup, that may itself fail? And all of it, maybe it needs to be decided dynamically...

        I've seen people use excep

        • I've seen people use exceptions for all kinds of error handling, to pass stuff back up to the top level and also just in-module error capture and consumption.

          The big problems with exceptions as an error handling mechanism is that over time they stop being used for only exceptional conditions and start being used as something much closer to general flow control.

          For instance even if the stream object has a method that answers "is there any data left?" a heavyweight try/catch exception handling scheme is used instead and becomes the "norm" even though that lightweight "is there any data left?" function works for almost all use cases.

          Another case case is a func

          • That's a great point, I've also seen systems that use exception handling for flow control and not just errors.

      • That's completely wrong.

        Whether to use exceptions or error codes is a matter of what your invariants are.
        if your invariant is "I'm never in an error state" then you have to use exceptions, because return codes only allow you to notify the caller something bad happened, as opposed to making sure state cannot be propagated and the stack is unwound.


      • try() {
            installwindows.exe
        } catch(exception e) {
            e = null; //LOL
            Msgbox.show("Something went wrong! Good luck figuring out what it was, LOL");
        }

      • by shess ( 31691 )

        The problem is there are different error mechanisms for different use cases. For example, if you're writing web APIs, then you mostly don't care what the error is, you can just let the exception float up to the top and return an error to the client or whatever. Maybe log something. Exceptions are really nice for that use case, really easy to write code with.

        If you are writing OS code, you need to know when an error happens, and you need to deal with it. For that use case, return values work well, and unchecked exceptions are very, very hard to use effectively (so difficult that when Microsoft wrote a kernel in C#, they added checked exceptions to the language).

        This distinction is only made because on a networked system, it is basically impossible to handle all errors. Once you're not handling a bunch of errors, it's super easy to not handle another error, in a self-reinforcing way. That doesn't mean it's a correct decision, it just means you gave up and decided to ship crappy software. You can always fix it with a patch rollout, right?

        [Sigh. I realize that that last might float past people - you can try to fix it, but if your development culture floats except

    • by davecb ( 6526 )

      Errors are hard: I'm trying to put together an analysis of error propagation (not handling!) as a safety-critical system, to follow up to A Discipline of Errors [wordpress.com]

      Comments, corrections and well-hurled brickbats are cordially invited!

      • by davecb ( 6526 )
        Ok, first draft of leaflessca.wordpress.com/2019/07/06/errors-as-if-they-were-in-a-safety-critical-system/
      • Thanks, it's a bit short at the moment but a good start and brings up some interesting points.

    • I think "error" handling is often the wrong term, it's "exception" handling normally. Ie, reaching the end of a file is not an error. So even with some advanced features like exception handing I see many programmers resort to assuming it's just for errors. I also see a tendency in that new ways of handling either errors or exceptions can be done even more clumsily than classical return code error handling, such as just having a single catch-all handler on the outermost loop (not error-handling per se but

    • by swilver ( 617741 )

      You forgot setting a global value to a non-zero value, that would get overwritten each call that might generate an error.

  • by That YouTube Guy ( 5905468 ) on Saturday July 06, 2019 @05:48PM (#58883676)
    "Do or do not! There is no TRY!" — Yoda
  • by 93 Escort Wagon ( 326346 ) on Saturday July 06, 2019 @05:51PM (#58883692)

    The word author the author learned today was obviously "kerfuffle", given he chose to use it a half dozen times.

    Maybe someone should teach him about the word "thesaurus".

  • by PopeRatzo ( 965947 ) on Saturday July 06, 2019 @06:11PM (#58883768) Journal

    Technically, this is less of a kerfuffle than a brouhaha. A to-do, if you will. Less than a donnybrook, but more than a mere hoo-ha.

  • by guruevi ( 827432 ) on Saturday July 06, 2019 @06:25PM (#58883810)

    Basically this is your code with try/catch (any language):
    try {
      do_thing_1();
      do_thing_2();
      do_thing_3();
    } catch {
        print_error("Something happened in 1, 2 or 3");
        die("Fatal error");
    }

    This is your code in Go:
    result = do_thing_1();
    if (result == failed) {
        print_error("Something happened in 1");
        die("Fatal error");
    } else {
            result2 = do_thing_2();
            if (result2 == failed) {
                print_error("Something happened in 2");
                die("Fatal error");
            } else {
                result3 = do_thing_3();
                if (result2 == failed) {
                    print_error("Something happened in 2");
                    die("Fatal error");
            }
        }
    }

    • by phantomfive ( 622387 ) on Saturday July 06, 2019 @06:29PM (#58883824) Journal
      That's a bad example: you don't need all those else clauses, and you can condense print_error() and die() into a single function.

      Finally, the try{}catch{} example you gave doesn't have anything to do with the feature proposed here in Go.
      • by guruevi ( 827432 )

        Yes, I know you can avoid the else clauses but it sacrifices readability/consistency. Perhaps you can condense the two, perhaps not, in many cases you do not want to die on printing an error. It largely depends on your circumstances.

        I'm also aware of the fact that Go's implementation of "try" will be 'slightly' different than just about any other language that implements a try statement, just for readability and to avoid confusion, I'm sure.

        • I'm also aware of the fact that Go's implementation of "try" will be 'slightly' different than just about any other language

          It's drastically different. It doesn't even implement the same functionality. The only similarity is that they both deal with error handling code.

        • This version of try() is just a short way to write "if err then return". It's a pretty crap macro even for C-like language, kind of limited use.
      • So illuminate it? I'm not following the problem here.

    • Note of course that your example had an error in it.

      The main benefit of exception based code is it's brevity when compared with the equivalent return-, wrapper-, or parameter-based error codes. The benefits of return-based codes are their specificity and flexibility. Wrapper-based errors are useful where an existing protocol can't be changed. Error parameters are about the same as returned error codes but are even more bulky code-wise. Different return targets have a linguistic overhead of supporting labels

    • by davecb ( 6526 )
      Alas, try allows and arguably encourages grouping of errors together. Unfortunately, programmer errors, input-data errors and infrastructure errors need different approaches. That made some of my Java and C++ error handling turn out like <expletive deleted> switch statements.
    • Pointless, you need to say where it crashed or include an error code at the very least. However it's better to actually handle the error rather than throw your hands in the air. There is often need for code that does not fail so easily and is more robust when encountering errors. After all, customers may be annoyed that their television crashed and is taking a few minutes to reboot; and extremely put out when their automobile engine decides that it's time to throw UnknownError.

    • ... try is great. Deals elegantly with what you cannot depend on.

      If you're calling try on your own code... well, where do I start.....

      • If you're calling try on your own code... well, where do I start.....

        You start out by pointing out that its in the name "exception handling" ... It is for handling things of an exceptional nature, not general flow control.

      • try is great. Deals elegantly with what you cannot depend on.

        That’s a very nice description of what try() is for. But it most definitely applies to your own code too. Or at least to mine: I’m not arrogant enough to think my own code is error-free or capable of dealing with every eventuality. But as others have stated elsewhere, I do not use try() for flow control. And I certainly do not test with serious errors being silently caught that way.

    • by AmiMoJo ( 196126 )
      What's wrong with

      if ( ((res = func1()) != ok) || ((res = func2()) != ok) || ((res = func3()) != ok) )
      {
          print_error(res);
          die(res);
      }

      Goes Go not allow something like that?

      Also this try() function is a bit different to the example you gave. Basically functions in Go return an error as the last parameter by convention, and it just condenses the if() and error handling into try(func()).
    • Unless I'm reading this [github.com] wrong, that isn't what is proposed. The "try()" statement for Go doesn't seem to be true "exception handling" as shown in the first example above, but more syntactic sugar for the second 'check the return of every function' example. In good old-fangled C you'd do:

      #define TRY(f) if ( (f) == EOF ) { return( EOF ) }

      (except using Go's facilities for functions to return a list of values, with the last one being an error flag (which does sound a useful technique). I'm not a Go progr

    • Basically this is your code with try/catch (any language):
      That example is wrong.

      try {
      do_thing_1();
      do_thing_2();
      do_thing_3();
      } catch {
      print_error("Something happened in 1, 2 or 3");
      die("Fatal error");
      }

      It should look more like this.

      try {
      do_thing_1();
      do_thing_2();
      do_thing_3();
      } catch (Exception1 ex) {
      print_error("Something happened in 1

  • I've worked in many large projects and company. I've seen very little GO usage. The main exception is where somebody felt like trying it and nobody found out about it until it was deployed. In other words, it's bottom up, without any management decision as to whether or not it is good for the organization. Usually management is pissed off because they perceive it as a new and unnecessary support headache.

    • by davecb ( 6526 )

      Whereas my management looks at it and said "Wow, Communicating Sequential Processes in a non-academic language"

      And yes, I do pick my companies based on who's running them as much as what they're doing. I even chased Jacob Slonim around for a couple of years until I could get a job with him, rather than at a company he'd left (;-))

    • Golang is really popular with Devops. For example, Gitlab uses it as a language of choice. It is a language built for infrastructure engineers, and it's a really nice language if you are writing lower level servers. It does a good job of that.

      It's also becoming more popular as a backend language. People start with Python, Javascript, or Rails on the backend, but soon realize static typing makes things a LOT easier once you have a bigger team. Then the question is what do you use? If you don't want to use
      • by nyet ( 19118 )

        The same devops that insist on building a 15M static binary in a container to avoid "dependency" issues because they're too stupid to architect around properly versioned libraries?

        Ya, I don't take them seriously either.

    • I wrote some toy programs in it, really tried to like it. But this language... it's not for professional developers. It's for wannabes. With all its in your face flaws and weird matters of taste... that is, Rob Pike's taste, fuck you malcontent users... it would have been completely forgotten by now, except Google. Conferred some kind of respect it doesn't deserve. Google couldn't possibly hatch a flightless turkey could they? Google is populated by nothing but smart people, right? Right?

      Check out Rust. An

  • try() not!
    do() or do not()!
    There is no try()!

  • I must say, my opinion of Rob Pike and Ken Thompson took a major dive when I looked at this supposed "feature". Oh yeah, change is hard, change for the worse is harder. But looks like Go for me is just Gone. Wake me up if it ever gets generics. Instead it gets halfassed syntactic sugar like try, at that same time polluting the well known try ... catch pattern with something that isn't even remotely like it. Even a highschooler could do better. Thxbai.

  • I quote "There is no TRY, only DO"
  • I consider error handling a solved problem, and I'd expect any "new" language to have solved it as well. No need to try this one for now.

Children begin by loving their parents. After a time they judge them. Rarely, if ever, do they forgive them. - Oscar Wilde

Working...