4 ms·
>If you don't handle the error (e.g. by forgetting), the compiler will show an error because you declared err, but didn't use it. But if I make a mistake like
by papsosouid 14y ago
>If you don't handle the error (e.g. by forgetting), the compiler will show an error because you declared err, but didn't use it.
But if I make a mistake like I mentioned previously, I could very well use err, thus not getting a compiler warning, and still also use foo, which is a whoknowswhat. It should be an Either, not two seperate return values.
>Making these specifics a criteria for decency is nothing but arrogance.
Having opinions is not arrogance. You should consider that when someone shares their opinion, they are not declaring that everyone everywhere must acknowledge it as a universal truth.
- Evbn 14y agoAnd in Haskell you could make the mistake of ignoring the error and writing Right x = leftOrRight y And get a runtime crash when a Left shows up, Or Just x = justOrNone y And crash on None.
- gnuvince 14y agoAs you point out, in both cases the program will crash, which for many people is preferable to the program churning along with invalid data. In Go with multiple return values, it is possible to have a code path where there's an error but still use what would've been the result of the procedure. In ML or Haskell when using sum types, that code path does not exist.
- masklinn 14y ago> In ML or Haskell when using sum types, that code path does not exist. Of course it exists: don't unpack the result and ignore it or pass it along, or use it through its monadic or applicative interface (to proxy-with-transform to the caller).
- papsosouid 14y agoI don't know what you mean by your first example, how does that lead to using undefined data? And your second example is incorrect, if you use an Either in monadic style then each successive function call after the error occurs is doing nothing. It simply returns the existing error from the Either, it doesn't try to run a computation on the non-existent value.
- gnuvince 14y agoI feel we may be arguing without me having properly defined what I meant, so I will try to remedy this. Consider the following code: a, _ := some_computation_that_may_fail() b := f(a) In Go, if there was an error in `some_computation_that_may_fail`, the call to `f` will be made with a undetermined value for `a` and we end up with an undetermined value for `b`. This is why I say that there is a path where we can use `a` even when we shouldn't. Compare with OCaml: let Some a = some_computation_that_may_fail () in let b = f a First of all, the compiler will warn you that the pattern matching on line 1 is non-exhaustive and will give you an example of a failing case (here, it will simply be `None`). If the programmer ignores that warning and runs the program anyway and the computation executes with an error, the program will fail at the first line, and thus the second function `f` will never be called and `b` will not contain an undetermined value. I hope this clears up what I meant, I apologize that I wasn't clearer in the first place. Cheers!
- papsosouid 14y agoThat isn't the same. If you do that you will get an Irrefutable pattern failed exception. You don't actually get access to x if justOrNone returns Nothing, because you are pattern matching and the Just pattern doesn't match. So you won't be able to use a non-value in further computations like you can with go.