Live data from Hacker News

How “let it fail” leads to simpler code

yiming.dev

61–70 of 165 posts

Re: How “let it fail” leads to simpler code

#61

I learned from working on aviation systems is that when a system enters an unknown state, it must be disabled and locked out. In software, this is known as an assertion failure. When the assert trips, the program is, by definition, in an unknown state. A program cannot reasonably be allowed to continue in an unknown state - it may launch nuclear missiles. The only thing to be done is exit directly, do not pass Go, do…

What if the plane is mid flight?

Engage the backup. Everything flight critical is dual.

Re: How “let it fail” leads to simpler code

#63
post #35

The article doesn’t seem to look at how resources are cleaned up when a BEAM process crashes. https://elixirforum.com/t/understanding-the-advantages-of-le... says “All resources are owned by a process in Erlang, and the VM guarantees clean-up of resources once the process dies”. My Google-fu failed me when I searched for more details about Erlang process cleanup of resources, or how to register cleanup actions (e.g.…

I’d take a look at the terminate callback for Elixir GenServers.

https://hexdocs.pm/elixir/1.12/GenServer.html#c:terminate/2

Re: How “let it fail” leads to simpler code

#64
One of the pieces of software I'm most proud of is a service to manage the dynamic part of our infrastructure. It uses control theory and let it fail to great effect.

The service reads the state of the system, and applies change to converge to a configured policy. If it encounter an error, it doesn't try to handle or fix it, it just fails and logs a fine grained metric, plus a general error metric.

The system fails all the time at this scale, but heals itself pretty quickly. In over 1 year of operation it hasn't caused a single incident, and it has survived all outages.

Re: How “let it fail” leads to simpler code

#65
post #14

For all the hate that Java tends to get, the language natively supports this distinction between: * Expected errors - Checked Exceptions * Unexpected errors - Unchecked Exceptions Idiomatic Java also makes heavy use of asserts, e.g. using the Guava Preconditions library.

Expected errors that need to pass through a lambda - unchecked exceptions.

Our good friend UncheckedIOException.

Re: How “let it fail” leads to simpler code

#66
post #14

For all the hate that Java tends to get, the language natively supports this distinction between: * Expected errors - Checked Exceptions * Unexpected errors - Unchecked Exceptions Idiomatic Java also makes heavy use of asserts, e.g. using the Guava Preconditions library.

Alas, the problem with java, which I say as a begrudging long time java developer, is that "supports this distinction" is a theoretical benefit that is seldom used in practice. Checked and unchecked exceptions get so thoroughly abused and twisted into byzantine contraptions that any distinction, if value were to be gained from it, is completely destroyed by the common free form usage throughout the ecosystem. The pre…

What kind of precondition and what kind of example do you have for the typing? My primary precondition is null checks, which is unavoidable

Re: How “let it fail” leads to simpler code

#67
post #7
post #5

I've seen a lot of new developers shocked by this approach, which surprises me a little. They seem to think that it's up to the application to handle all errors, even those of the programmer(s). This, of course, is unreasonable since it would essentially require knowing all the bugs in advance. :-)

I'm a big fan of the "crash early" strategy. I write in Swift primarily, and if I suspect a state is impossible to reach, I'll add a fatalError() so that in development, if it turns out I'm wrong, I spot it right away. (Something I learned from another dev I worked with, who was very productive.) Unfortunately, a lot of other devs hate to see that your code may actually crash and start asking questions about what sce…

> if I suspect a state is impossible to reach, I'll add a fatalError()

Does Swift have assert statements? If so, is there a reason you chose this method instead?

Re: How “let it fail” leads to simpler code

#68

A corollary or generalized interpretation of this approach (and someone please specify if there’s a formal term for this) is: “fail locally, and immediately.” What I mean is that once something unexpected happens your code should ideally fail in that step itself. The simplest most common example I’ve seen with python programmers is when they pass around dicts as arguments in complex code bases. Methods expect various…

>Solutions and suggestions would be appreciated!

Ban the usage of default values or default parameters anywhere outside of top-level / public facing functions. Plus assert everything all the time.

I've gotten into arguments with other developers over it but I'll take the inconvenience in developing now over tearing hair out over bugs later, anytime.

Re: How “let it fail” leads to simpler code

#69
post #44
post #38

Earlier quoted context omitted.

>Solutions and suggestions would be appreciated! Use a language with strong typing?

Yeah, that one is indeed obvious. That's what everyone advocating for static typing (which you mean, somebody commented already) has been shouting all the time. The problems coming from dynamic typing are just unnecessary, and the only thing that made python palpable for me again was mypy, which introduces static typing into python. But it's not the default, so it still only really works for small things.

We use pytype as well but nothing works runtime right?

I implemented a “check_type” decorator I use in many places but am starting to think I should decorate all the methods in my code with this decorator while building it or something.

Re: How “let it fail” leads to simpler code

#70
post #7
post #5

I've seen a lot of new developers shocked by this approach, which surprises me a little. They seem to think that it's up to the application to handle all errors, even those of the programmer(s). This, of course, is unreasonable since it would essentially require knowing all the bugs in advance. :-)

I'm a big fan of the "crash early" strategy. I write in Swift primarily, and if I suspect a state is impossible to reach, I'll add a fatalError() so that in development, if it turns out I'm wrong, I spot it right away. (Something I learned from another dev I worked with, who was very productive.) Unfortunately, a lot of other devs hate to see that your code may actually crash and start asking questions about what sce…

Yeah. My pet peeve is `guard let … else { return }` instead of force-unwrapping. Like, why do people think that silently swallowing an error is better than crashing loudly and clearly?
Post reply on HN