Hacker News new | ask | show | jobs
by cannabis_sam 1544 days ago
This question actually has a simple answer:

Most languages have embraced statements over expressions for a lot of language constructs.

This causes a lot of issues:

An if-statement is in essence a function from boolean to unit/() (i.e. from a barely useful type to a type with no useful information), while an if-expressions will contain enough type information to at least provide this kind of “flow typing”, (even if it induces an amount of boolean blindness.)

It’s even worse when you get to loop-statements, which often is a function from unit/() to (unit/() | bottom/⊥), compared to a map or a reduce or fold, which again provide enough type information to provide this kind of “flow typing”.

Sometimes you will of course need to provide impure conditionals or loops, but that can be made explicit in the type system.

IMHO statements in programming languages are an anti-pattern.

2 comments

Almost all of the languages I know that do "flow typing" (TypeScript, Flow, Hack), "smart casts" (Kotlin), or "type promotion" (Dart) are fairly statement-oriented.

Expression-based languages tend to have pattern matching which provides another way to solve the same problem.

Flow typing is most useful in imperative languages where code like this is common:

    if (foo is! Bar) return "not a Bar";
    foo.someBarMethod();
Early returns and other imperative control flow is idiomatic and it's annoying if the static type system doesn't understand it.

In a more functional or expression-oriented language, early returns and other imperative control flow like that is rarer, so there's less "flowing" to type over.

How does pattern matching solve the same problem?
It gives you a very nice notation for checking if a value has some type and, if so, binding a new variable that refers to it as that more specific type.
How does that solve the problem of statements being devoid of return information?

Also, what? Pattern matching differentiate between values of a single type, and while the assignment mechanism is a great nice-to-have, it still completely follows the basic type consistency that actually typed functions provide.

Statements have none of these qualities..

I'm sorry, but we seem to be talking past each other.

Why is it a problem that statements are "devoid of return information"? A statement occurs in a position where, by definition, no value it produces will be used.

> Most languages have embraced statements over expressions for a lot of language constructs.

Some of the most used languages with flow typing have statements and follow them for typing, so that is emphatically not the reason.

My view might of course be a bit outdated, do you have any examples?

(Specifically for this point: “and follow them for typing”)

The example in TFA. TypeScript.
So my point stands…?