←back to thread

Parse, Don't Validate (2019)

(lexi-lambda.github.io)
389 points melse | 1 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 #
ImprobableTruth ◴[] No.27642043[source]
Huh? Could you give a specific example? Because e.g. C++ and Rust definitely have dynamic dispatch through their vtable mechanisms.
replies(1): >>27642108 #
ukj ◴[] No.27642108[source]
Do you understand the difference between compile time and runtime?

Neither C++ nor Rust give you static type safety AND dynamic dispatch because all of the safety checks for C++ and Rust happen at compile time. Not runtime.

replies(4): >>27642140 #>>27642147 #>>27642150 #>>27642761 #
jsnell ◴[] No.27642150[source]
I think you might need to define what you mean by dynamic dispatch, because it is very clearly something totally different than how the term is commonly understood.
replies(1): >>27643462 #
ukj ◴[] No.27643462[source]
Deciding which implementation of a function handles any given piece of data at runtime.

Trivially, because you don’t have this knowledge (and therefore you can’t encode it into your type system) at compile time.

replies(1): >>27644291 #
justinpombrio ◴[] No.27644291[source]
Aha! I think I have debugged your thinking. Wow you made that hard by arguing so much.

Apparently you do know what dynamic dispatch is, you're just wrong that it can't be type checked.

In Java, say you have an interface called `Foo` with a method `String foo()`, and two classes A and B that implement that method. Then you can write this code (apologies if the syntax isn't quite right, it's been a while since I've written Java):

    Foo foo = null;
    if (random_boolean()) {
        foo = new A();
    } else {
        foo = new B();
    }
    // This uses dynamic dispatch
    System.out.println(foo.foo())
This uses dynamic dispatch, but it is statically type checked. If you change A's `foo()` method to return an integer instead of a String, while still declaring that A implements the Foo interface, you will get a type error, at compile time.
replies(1): >>27644679 #
ukj ◴[] No.27644679[source]
So, there is nothing dynamic about that dispatch.

Because the implementation details of Foo are actually know at compile time. Which is why you are able to type-check it.

You have literally declared all allowed (but not all possible) implementations of Foo.

What happens when Foo() is a remote/network call?

replies(2): >>27644720 #>>27644901 #
justinpombrio ◴[] No.27644901[source]
That is not what dynamic dispatch means! It is an extremely well established term, with a very clear meaning, and that is not what it means.

I thought you were just mistaken about something, but no, instead you've redefined a well understood term without telling anyone, then aggressively refused to clarify what you meant by it and argued for hours with people, while saying they were all wrong when they used the well established term to mean its well established meaning.

The thing you're talking about is an interesting concept, but it's not called dynamic dispatch, and you will confuse everyone you talk to if you call it that. I don't know if there's a term for it.

replies(2): >>27644974 #>>27648858 #
ukj ◴[] No.27644974[source]
“Well established” doesn’t mean anything.

According to who?

Computer scientists talk about “well formed” not “well established”.

Those are categorical definitions.

replies(1): >>27645075 #
justinpombrio ◴[] No.27645075[source]
> According to who?

Wikipedia, every textbook you can find, the top dozen search results for "dynamic dispatch", me who has a PhD in computer science plus all the other CS PhD people I know, everyone in my office who knows the term (who are industry people, not academia people), every blog post I have ever read that uses the term, and all the other HN commenters except you. I'm really not exaggerating; a lot of CS terms have disputed meanings but not this one.

EDIT: Sorry all for engaging the troll. I thought there might have been some legitimate confusion. My bad.

replies(2): >>27645217 #>>27647108 #
1. ukj ◴[] No.27645217{8}[source]
So which textbook contains the meaning of "meaning"?

Oh, that's recursive! Which is Computer Science's domain of expertise, not the public domain.

We are talking about formal semantics here. What do programs (and computer languages are themselves programs) mean?

Point 0 of Wadler's law.

https://en.wikipedia.org/wiki/Semantics_(computer_science)

If you can type-check it at compile time then it is NOT dynamic dispatch. It's a contextual confusion.