Live data from Hacker News

Parse, Don't Validate – In a Language That Doesn't Want You To

cekrem.github.io

61–70 of 107 posts

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#61

I personally love the idea and concept, but struggle to apply to real projects. Suppose I have a User with some attributes like birthday, email and whether they have been verified. in common codebase, you can see `if (user.verified_at != null)` or something along the lines, in case of parsed code I do feel like I should have types for each of them (or interfaces): - UserWithBirthday - VerifiedUser, UnverifiedUser - U…

> Suppose I have a User with some attributes like birthday, email and whether they have been verified.

Philosophically, birthday and email are not attributes of a user. If you remove a user from existence, a birthdate and email address still exist. So...

> would you create UserWithBirthdayAndEmail type

...yes, something like a `profile { user, birthday, email }` type is necessary to compose the attributes you are interested in into something where those attributes do belong together.

> it feels like it is going to bloat the interface space, how do you tackle this problem?

Like all things formal verification, increase the level of verification in your critical sections and don't sweat the non-critical sections. How impactful will it be to your business if sending a birthday email message fails?

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#62

It is nice the author mentioned F#, because if you want to target the browser (or any JavaScript runtime), you can do from F# directly from fable ( https://fable.io ). This allows you to program by default in a type safe manner without having to play tricks to circumvent the limits of structural typing.

I suspect idiomatic TypeScript or idiomatic F# are both way better solutions in the real world than abstruse Typescript emulating idiomatic F#.

Possibly, but I think what we wish for is a language with a nominal type system that lets you switch to structural typing when needed.

Luckily, F# has type providers, which lets the compiler construct nominal types based on the structure of real data (like json, xml or any format you want), saving you from the effort of building wrapper types by hand.

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#63

Earlier quoted context omitted.

> Effect is there to find a solution but will fail. What do you mean? I'm into Effect from long time and it really scales well the more complex your applications. Schema is way more advanced than Zod by the way, both at type level and functionality it has a proper decoder/encoder architecture. You can encode "this isn't just a string -> non-empty-string -> valid email pattern" but a confirmed email the user has click…

I haven’t used Effect but the problem I see with using it is that it seems to want to completely swallow the whole app architecture. At that point, why not just use a functional language?

Yes, your hunch is correct.

Which functional language has a similarly huge ecosystem, works across the frontend/backend, has first class support of different runtimes, provides similar ergonomics, has meetups and conferences in so many countries and is easy to hire for (all you need is solid TypeScript)?

There's a reason effect-ts keeps spreading despite its syntax and learning curve, and I say it as somebody that used Haskell, functional Scala, Purescript, Elm, Racket, Elixir and tested another half a dozen.

Give me an Elixir with properly powerful types (not gleam) and I'm in.

I'd gladly throw effect and typescript especially out of my work day, but I see no sane replacement at complexity scaling.

I wouldn't personally recommend effect without a solid champion in the team and without having the complexity needs for it (I'm talking recurring durable worklows, complex encodings, suspension, retries, etc) and even if you have them the price is steep without a champion, but that's my 2 cents.

You use it for an agentic cli (opencode uses it e.g.) not a simple crud (which is 90% of web dev industry).

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#64
post #40

This is just validation that is using the type system to indicate the validation has already occurred. I think the real point of “parse, don’t validate” is to make the type system give you structural guarantees that couldn’t exist otherwise (e.g. always having a first/last element in the NonEmpty example from the original article). If you’re just branding the types as “parsed” (in reality, simply validated) you still…

"This is just validation that is using the type system to indicate the validation has already occurred. I think the real point of “parse, don’t validate” is to make the type system give you structural guarantees that couldn’t exist otherwise (e.g. always having a first/last element in the NonEmpty example from the original article)." It's the same thing. In the latter case, something has validated that your NonEmpty…

> It's the same thing. In the latter case, something has validated that your NonEmpty has a first and a last element.

No, it has parsed it into a structure that structurally has at least one element, not just the promise that there ought to be one. From the original “Parse, don’t validate” article:

    data NonEmpty a = a :| [a]
> your type still permits {name: "\0\0\0\0\0\0", host: "!"}

I actually originally wrote it with an array of EmailNameCharacters, etc but didn’t want to overcomplicate the example.

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#65

