Live data from Hacker News

How “let it fail” leads to simpler code

yiming.dev

161–165 of 165 posts

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

#161

Earlier quoted context omitted.

What you're describing are "known" states; the idea behind "let it fail" is that you shouldn't write code that exhaustively handles every single potential outcome, just the ones that are part of your code's path in general use. Definitely write code to handle network issues. Don't write code to handle random bitflips, ways to handle garbage coming back from the service you're connecting to, or try to handle OOM error…

> Don't write code to handle random bitflips It depends what you're doing. There's no fixed threshold for "errors that you should handle" so smackeyacky is right - handle the errors you can (but don't spend an inordinate amount of time handling very unlikely errors). Bitflips are not very unlikely on huge systems so you need to handle them. In my experience trying to distinguish between "expected" or "normal" errors…

Handle errors you should.

Don’t handle errors that aren’t relevant to your specific code.

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

#162
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…

they did indent by 3 spaces Probably a compromise between 2 and 4?

I suggested exactly that as a joke over a decade ago, then decided to try it out. Ended up I really liked it, and still use it for all my personal code.

I do stick to 4 spaces at work though.

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

#163

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…

Coming back from TypeScript to Python, I found that most recent (3.10+) typing annotation shorthands are pretty succinct, and running mypy at all times really helps cut down on runtime errors.

My recipe:

— annotate variables, attributes, arguments and return values;

— run a good type linter (we use mypy) at all times;

— never pass around generic dictionaries: use dataclasses[0], TypedDicts, etc. instead.

That way you define a subclass inheriting from, say, TypedDict and declare that your function only takes that subclass. After that, you’ll get a loud error if you pass any dictionary that doesn’t match the spec (missing keys, wrong values, etc.)—ideally, right in your IDE.

(To reiterate, this would be a pointless exercise if you don’t lint all the time; most IDEs support this.)

[0] You can additionally use them with Pydantic, which can validate data at runtime at a cost of some performance overhead.

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

#164
post #159

Earlier quoted context omitted.

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.

I would be very interested in that!

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

#165

In a new language, I'd like to see exceptions being allowed in pure code, but prohibited in non-pure code. (Non-pure here meaning code with side effects.) In pure code, an exception could essentially be passed up, and transformed into an error return value at the point where it's called by non-pure code.

So then you make a pure function `throw_exception` and now you can throw from impure code.

In non-pure code, we would want to force the programmer to handle the exception.

In this case, wherever `throw_exception` is called, the programmer would have to handle the exception, and either refactor the return value to indicate an error, change the return value to an Optional (and silently fail by returning an empty Optional), or cause/trigger a side effect (like terminating the thread/program termination early, with an exit code).

Post reply on HN