Live data from Hacker News

Parse, Don't Validate (2019)

lexi-lambda.github.io

151–160 of 175 posts

Re: Parse, Don't Validate (2019)

#151
post #96

Earlier quoted context omitted.

In the spirit of "Parse, Don't Validate", rather than encode "validation" information as a boolean to be checked at runtime, you can define `Email { raw: String }` and hide the constructor behind a "factory function" that accepts any string but returns `Option ` or `Result `. If you need a stronger guarantee than just a "string that passes simple email regex", create another "newtype" that parses the `Email` type fur…

I would still usually prefer email as just a string and validation as a separate property, and they both belong to some other object. Unless you really only want to know if XYZ email exists, it's usually something more like "has it been validated that ABC user can receive email at XYZ address". Is the user account validated? Send an email to their email string. Is it not validated? Then why are we even at a point in…

> I would still usually prefer email as just a string and validation as a separate property, and they both belong to some other object. Unless you really only want to know if XYZ email exists, it's usually something more like "has it been validated that ABC user can receive email at XYZ address".

> Is the user account validated? Send an email to their email string. Is it not validated? Then why are we even at a point in the code where we're considering emailing the user, except to validate the email.

You are looking at this single type in isolation. The benefit of an email type over using a string to hold the email is not validating the actual string as an email address, it's forcing the compiler to issue an error if you ever pass a string to a function expecting an email.

Consider function `foo`, which takes an email and a username parameter.

This compiles just fine but is a logic error:

    void foo (char *email, char *username);
    ...
    char *my_email = parse_input ();
    char *my_user = parse_input ();
    foo (my_user, my_email);
Using a separate type for email means that this refuses to compile:

    void foo (email_t *email, char *username);
    ...
    email_t *my_email = parse_input ();
    char *my_user = parse_input ();
    foo (my_user, my_email); // Compiler error
I hope you can see the value in having the compiler enforce correctness. I have a blog post on this, with this exact example.

Re: Parse, Don't Validate (2019)

#152
post #100
post #7

Earlier quoted context omitted.

> In most strong statically typed languages, you wouldn't often pass strings and generic dictionaries around. In 99% of the projects I worked on my professional life, anything that is coming from an human input is manipulated as a string and most of the time, it stays like this in all of the application layers (with more or less checks in the path). On your precise exemple, I can even say that I never saw something l…

At first I had a negative reaction to that comment and wanted to snap back something along the lines of "that's horrible" as well, but after thinking for a while, I decided that if I have anything to contribute to the discussion, I have to kinda sorta agree with you, and even defend you. I mean, of course having a string, when you mean "email" or "date" is only slightly better than having a pointer, when you mean a s…

> So, when you model data "correctly" and turn "2026-02-10 12:00" (or better yet, "10/02/2026 12:00") into a "correct" DateTime object, you are making a hell lot of assumptions, and some of them, I assure you, are wrong.

I think that's the benefit of strong typing: when you find an assumption is wrong, you fix it in a single place (in this example, the DateTime object).

If your datetime values are stored as strings everywhere in your code:

a) You are going to have a bad day trying to fix a broken assumption in every place storing/using a datetime, and

b) Your wrong assumptions are still baked in, except now you don't have a single place to fix it.

Re: Parse, Don't Validate (2019)

#153

Earlier quoted context omitted.

This is such a tired take. The burden of using static types is incredibly minimal and makes it drastically simpler to redesign your program around changing business requirements while maintaining confidence in program behavior.

People keep saying this and yet in the decades of my career the industry bounces between being fully dynamic and fully typed according to the affordability of senior engineers. What you are saying are covered by tests, not types.

> What you are saying are covered by tests, not types.

You know Haskell programmers write tests, right?

Re: Parse, Don't Validate (2019)

#154

Earlier quoted context omitted.

> no amount of static typing will save you from poorly defined or optimised-too-early types that encode business logic constraints into programmatic types. That's not a fault of type systems, though. > because business logic will move faster than whatever code you can write and fix, and exposing it as just "types" breaks the process for future programmers to extend your program That's a problem with overly-tight coup…

> overly-tight coupling, poor design, and poor planning yeah imagine if you could foresee the future five years in advance. People overestimate their ability to use type systems correctly, as shown in your reply here.

It has worked out well for me for 15 years or so.

Re: Parse, Don't Validate (2019)

#155

I'm not very familiar with functional programming and Haskell in particular. I think I understand the gist of this article, and "use data structures that make illegal states unrepresentable". However, is there a similar article but written with more common languages (C#, C++, Java, Go) in mind? Or is a big part of this concept only relevant for strong functional languages with sum types and pattern matching?

