frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

fp.

Open in hackernews

Parse, Don't Validate and Type-Driven Design in Rust

https://www.harudagondi.space/blog/parse-dont-validate-and-type-driven-design-in-rust/
64•todsacerdoti•2h ago

Comments

dang•1h ago
Recent and related: Parse, Don't Validate (2019) - https://news.ycombinator.com/item?id=46960392 - Feb 2026 (172 comments)

also:

Parse, Don’t Validate – Some C Safety Tips - https://news.ycombinator.com/item?id=44507405 - July 2025 (73 comments)

Parse, Don't Validate (2019) - https://news.ycombinator.com/item?id=41031585 - July 2024 (102 comments)

Parse, don't validate (2019) - https://news.ycombinator.com/item?id=35053118 - March 2023 (219 comments)

Parse, Don't Validate (2019) - https://news.ycombinator.com/item?id=27639890 - June 2021 (270 comments)

Parsix: Parse Don't Validate - https://news.ycombinator.com/item?id=27166162 - May 2021 (107 comments)

Parse, Don’t Validate - https://news.ycombinator.com/item?id=21476261 - Nov 2019 (230 comments)

Parse, Don't Validate - https://news.ycombinator.com/item?id=21471753 - Nov 2019 (4 comments)

(p.s. these links are just to satisfy extra-curious readers - no criticism is intended! I add this because people sometimes assume otherwise)

jaggederest•1h ago
You can go even further with this in other languages, with things like dependent typing - which can assert (among other interesting properties) that, for example, something like

    get_elem_at_index(array, index)
cannot ever have index outside the bounds of the array, but checked statically at compilation time - and this is the key, without knowing a priori what the length of array is.

"In Idris, a length-indexed vector is Vect n a (length n is in the type), and a valid index into length n is Fin n ('a natural number strictly less than n')."

Similar tricks work with division that might result in inf/-inf, to prevent them from typechecking, and more subtle implications in e.g. higher order types and functions

VorpalWay•1h ago
How does that work? If the length of the array is read from stdin for example, it would be impossible to know it at compile time. Presumably this is limited somehow?
jaggederest•1h ago
If the length is read from outside the program it's an IO operation, not a static variable, but there are generally runtime checks in addition to the type system. Usually you solve this as in the article, with a constructor that checks it - so you'd have something like "Invalid option: length = 5 must be within 0-4" when you tried to create the Fin n from the passed in value
ratorx•1h ago
It doesn’t have to be a compile time constant. An alternative is to prove that when you are calling the function the index is always less than the size of the vector (a dynamic constraint). You may be able to assert this by having a separate function on the vector that returns a constrained value (eg. n < v.len()).
mdm12•1h ago
One option is dependent pairs, where one value of the pair (in this example) would be the length of the array and the other value is a type which depends on that same value (such as Vector n T instead of List T).

Type-Driven Development with Idris[1] is a great introduction for dependently typed languages and covers methods such as these if you're interested (and Edwin Brady is a great teacher).

[1] https://www.manning.com/books/type-driven-development-with-i...

