←back to thread

Parse, Don't Validate (2019)

(lexi-lambda.github.io)
389 points melse | 2 comments | | HN request time: 0s | source
Show context
seanwilson ◴[] No.27640953[source]
From the Twitter link:

> IME, people in dynamic languages almost never program this way, though—they prefer to use validation and some form of shotgun parsing. My guess as to why? Writing that kind of code in dynamically-typed languages is often a lot more boilerplate than it is in statically-typed ones!

I feel that once you've got experience working in (usually functional) programming languages with strong static type checking, flakey dynamic code that relies on runtime checks and just being careful to avoid runtime errors makes your skin crawl, and you'll intuitively gravitate towards designs that takes advantage of strong static type checks.

When all you know is dynamic languages, the design guidance you get from strong static type checking is lost so there's more bad design paths you can go down. Patching up flakey code with ad-hoc runtime checks and debugging runtime errors becomes the norm because you just don't know any better and the type system isn't going to teach you.

More general advice would be "prefer strong static type checking over runtime checks" as it makes a lot of design and robustness problems go away.

Even if you can't use e.g. Haskell or OCaml in your daily work, a few weeks or just of few days of trying to learn them will open your eyes and make you a better coder elsewhere. Map/filter/reduce, immutable data structures, non-nullable types etc. have been in other languages for over 30 years before these ideas became more mainstream best practices for example (I'm still waiting for pattern matching + algebraic data types).

It's weird how long it's taking for people to rediscover why strong static types were a good idea.

replies(10): >>27641187 #>>27641516 #>>27641651 #>>27641837 #>>27641858 #>>27641960 #>>27642032 #>>27643060 #>>27644651 #>>27657615 #
ukj ◴[] No.27641651[source]
Every programming paradigm is a good idea if the respective trade-offs are acceptable to you.

For example, one good reason why strong static types are a bad idea... they prevent you from implementing dynamic dispatch.

Routers. You can't have routers.

replies(3): >>27641741 #>>27642043 #>>27642764 #
kortex ◴[] No.27641741[source]
Sure you can. You just need the right amount of indirection and abstraction. I think almost every language has some escape hatch which lets you implement dynamic dispatch.
replies(1): >>27641809 #
ukj ◴[] No.27641809[source]
This is a trivial and obvious implication of Turing completeness. Why do you even bother making the point?

With the right amount of indirection/abstraction you can implement everything in Assembly.

But you don't. Because you like all the heavy lifting the language does for you.

First Class citizens is what we are actually interested in when we talk about programming language paradigm-choices.

https://en.wikipedia.org/wiki/First-class_citizen

replies(3): >>27641950 #>>27641980 #>>27641983 #
mixedCase ◴[] No.27641983{4}[source]
Did you mean something other than "dynamic dispatch", or what do you mean by "first class support"?

No offense, but your claim sounds like you're confused to me, but maybe I am the one confused. AFAIK I do dynamic dispatch all the time in strongly typed languages. Can you show an example that a strongly typed language can't accomplish?

replies(1): >>27642516 #
ukj ◴[] No.27642516{5}[source]
>I do dynamic dispatch all the time in strongly typed languages.

I believe semantics is getting in our way of communicating.

You don't do dynamic dispatch ___ALL___ the time. You only do it at runtime. And you only do static type safety at compile time. Those are different times.

You can't have both of those features at the __SAME TME__, therefore you can't have both features ALL the time. They are mutually exclusive.

replies(2): >>27643104 #>>27643160 #
1. Jtsummers ◴[] No.27643104{6}[source]
Dynamic dispatch is literally a runtime feature of a language. That's why it's called "dynamic". GP can absolutely use dynamic dispatch "all the time" in the sense that they use it regularly in their program, perhaps in every or nearly every program they write.

Your statement is verging on the nonsensical, like saying to someone "You don't use integers all the time, sometimes you use strings, they're different things." Well, duh?

EDIT: Also, it's discouraged on this site in general to use all caps for emphasis. *phrase* produces an italicized/emphasized form with phrase.

replies(1): >>27645393 #
2. ukj ◴[] No.27645393[source]
I am using a perfectly sensible notion of "dynamic" (e.g NOT static) when I am talking about "dynamic dispatch".

Registering pointers to new implementations at runtime (adding entries to the dispatch table) Unregistering pointers to old implementations at runtime (removing entries from the dispatch table).

If your dispatch table is immutable (e.g static!), there's nothing dynamic about your dispatch!