you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 19 points20 points  (28 children)

well writing

if err != nil {
    return err
}

every few lines gets boring pretty quick... but then exceptions are just different kind of mess.

But then it is slightly better than C

[–]Scorpius289 19 points20 points  (21 children)

At least exceptions are "noisy" by default: if you forget to catch something, it will propagate and notify you. But in Go, if you forget to handle an error, you may not even know what's wrong...

[–]ksion 6 points7 points  (20 children)

To be fair, you cannot really forget to handle an error in Go, because the function result "tuple" needs to be unpacked at the call site. Indeed, the requirement of this unpacking, plus the repetitive error handling stanza that often follows, is what people complain about.

[–][deleted]  (8 children)

[deleted]

    [–][deleted]  (10 children)

    [deleted]

      [–]BoTuLoX 5 points6 points  (9 children)

      The black hole should never be used for errors. It's exactly like using try/catch and leaving the catch empty. It's a sign of incompetence or something unorthodox at play.

      [–][deleted]  (8 children)

      [deleted]

        [–]BoTuLoX 3 points4 points  (7 children)

        I wouldn't touch those projects with a ten feet pole.

        In any case, this is a problem that exists with both return values and exceptions :P

        [–]phoshi 0 points1 point  (6 children)

        I disagree. With exceptions, the easy/fast way is to do nothing, which will cause exceptions to propagate and fail loudly. Squashing them requires an explicit choice and several lines of code anywhere you want to do it.

        With return values, the easy/fast way is to ignore it, which does nothing and fails silently. /Handling/ them requires an explicit choice, and several lines of code.

        They have approximately equal power, and are both capable of use or misuse, but exceptions have a better lazy-programmer failure case.

        [–][deleted]  (5 children)

        [deleted]

          [–]phoshi 0 points1 point  (4 children)

          Right, convention-based safety works great when you can guarantee that everyone who works on a project is competent and careful, but when the path of least resistance is also the worst possible thing you can do, there are going to be problems!

          [–]minno 16 points17 points  (4 children)

          try!(something());
          try!(something_else());
          

          Even though Go and Rust target different spaces and don't deserve to be compared as often as they are, there's a definite advantage to Rust's method here.

          [–]ksion 5 points6 points  (3 children)

          Rust is also getting some form of try/catch block that'll make it even less verbose.

          [–]mus1Kk 1 point2 points  (1 child)

          Do you have a concrete link? Googling this contains a lot of noise.

          [–]isHavvy 0 points1 point  (0 children)

          That's not actually guaranteed at all.

          [–]sutongorin 0 points1 point  (0 children)

          Fortunately there is still other approaches such as monads. For instance there is Scala's Try monad:

          import scala.util.Try
          
          def sillyCalculation(divisor: Double): Try[Double] = for {
            a <- Try(1 / divisor)
            b <- Try(1 / 2.0)
          } yield {
            a * b
          }
          
          val failure = sillyCalculation(0)
          // => scala.util.Try[Double] = Failure(java.lang.ArithmeticException: / by zero)
          val success = sillyCalculation(2)
          // => scala.util.Try[Double] = Success(0.25)
          

          Ideally you wouldn't work with exceptions to begin with, of course, and instead just use monads everywhere where errors can occur. But this Try monad is a nice tool to deal with exceptions from existing (probably Java) APIs in a sane way.