Live data from Hacker News

Parse, Don't Validate (2019)

lexi-lambda.github.io

161–170 of 175 posts

Re: Parse, Don't Validate (2019)

#161
post #8

Earlier quoted context omitted.

record PhoneNumber(String value) {} Huge pain.

I’m very much a proponent of statically typed languages and primarily work in C#. We tried “typed” strings like this on a project once for business identifiers. Overall it worked in making sure that the wrong type of ID couldn’t accidentally be used in the wrong place, but the general consensus after moving on from the project was that the “juice was not worth the squeeze”. I don’t know if other languages make it eas…

In f# you can use a single case discriminated union to get that behaviour fairly cheaply, and ergonomically.

https://fsharpforfunandprofit.com/posts/designing-with-types...

Re: Parse, Don't Validate (2019)

#162
post #107

Earlier quoted context omitted.

If you spend your life talking about bool having two values, and then need to act as if it has three or 256 values or whatever, that's where the weirdness lives. In C, true doesn't necessarily equal true. In Java (myBool != TRUE) does not imply that (myBool == FALSE). Maybe you could do with some weirdness ! In Haskell: Bool has two members: True & False. (If it's True, it's True. If it's not True, it's False). Unit…

What were you expecting to find? A function which returns an empty type will always diverge - ie there is no return of control, because that return would have a value that we've said never exists. In a systems language like Rust there are functions like this for example std::process::exit is a function which... well, hopefully it's obvious why that doesn't return. You could imagine that likewise if one day the Linux…

> What were you expecting to find?

> functions like this for example std::process::exit

Re: Parse, Don't Validate (2019)

#163
post #78

Earlier quoted context omitted.

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.

I honestly have no idea!

I strongly suspect the systems that are uppercasing everything were not written to handle unicode in the first place though.

Re: Parse, Don't Validate (2019)

#164
post #162

Earlier quoted context omitted.

What were you expecting to find? A function which returns an empty type will always diverge - ie there is no return of control, because that return would have a value that we've said never exists. In a systems language like Rust there are functions like this for example std::process::exit is a function which... well, hopefully it's obvious why that doesn't return. You could imagine that likewise if one day the Linux…

> What were you expecting to find? > functions like this for example std::process::exit

I'm not astonished this isn't provided that way in a language like Haskell but I suppose I would also not be surprised if it were provided.

Re: Parse, Don't Validate (2019)

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

Python has an "email object" that you should definitely use if you're going to parse email messages in any way. https://docs.python.org/3/library/email.message.html I imagine other languages have similar libraries. I would say static typing in scripting languages has arrived and is here to stay. It's a huge benefit for large code bases.

That's for messages. The discussion was about email _addresses_. The former logically makes sense as an object, but the latter can easily be implemented as a raw string, hence the discussion.

Re: Parse, Don't Validate (2019)

#166

Earlier quoted context omitted.

The point is parse and validate are interchangeable words for the most part. If you’re parsing something you expect to be an int, but it’s a float or the letter “a” is that not invalid? Is this assessment a form of validating expectations? The line between parsing and validating doesn’t exist.

But they plainly aren't interchangeable? Just asserting that it's true doesn't make it true.

The fact that we are in disagreement here proves my point. If you pose this question to 10,000 developers, you will get mixed answers. This ambiguity is why I think the phrasing of this article (not the intent) is incorrect.

Re: Parse, Don't Validate (2019)

#167

Earlier quoted context omitted.

The point is parse and validate are interchangeable words for the most part. If you’re parsing something you expect to be an int, but it’s a float or the letter “a” is that not invalid? Is this assessment a form of validating expectations? The line between parsing and validating doesn’t exist.

But they plainly aren't interchangeable? Just asserting that it's true doesn't make it true.

That's true, but then again, don't forget the fact that words might get interpreted as different things by different people. Words like "arrow", "functor", or "validate" might get interpreted slightly differently even between people with the same background.

After all, the meaning of words is just a socially accepted meaning attached to a certain arrangement of symbols. The meaning can be whatever they want it to be. And even though each individual might interpret it slightly differently, as long as the interpretation is "compatible", communication between individuals is possible.

