Live data from Hacker News

How “let it fail” leads to simpler code

yiming.dev

151–160 of 165 posts

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

#151
post #37

Earlier quoted context omitted.

I was on a team for a short while (Java programmers) and their frontend code was really overly "careful". For example, they would always check if a method existed, before calling it. var o = new SomeObject(); if (o.computeSomething != null && o.computeSomething != undefined) { o.computeSomething(...); } Their reasoning was that in JavaScript (with the old syntax) you just add functions to the prototype, so you could…

Picked up by unit tests? How about some kind of system which can tell you if the method exists or not, and even possibly correct your typos, before you run the code!

Completely fair, but that's often not built into dynamic languages. My main criticism is with their nonsensical approach to dealing with the limitations of JavaScript.

As far a I know, ESlint can't detect missing methods, and they weren't even using a linter. TypeScript can, but they weren't using that.

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

#152

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…

As someone working with an extremely large Python codebase, early on we made the call to never allow dictionaries as arguments to functions (with exceptions for if the dictionary is truly arbitrary and only gets logged/persisted for human reading). We rely heavily on type annotations and dataclasses. Type system weaknesses aside, the system is rather maintainable despite its size, complexity, and domain.

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

#153

Earlier quoted context omitted.

Yes, I can guess what the code does. But can you guess what this code will do? 1 + "1" Contrast Python (a strongly typed language): >>> 1 + "1" Traceback (most recent call last): File " ", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'str' >>> [] + 1 Traceback (most recent call last): File " ", line 1, in TypeError: can only concatenate list (not "int") to list With Javascript (a weakly typed la…

> With Javascript (a weakly typed language): I'm always wary of these, because you can define that as strongly typed if it's the operation which is defined to perform the conversion internally, which IIRC is how it works in javascript. For instance the first example will do the exact same thing in Java, because addition between a string and a non-string is defined as converting the non-string to a string then concate…

I'm wary too.

Stand upon a language and look down. You get to raw physics as you go down. All the abstractions are a useful reconception, not the reality. Stand upon the language and look up. You see all the unrealized programs that can be built atop it. Focus in on the programs of a particular type: those that implement a language within the language. Spot one in particular - the one that uses say `@property` `isinstance` and `raise` and `TypeError` to always preserve type safety in every situation a person cares about.

So what I am concerned about is the behavior of the finite set of elements provided by the language and their properties. I can make claims about these concrete things - the addition operator in one language rejects by type but in another it doesn't. But I'm quickly overwhelmed by infinities when I try to do more.

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

#154

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 a…

This is exactly why I think all the discussions about the importance of error handling paths (and the aversion drive have to exceptions) are usually overblown. The most successful, and common, error handling strategy is to log and abandon the whole operation, cleaning up everything the operation left around. If you have one process per operation, this is often very well captured by doing exit() at the place of the er…

From my experience, much of this comes down to the design of the system: was some state modified prior to an error occurring? If so, can it easily be rolled back? If not, why not?

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

#155

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.

>Plus assert everything all the time.

This is where static checking comes in. Static tests should fail if it's assumed (and not asserted) that a key exists.

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

#156

Earlier quoted context omitted.

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

[deleted]

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

#157
post #93

Earlier quoted context omitted.

Yes, please give us more info about using control theory and how one might think about building such a system please..

My guess would be add assertions everywhere instead of throwing exceptions.

I don't know of a way to test this behavior (I mainly code C++ and unit test with Google Test). One could spawn a process and capture the output and return value, but that sounds a bit heavy for just testing if your error handling still works as intended.

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

#158
post #8
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. :-)

Well, there's software that can cause some degree of harm. For example through servos controlling something physical. While you still probably can't catch all of the issues, you damn better try as hard as you can within reason. I'd also wish for similar rigor from people developing whatever filesystens my data is on. :-) Fail fast is generally a good idea, if you can do it safely.

> I'd also wish for similar rigor from people developing whatever filesystens my data is on. :-)

Stable storage is a key factor in making this philosophy work. [1]

[1] https://qconlondon.com/london-2012/qconlondon.com/dl/qcon-lo...

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

#159

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…

Thanks for posting this. I have worked on non critical flight software and thought that this philosophy might work well.

I wonder how easy the certification is for such software? For work I might have to write Do178 code in the future.

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

#160
post #159

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…

Thanks for posting this. I have worked on non critical flight software and thought that this philosophy might work well. I wonder how easy the certification is for such software? For work I might have to write Do178 code in the future.

I use it in the software I write. I should do a presentation sometime about how the aviation industry should be influencing software development.
Post reply on HN