marcosdumay•56m ago
If you check that the value is inside the range, and execute some different code if it's not, then congratulations, you now know at compile time that the number you will read from stdin is in the right range.
dernett•55m ago
Not sure about Idris, but in Lean `Fin n` is a struct that contains a value `i` and a proof that `i < n`. You can read in the value `n` from stdin and then you can do `if h : i < n` to have a compile-time proof `h` that you can use to construct a `Fin n` instance.
esafak•23m ago
I wish dependent types were more common :(
cmovq•1h ago
Dividing a float by zero is usually perfectly valid. It has predictable outputs, and for some algorithms like collision detection this property is used to remove branches.
woodruffw•1h ago
I think “has predictable outputs” is less valuable than “has expected outputs” for most workloads. Dividing by zero almost always reflects an unintended state, so proceeding with the operation means compounding the error state.

(This isn’t to say it’s always wrong, but that having it be an error state by default seems very reasonable to me.)

cmovq•54m ago
It’s more so that dividing by zero is not an error in IEE754, so it would be more unexpected to have your float divide operator return a Option<f32>
noitpmeder•1h ago
This reminds me a bit of a recent publication by Stroustrup about using concepts... in C++ to validate integer conversions automatically where necessary.

https://www.stroustrup.com/Concept-based-GP.pdf

  {
     Number<unsigned int> ii = 0;
     Number<char> cc = '0';
     ii = 2; // OK
     ii = -2; // throws
     cc = i; // OK if i is within cc’s range
     cc = -17; // OK if char is signed; otherwise throws
     cc = 1234; // throws if a char is 8 bits
  }
strawhatguy•1h ago
The alternative is one type, with many functions that can operate on that type.

Like how clojure basically uses maps everywhere and the whole standard library allows you to manipulate them in various ways.

The main problem with the many type approach is several same it worse similar types, all incompatible.

packetlost•1h ago
I don't really get why this is getting flagged, I've found this to be true but more of a trade off than a pure benefit. It also is sort of besides the point: you always need to parse inputs from external, usually untrusted, sources.
doublesocket•1h ago
Agree with this. Mismatching types are generally an indicator of an underlying issue with the code, not the language itself. These are areas AI can be helpful flagging potential problems.
fiddlerwoaroof•1h ago
Yeah, there's something of a tension between the Perlis quote "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures" and Parse, don't validate.

The way I've thought about it, though, is that it's possible to design a program well either by encoding your important invariants in your types or in your functions (especially simple functions). In dynamically typed languages like Clojure, my experience is that there's a set of design practices that have a lot of the same effects as "Parse, Don't Validate" without statically enforced types. And, ultimately, it's a question of mindset which style you prefer.

strawhatguy•50m ago
There's probably a case for both. Core logic might benefit from hard types deep in the bowels of unchanging engine.

The real world often changes though, and more often than not the code has to adapt, regardless of how elegant are systems are designed.

marcosdumay•59m ago
There are more than two alternatives, since functions can operate in more than one type.
Rygian•49m ago
This sounds like the "stringly typed language" mockery of some languages. How is it actually different?
sam0x17•1h ago
btw the “quoth” crate makes it really really easy to implement scannerless parsing in rust for arbitrary syntax, use it on many of my projects
IshKebab•28m ago
Interesting looking crate. You don't seem to have any examples at all though so I wouldn't say it makes it easy!
hutao•31m ago
Note that the division-by-zero example used in this article is not the best example to demonstrate "Parse, Don't Validate," because it relies on encapsulation. The principle of "Parse, Don't Validate" is best embodied by functions that transform untrusted data into some data type which is correct by construction.

Alexis King, the author of the original "Parse, Don't Validate" article, also published a follow-up, "Names are not type safety" [0] clarifying that the "newtype" pattern (such as hiding a nonzero integer in a wrapper type) provide weaker guarantees than correctness by construction. Her original "Parse, Don't Validate" article also includes the following caveat:

> Use abstract datatypes to make validators “look like” parsers. Sometimes, making an illegal state truly unrepresentable is just plain impractical given the tools Haskell provides, such as ensuring an integer is in a particular range. In that case, use an abstract newtype with a smart constructor to “fake” a parser from a validator.

So, an abstract data type that protects its inner data is really a "validator" that tries to resemble a "parser" in cases where the type system itself cannot encode the invariant.

The article's second example, the non-empty vec, is a better example, because it encodes within the type system the invariant that one element must exist. The crux of Alexis King's article is that programs should be structured so that functions return data types designed to be correct by construction, akin to a parser transforming less-structured data into more-structured data.

[0] https://lexi-lambda.github.io/blog/2020/11/01/names-are-not-...

fph•29m ago
The article quickly mentions implementing addition:

```

impl Add for NonZeroF32 { ... }

impl Add<f32> for NonZeroF32 { ... }

impl Add<NonZeroF32> for f32 { ... }

```

What type would it return though?

alfons_foobar•11m ago
Would have to be F32, no? I cannot think of any way to enforce "non-zero-ness" of the result without making it return an optional Result<NonZeroF32>, and at that point we are basically back to square one...

EDuke32 – Duke Nukem 3D (Open-Source)

https://www.eduke32.com/
65•reconnecting•1h ago•21 comments

Parse, Don't Validate and Type-Driven Design in Rust

https://www.harudagondi.space/blog/parse-dont-validate-and-type-driven-design-in-rust/
65•todsacerdoti•2h ago•25 comments

I Don't Like Magic

https://adactio.com/journal/22399
52•edent•3d ago•23 comments

I verified my LinkedIn identity. Here's what I handed over

https://thelocalstack.eu/posts/linkedin-identity-verification-privacy/
1014•ColinWright•14h ago•378 comments

Toyota Mirai hydrogen car depreciation: 65% value loss in a year

https://carbuzz.com/toyota-mirai-massive-depreciation-one-year/
36•iancmceachern•3h ago•86 comments

How an inference provider can prove they're not serving a quantized model

https://tinfoil.sh/blog/2026-02-03-proving-model-identity
53•FrasiertheLion•15h ago•28 comments

How far back in time can you understand English?

https://www.deadlanguagesociety.com/p/how-far-back-in-time-understand-english
245•spzb•3d ago•157 comments

Inputlag.science – Repository of knowledge about input lag in gaming

https://inputlag.science
38•akyuu•2h ago•5 comments

What not to write on your security clearance form (1988)

https://milk.com/wall-o-shame/security_clearance.html
328•wizardforhire•4h ago•128 comments

Canvas_ity: A tiny, single-header <canvas>-like 2D rasterizer for C++

https://github.com/a-e-k/canvas_ity
30•PaulHoule•3h ago•13 comments

zclaw: personal AI assistant in under 888 KB, running on an ESP32

https://github.com/tnm/zclaw
26•tosh•9h ago•17 comments

CXMT has been offering DDR4 chips at about half the prevailing market rate

https://www.koreaherald.com/article/10679206
112•phront•7h ago•77 comments

Personal Statement of a CIA Analyst

https://antipolygraph.org/statements/statement-038.shtml
83•grubbs•4h ago•44 comments

Cloudflare outage on February 20, 2026

https://blog.cloudflare.com/cloudflare-outage-february-20-2026/
112•nomaxx117•2h ago•80 comments

MeshTNC is a tool for turning consumer grade LoRa radios into KISS TNC compatib

https://github.com/datapartyjs/MeshTNC
10•todsacerdoti•1h ago•3 comments

Claws are now a new layer on top of LLM agents

https://twitter.com/karpathy/status/2024987174077432126
128•Cyphase•21h ago•541 comments

Loon: A functional lang with invisible types, safe ownership, and alg. effects

https://loonlang.com
50•surprisetalk•1d ago•29 comments

Permacomputing

https://wiki.xxiivv.com/site/permacomputing.html
62•tosh•4d ago•12 comments

Acme Weather

https://acmeweather.com/blog/introducing-acme-weather
149•cryptoz•14h ago•96 comments

A solver for Semantle

https://victoriaritvo.com/blog/semantle-solver/
45•evakhoury•3d ago•11 comments

Online Pebble Development

https://cloudpebble.repebble.com/
3•teekert•1h ago•0 comments

Show HN: Iron-Wolf – Wolfenstein 3D source port in Rust

https://github.com/Ragnaroek/iron-wolf
47•ragnaroekX•6h ago•17 comments

Padlet (YC W13) Is Hiring in San Francisco and Singapore

https://padlet.jobs
1•coffeebite•9h ago

Uncovering insiders and alpha on Polymarket with AI

https://twitter.com/peterjliu/status/2024901585806225723
104•somerandomness•1d ago•98 comments

AI uBlock Blacklist

https://github.com/alvi-se/ai-ublock-blacklist
190•rdmuser•13h ago•79 comments

Be wary of Bluesky

https://kevinak.se/blog/be-wary-of-bluesky
173•kevinak•22h ago•132 comments

Microsoft team creates data-storage system that lasts for millennia

https://www.nature.com/articles/d41586-026-00502-2
65•gnabgib•3d ago•56 comments

A16Z partner says that the theory that we'll vibe code everything is ' wrong'

https://www.aol.com/articles/a16z-partner-says-theory-well-050150534.html
62•paulpauper•23h ago•75 comments

The Software Development Lifecycle Is Dead

https://boristane.com/blog/the-software-development-lifecycle-is-dead/
14•zenon_paradox•3h ago•12 comments

Keep Android Open

https://f-droid.org/2026/02/20/twif.html
1950•LorenDB•1d ago•670 comments