4 ms·
What is a Golang person... a Goist? A Goer (hehe, Monty Python). Since I am a goer, I'll use Goist here. I'm not a Goist, but I agree with TFA in general. D
by z9znz 4y ago
What is a Golang person... a Goist? A Goer (hehe, Monty Python). Since I am a goer, I'll use Goist here.
I'm not a Goist, but I agree with TFA in general. Don't complicate a language for error handling purposes. My reasoning is that most errors cannot be properly dealt with anyway.
Is it the Erlang or the Elixir folks to just say, paraphrased, "let it die"?
Just let it blow up. Somewhere upstream can deal with it, because chances are we don't know enough down in the trenches to know what to do when something which we expect to work virtually always, fails.
And to improve the noise on the current copy example, I would argue to stop wasting lines!!! There is no good reason to open a bracket, newline, then return err, then close the bracket. It's small and obvious.
if err != nil { return err } // put it on one line. It's clean and natural.
Edit: Oh now I remember from my limited Go experience :(. They live by their formatter, and their formatter was built in a bondage dungeon.
- nine_k 4y agoThere are errors and exceptions. An exception is something unexpected, unanticipated, exceptional. It's totally fine to crash on it. Running out of memory is a good example. An error is something expected, a less probable but anticipated result. A request timeout is a good example. It's important to have a nice way to process it, and to take an action other than crashing, say, to retry. In this regard, `guard` is a nice proposal: it explicitly shows where we are willing to crash (like `!` in Typescript or Rust or Kotlin), while staying perfectly backwards-compatible and not requiring any rewrites. It's not perfect in other respects though; I liked the `try` proposal better.
- llanowarelves 4y agoThanks for making this distinction. I sometimes have to stop and remind myself that. Can get crazy going up and down the stack, handling errors and exceptions in different ways. It's also very easy in many languages to use exceptions for non-"exceptional" control-flow even though they aren't really meant for that.
- z9znz 4y agoI'm not sure I buy your definitions for errors and exceptions. In practice, many errors are rare cases and are essentially unexpected. They are exceptions in terms of being exceptional results compared to most results. The biggest challenge with error -- or exception -- handling is that most callers are not prepared to deal with something other than success. So the safest thing for them to do is push the failure up, with the expectation that somewhere higher will be equipped to deal with it. If you take TFA's CopyFile as an example, there are plenty of scenarios where copying a file would be part of some complex process. If the file copy fails, it probably indicates either a logic problem (bad path, empty filename, something) or an OS level failure. Either of those cases cannot be dealt with at layers close to the CopyFile call. From TFA example, the guard only eliminates the if err != nil { return err }. This is a bigger problem than can be solved with syntactic sugar. And from my perspective, it is why exceptions exist. If you merrily go on your way in some other languages and try to copy, but that fails, it will generate an exception. If you don't explicitly handle that exception in your calling function, then it will bubble up. If somewhere upstream expects this possibility, it can be designed to respond to a specific type of exception and do something reasonable about it. But your calling function, down here at a low level, will not have any clue what the business logic behavior should be if the CopyFile() fails.
- scatterhead 4y ago> What is a Golang person... a Goist? A Goer (hehe, Monty Python). Since I am a goer, I'll use Goist here. Gopher. > Is it the Erlang or the Elixir folks to just say, paraphrased, "let it die"? That sounds like panic. When the Erlang folks say that, they're talking about letting a process die. The rest of the application is in different processes and doesn't get taken down. So the offending process can be rebooted and operations can continue. > if err != nil { return err } // put it on one line. It's clean and natural. Oh.. erm... well that's explicitly not letting it die. That's returning it and forcing it to be manually "dealt with", as you put it. It seems like you're contradicting yourself. Also, the article explains that returning without context is often a bad idea.
- z9znz 4y ago> Gopher Now I know what being old means. It means you can make references to things, and younger people will completely overlook them. Of course I can do a small bit of internet search to get the answer to my rhetorical question. But I thought (wrongly) that it would be more entertaining to make a Monty Python reference. "Is your wife a goer? Know what I mean?" > that's explicitly not letting it die. That's returning it and forcing it to be manually "dealt with" That is letting it die in the sense of not handling the error locally. It is allowing the failure to go upstream, and either assuming the caller will handle it, blow up, or further pass it up. > Erlang As I understand it, the supervisor processes ensure that the workers are up and running. If one dies, it gets restarted within the constrants of failure count limits and such. Instead of handling errors, you can choose to allow a failure to blow up the "process" (it's not a full OS process, I believe) and be comforted in the knowledge that your process will be restarted. If you look at many business processes (take web app activities for example), you see that failures don't get resolved in perfect tidy fashion. Instead of trying to handle the multitude of possible failure cases, you just accept that many failures cannot be recovered from. You just let it silently die, and you maybe provide a general "sorry, try again" message to the user. That is acceptable in a lot of cases, especially when it is virtually impossible to properly handle all failure cases gracefully. Imagine if a user were uploading an image to a web app, and CopyFile() failed. How would you handle that? Would you tell the user, "Sorry, we got your upload, but we couldn't put it in its proper place, so it failed. Try again."? Or could you let it "blow up" and just tell the user, "upload failed; try again". Now imagine you try to handle failure cases and properly report them all upstream. Now if you write tests, your tests must test for the success path and multitudes of possible failure cases and resolutions. In practice, this just is not done (outside special high risk scenarios like commercial flight and such).
- Jayschwa 4y ago> What is a Golang person Gopher
- z9znz 4y agoI'm sorry. We're all on the internet, and I could have looked it up myself. It was really a rhetorical question as well as an opportunity to enjoy a memory of the Monty Python nudge nudge wink wink skit: https://youtu.be/4Kwh3R0YjuQ?t=25 https://youtu.be/4Kwh3R0YjuQ?t=25