I don't like zod. I want to define my types, not write schemas. And I don't like that then I have to use the types derived from those schemas rather than types I've defined myself directly. So I just define my types and then use typescript-json-schema or similar to build a JSON Schema at build time (i.e. from an npm script) which then I use to validate input using ajv. The only thing I do on top of that is to use ann…

While I would much prefer to only write Typescript types, this would drive me insane:

> The only thing I do on top of that is to use annotations like "@minimum 0" (or, in the email example, "@format email") where the base types are not enough, but those simply go inside comments.

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#66
post #45

Zod is by far the most ergonomic way to express those ideas in TypeScript these days. I miss it when writing code in other languages. The friction with the rest of the ecosystem is real, though. Most code out there expects you to handle errors with exceptions. I get the impression that polymorphic return types could get in the way of JSC/V8/SpiderMonkey's JIT, but I haven't measured it and I'm not sure of the actual…

I haven't done a lot of Typescript, but I've done at least a couple of month's worth now, and every time I have to type "as" my inner Haskell programmer screams. If I could add one feature to Typescript it would be something like "as" that actually validates the result against the type system and can fail. Unfortunately, that's way, way easier said than done. It's the bad type of keyword that has unbounded runtime co…

"every time I have to type "as" my inner Haskell programmer screams." - most of the times you don't have to. You choose to.

"If I could add one feature to Typescript it would be something like "as" that actually validates the result against the type system and can fail." - I don't think it's fair to expect that since most of the statically typed languages will not guarantee things in runtime unless you specifically run a validation code in runtime.

There's also type guards and good old self-written validation functions you can use.

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#68
Parse, don't validate is one way of building constraints. The issue is it feeds into a tree-based view of constraints. However it does yield the philosophy of "constraints by construction".

Another is making a set of "linearly independent" configurations - except in practice it never is, is it? Has anyone actually ever had a clean CI Matrix that didn't have weird hidden edge cases, for example?

Functional programming really wants to emphasize the notion of pure functions, which have modularity and independence built in. But there are perf issues and in practice, you don't really escape the issues of "how to design constraints". Sure, you don't need inheritance and OOP and all of that, but you can easily have a tree-based view of constraints and ontology in FP as well.

(Incidentally, my view of the issue with something like Carnap's logical frameworks is that they are so general and flexible that they fail to capture anything operationally useful; yes, I know that isn't always philosophy's goal but I view the same with a lot of purported theories of everything today)

Are there any other philosophies in software that have certain distinct wins versus losses when it comes both to the organization & encoding of your constraints, and coming up with them? Tree-based hierarchal decomposition and linearly independent axes in a space are two go-to things for me.

I suppose you could design a state machine, but that requires understanding all the semantics upfront, encoding them once, and hoping that requirement changes don't mess you up.

I have seen poset-based solutions as well (actually, I think "monotonic" distributed architectures are based around this approach) but that obviously requires a very specific type of problem domain.

----

There are also some very common memes from physics-swes: such as how information cancels out over "long distances" and therefore certain kinds of abstractions are good; attractor states in idea space; or even people loving the idea of symmetry (which, granted - in physics, is truly a beautiful approach, but does not seem to generalize well to generic software engineering). But those are a bit too high level to put into a concrete software plan. Still interesting though.

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#69

I don't like zod. I want to define my types, not write schemas. And I don't like that then I have to use the types derived from those schemas rather than types I've defined myself directly. So I just define my types and then use typescript-json-schema or similar to build a JSON Schema at build time (i.e. from an npm script) which then I use to validate input using ajv. The only thing I do on top of that is to use ann…

While I would much prefer to only write Typescript types, this would drive me insane: > The only thing I do on top of that is to use annotations like "@minimum 0" (or, in the email example, "@format email") where the base types are not enough, but those simply go inside comments.

Obviously it's not ideal, but IMO it's the better option. Much better than `z.number().integer().min(0)` or whatever zod equivalent there is and then have to deal with the inferred types which among other things tend to suck for IntelliSense etc. Those annotations map directly to JSON Schema attributes.

Re: Parse, Don't Validate – In a Language That Doesn't Want You To

#70
post #15

We should make authors disclose how much AI was used to write an article. This reeks of Opus 4.8.

Why should they disclose how much AI was used to write an article?

Because it's a trapdoor function. You generate heaps of content with AI with 1:10 or 1:100 amplification of time/attention invested, but your readers spend their time reading it at 1:1.

Also, what are we doing using AI to write our blogs? Surely that's the final domain of human writing outside of our local circle?

Post reply on HN