zlacker

Patterns for Defensive Programming in Rust

submitted by PaulHo+(OP) on 2025-12-05 16:34:25 | 321 points 92 comments
[view article] [source] [go to bottom]

NOTE: showing posts with links only show all posts
2. brohee+7n[view] [source] 2025-12-05 18:16:28
>>PaulHo+(OP)
The very useful TryFrom trait landed only in 1.34, so hopefully the code using unwrap_or_else() in From impl predates that...

Actually the From trait documentation is now extremely clear about when to implement it (https://doc.rust-lang.org/std/convert/trait.From.html#when-t...)

14. schnee+5J[view] [source] 2025-12-05 19:52:17
>>PaulHo+(OP)
This was posted with a (mostly) healthy discussion on lobste.rs, here's the link https://lobste.rs/s/ouy4dq/patterns_for_defensive_programmin...
◧◩◪◨
21. tczMUF+dS[view] [source] [discussion] 2025-12-05 20:40:48
>>perchi+PJ
You may wish to search for "readability at Google". Here is one article:

https://www.moderndescartes.com/essays/readability/

(I have not read this article closely, but it is about the right concept, so I provide it as a starting point since "readability" writ large can be an ambiguous term.)

◧◩◪◨⬒
32. mattar+Ue1[view] [source] [discussion] 2025-12-05 22:42:50
>>tczMUF+dS
See https://abseil.io/tips/ for some idea of the kinds of guidance these kinds of teams work to provide, at least at Google. I worked on the “C++ library team” at Google for a number of years.

These roles don’t really have standard titles in the industry, as far as I’m aware. At Google we were part of the larger language/library/toolchain infrastructure org.

Much of what we did was quasi-political … basically coaxing and convincing people to adopt best practices, after first deciding what those practices are. Half of the tips above were probably written by interested people from the engineering org at large and we provided the platform and helped them get it published.

Speaking to the original question, no, there were no teams just manually reading code and looking for mistakes. If buggy code could be detected in an automated way, then we’d do that and attempt to fix it everywhere. Otherwise we’d attempt to educate and get everyone to level up their code review skills.

◧◩◪◨
37. svat+Vv1[view] [source] [discussion] 2025-12-06 00:55:57
>>perchi+PJ
Not exactly the question you asked, but you may want to read the chapter on “Large-Scale Changes” in the “Software Engineering at Google” book: https://abseil.io/resources/swe-book/html/ch22.html
43. torgin+zO1[view] [source] 2025-12-06 04:06:22
>>PaulHo+(OP)
Defensive programming is a widely known antipattern : https://wiki.c2.com/?DefensiveProgramming

The 'defensive' nature refers to the mindset of the programmer (like when guilty people are defensive when being asked a simple question), that he isn't sure of anything in the code at any point, so he needs to constantly check every invariant.

Enterprise code is full of it, and it can quickly lead to the program becoming like 50% error handling by volume, many of the errors being impossible to trigger because the app logic is validating a condition already checked in the validation layer.

Its presence usually betrays a lack of understanding of the code structure, or even worse, a faulty or often bypassed validation layer, which makes error checking in multiple places actually necessary.

One example is validating every parameter in every call layer, as if the act of passing things around has the ability to degrade information.

◧◩◪◨
52. openun+y32[view] [source] [discussion] 2025-12-06 08:01:11
>>elbear+J02
https://hackage.haskell.org/package/base/docs/Data-Maybe.htm...

"The fromJust function extracts the element out of a Just and throws an error if its argument is Nothing."

◧◩
58. fvncc+7g2[view] [source] [discussion] 2025-12-06 10:51:40
>>swiftc+X52
Note its possible to write the example more succinctly (while having the same behavior) with:

https://docs.rs/itertools/latest/itertools/trait.Itertools.h...

◧◩◪◨
61. joseph+wj2[view] [source] [discussion] 2025-12-06 11:31:29
>>elbear+J02
> The point is Rust provides more safety guarantees than C. But unwrap is an escape hatch

Nope. Rust never makes any guarantees that code is panic-free. Quite the opposite. Rust crashes in more circumstances than C code does. For example, indexing past the end of an array is undefined behaviour in C. But if you try that in rust, your program will detect it and crash immediately.

More broadly, safe rust exists to prevent undefined behaviour. Most of the work goes to stopping you from making common memory related bugs, like use-after-free, misaligned reads and data races. The full list of guarantees is pretty interesting[1]. In debug mode, rust programs also crash on integer overflow and underflow. (Thanks for the correction!). But panic is well defined behaviour, so that's allowed. Surprisingly, you're also allowed to leak memory in safe rust if you want to. Why not? Leaks don't cause UB.

You can tell at a glance that unwrap doesn't violate safe rust's rules because you can call it from safe rust without an unsafe block.

[1] https://doc.rust-lang.org/reference/behavior-considered-unde...

◧◩
63. dwattt+Jl2[view] [source] [discussion] 2025-12-06 11:59:04
>>tayo42+EL1
Underscore acts as a wildcard, denoting that you don't want to bind a variable. Quoting the Rust reference[0]:

> Underscore expressions, denoted with the symbol _, are used to signify a placeholder in a destructuring assignment.

[0]: https://doc.rust-lang.org/reference/expressions/underscore-e...

[go to top]