Arguably, it's more useful to distinguish between "parse" & "validate" and I agree with that. But based on my own experience and what I've observed when I'm trying to spread type-driven style, it looks like there's no difference in meaning between the words "parse" and "validate" for most developers. Trying to sell type-driven style via the "catchy catchphrase" "Parse, Don't Validate" will certainly backfire, confusing most people rather than making them appreciate the value of it.

In my opinion, it's not worth it to combat this "parse" & "validate" misconception for the sake of the catchphrase "Parse, Don't Validate". Why? Pure FP and type-driven style already put off most people because of the tendency to go with mathematical jargon. Why add even more unnecessary barriers when the core of it is just "utilize your type system"?

I agree with the point of the "Parse, Don't Validate" article, but I strongly dislike the "catchphrase" marketing part.

Re: Parse, Don't Validate (2019)

#168
post #23

Earlier quoted context omitted.

Without any other context? Nothing - it's just a type alias... But the context this type of an alias should exist in is one where a string isn't turned into a PhoneNumber until you've validated it. All the functions taking a string that might end up being a PhoneNumber need to be highly defensive - but all the functions taking a PhoneNumber can lean on the assumptions that go into that type. It's nice to have tight c…

one issue is it’s not a type alias but a type encapsulation. This have a cost at runtime, it’s not like in some functionnals languages a non cost abstraction.

In languages like kotlin and rust you can have a type encapsulation like this that does not exist at runtime

Re: Parse, Don't Validate (2019)

#169

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?

  > Or is a big part of this concept only relevant for strong functional languages with sum types and pattern matching?
It need not strictly be a pure functional language for type-driven style to be usable. Type-driven style only requires the fact that some type cannot be assigned to another type, so it's kind of possible to do even in a language like C, as `int a = (struct Foo) {};` would get rejected by C compilers.

However, I don't think it's doable in languages with structural type systems like Typescript or Go's interface without a massive ergonomic hit for minimal gain. Languages with a structural type system are deliberately designed to remove the intentionality of "type T cannot be assigned to type S" in exchange for developer ergonomics.

  > However, is there a similar article but written with more common languages (C#, C++, Java, Go) in mind?
For C#, there's F#-focused article, which I believe some of it can be applied to C# as well:

F# - Railway Oriented Programming - https://fsharpforfunandprofit.com/rop/

F# - Designing with Types - https://fsharpforfunandprofit.com/series/designing-with-type...

For modern Java, there is some attempt at popularizing "Data-Oriented Programming" which just rebranded "Type-driven design". Surprisingly, with JDK 21+, type-driven style is somewhat viable there, as there is algebraic data type via `record` + `sealed` and exhaustive pattern match & destructuring.

Inside Java Blog - Data-Oriented Programming - https://inside.java/2024/05/23/dop-v1-1-introduction/

Infoq - Data-Oriented Programming - https://www.infoq.com/articles/data-oriented-programming-jav...

For Rust, due to the new mechanics introduced by its affine type system, there is much more flexibility in what you could express in Rust types compared to more common languages.

Rust - Typestate Pattern - https://cliffle.com/blog/rust-typestate/

Rust - Newtype - https://rust-unofficial.github.io/patterns/patterns/behaviou...

Re: Parse, Don't Validate (2019)

#170
post #169

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?

> Or is a big part of this concept only relevant for strong functional languages with sum types and pattern matching? It need not strictly be a pure functional language for type-driven style to be usable. Type-driven style only requires the fact that some type cannot be assigned to another type, so it's kind of possible to do even in a language like C, as `int a = (struct Foo) {};` would get rejected by C compilers.…

> However, I don't think it's doable in languages with structural type systems like Typescript or Go's interface without a massive ergonomic hit for minimal gain.

Go only has structural interfaces, concrete types are nominative, and this sort of patterns tends to be more on the concrete side.

Typescript is a lot more broadly structural, but even there a class with a private member is not substitutable with a different class with the same private member.

Post reply on HN