It is relevant to all languages with static type checkers from idris to python. But of course since it is about expressing properties via the type system the more expressive that is the easier and more applicable.

Java has sum types, incidentally. And pattern matching.

Re: Parse, Don't Validate (2019)

#156
post #78

Earlier quoted context omitted.

that's a bit of a hairy situation. You're doing it wrong. Or not really, but.. complicated. As per [RFC 5321]( https://www.rfc-editor.org/rfc/rfc5321.html ): > the local-part MUST be interpreted and assigned semantics only by the host specified in the domain part of the address. You're not allowed to do that . The email address `foo@bar.com` is identical to `foo@BAR.com`, but not necessarily identical to `FOO@bar.com…

These days the world assumes that all parts of emails are case-insensitive, even if RFC5321 says otherwise. If it’s true for Google, Outlook & Apple mail then it’s basically true everywhere & everyone else has to get with the program. If you don’t want to lose potentially important email then you need to make sure your own systems are case-insensitive everywhere. Otherwise you’ll find out the hard way when a customer…

Genuinely curious: Are non-ascii characters also case-insensitive. With Unicode comes different case-sensitivity rules according to Unicode version and locale.

Re: Parse, Don't Validate (2019)

#157

Maybe I'm missing something and I'm glad this idea resonates, but it feels like sometime after Java got popular and dynamic languages got a lot of mindshare, a large chunk of the collective programming community forgot why strong static type checking was invented and are now having to rediscover this. In most strong statically typed languages, you wouldn't often pass strings and generic dictionaries around. You'd nat…

I worked (a long time ago) on a C project where every int was wrapped in a struct. And a friend told me about a C++ project where every index is a uint8, uint16, and they have to manage many different type of objects leading to lots of bugs.. So it isn't really linked to the language.

Re: Parse, Don't Validate (2019)

#158

Maybe I'm missing something and I'm glad this idea resonates, but it feels like sometime after Java got popular and dynamic languages got a lot of mindshare, a large chunk of the collective programming community forgot why strong static type checking was invented and are now having to rediscover this. In most strong statically typed languages, you wouldn't often pass strings and generic dictionaries around. You'd nat…

> Edit: Changed this from email because email validation is a can of worms as an example Email honestly seems much more straightforward than dates... Sweden had a Feb 30 in 1712, and there's all sorts of date ranges that never existed in most countries (e.g. the American colonies skipped September 3-13 in 1752).

It’s a ISO-standard to use Gregorian dates even for dates predating its invention. If you need to support anything else (I never had to in my Eurocentric work so far), you’ll need to model calendars, similar to how temporal did for JavaScript: https://tc39.es/proposal-temporal/docs/calendars.html

Re: Parse, Don't Validate (2019)

#159

Earlier quoted context omitted.

> I don't like to title drop, but I am a Staff Data Engineer I am a Chief Technology Officer[^1]. Your opinion here is common, and misguided. Here is why: https://lexi-lambda.github.io/blog/2020/01/19/no-dynamic-typ... --- [^1]: Literally nobody cares.

That's an insular opinion piece that doesn't sway, especially in the age of AI agents, it has not aged well. Its shallow rejection of Rich Hickey's nuance, is also unconvincing. It is a polemical justification for a coding philosophy that is incomplete and dishonest about the benefits of alternatives. Thanks for reminding me that no one cares; important to reinforce that.

That's quite the shallow dismissal, and the bit about AI agents is a particularly weird non sequitur — King's argument is about what type systems can and cannot express. AI agents don't change the relationship between static types and open-world data processing.

It sounds like you're annoyed that Hickey's position was effectively challenged.

Re: Parse, Don't Validate (2019)

#160

Maybe I'm missing something and I'm glad this idea resonates, but it feels like sometime after Java got popular and dynamic languages got a lot of mindshare, a large chunk of the collective programming community forgot why strong static type checking was invented and are now having to rediscover this. In most strong statically typed languages, you wouldn't often pass strings and generic dictionaries around. You'd nat…

Strong static type checking is helpful when implementing the methodology described in this article, but it is besides its focus. You still need to use the most restrictive type. For example, uint, instead of int, when you want to exclude negative values; a non-empty list type, if your list should not be empty; etc. When the type is more complex, specific contraints should be used. For a real live example: I designed…

> The number of occupants of a room must be positiv and a child must be accompanied by at least one adult. My type Occupants has a constructor Occupants(int adults, int children) that varifies that condition on construction (and also some maximum values).

Or, you could do what I did when faced with a similar problem - I put in a PostgreSQL constraint.

Now, no matter which application, now or in the future, attempts to store this invalid combination, it will fail to store it.

Doing it in code is just asking for future errors when some other application inserts records into the same DB.

Business constraints should go into the database.

Post reply on HN