Live data from Hacker News

Why don't more languages offer flow typing?

ayazhafiz.com

51–60 of 127 posts

Re: Why don't more languages offer flow typing?

#51

So I've been working on a personal project which is in a mix of C++ and TypeScript -- partially because of practicality and partially to learn TypeScript, and I'm really liking the language. One question I have is whether there's any possibility that TypeScript could, in the long run, gain performance advantages over pure JS? That the compiler could leave behind some type information artifacts so that V8 (or similar)…

Unfortunately a big issue in TypeScript is that objects can and surprisingly often do have the completely wrong type. Some libraries even blatantly violate their TypeScript types. So any optimizations which take advantage of TypeScript types are likely to lead to very hard to debug behavior.

A better option is to make/use a language which interfaces well with JavaScript but is not JavaScript and actually checks it’s types. If the type system is actually be sound, and any code going in from JavaScript is type-checked at runtime, then compiler optimizations are reasonable.

As for your last point, I know that JIT-compilers like V8 can and do infer types at runtime (e.g. by noticing if a particular variable or function arg is always set to the same type) and will compile specialized function overloads which take advantage of the inferred type for optimizations (e.g. using fixed-width integers even though all JavaScript numbers are doubles).

Re: Why don't more languages offer flow typing?

#52
See also “Occurrence Typing” in Typed Racket. [^1]

> One of Typed Racket’s distinguishing type system features is occurrence typing, which allows the type system to ascribe more precise types based on whether a predicate check succeeds or fails.

One of the big advantages is that it lets a text editor use the added information to supply better auto-complete suggestions. It also makes it possible to eliminate some safety checks at runtime because the type checker has ensured that certain calls will be safe based on prior conditional checks.

[^1]: https://docs.racket-lang.org/ts-guide/occurrence-typing.html

Re: Why don't more languages offer flow typing?

#53

Earlier quoted context omitted.

Dynamic and strong typing are not opposed (dynamic and static typing are opposed, and, to the extent the distinction is valid, weak and strong typing are opposed), dynamic doesn't mean everything is physically boxed (most dynamic language implementations don't box some subset of small primitive values, usually including bools and small ints), and, in any case, flow typing is a feature of static type systems (though s…

> dynamic and static typing are opposed Any given typing judgement we might want to make about a particular term can be checked statically or not, and it can be checked dynamically or not. If the language has terms (... that might be evaluated) that don't get checked statically or dynamically, then it is going to be weakly typed (with respect to those typing judgements we're considering). If we've already checked som…

Something that's checked dynamically is not a "typing judgment", by definition. It's a proposition established at runtime, possibly even with non-trivial data attached describing "how" the dynamic check succeeds, and possibly affecting program operation in its own right as that proposition object gets "passed" to downstream functions that depend on that dynamic check. These are two altogether different things.

Re: Why don't more languages offer flow typing?

#54
post #36

Earlier quoted context omitted.

In the end, I feel like structural typing is one of those attractive nuisances. It sounds good on the outset, and it does provide a limited amount of convenience, but then it turns out not to be that convenient, and it removes a lot of safety and flexibility by taking intent out of the thing.

That depends on where it's used. For example, Rust's traits bounds are structurally typed, for exemple making a function that accepts a type that's Summary + Display. This "Summary + Display" type doesn't need to have a name, and in that case it's great. On the other hand sometimes you want to have two strings, one that's a name and the other the address, and not substitute one with the other. I don't think there is…

> For example, Rust's traits bounds are structurally typed, for exemple making a function that accepts a type that's Summary + Display. This "Summary + Display" type doesn't need to have a name, and in that case it's great.

That's still nominative. The bound is not named, but it's based on names, not on structure. Otherwise you couldn't have marker types in such a bound, or would always have all of them and be unable to opt out.

> I don't think there is "a" solution, only multiple solutions and tradeoffs.

I have a hard time seeing that: if you have a structure, you can always give it a name. But you can also give different names to the same structure. So a nominative type system is more flexible and powerful at the very limited cost of having to name things. And even then, nominative type systems can support anonymous types (where the name is simply implicit / automatically generated) e.g. lambdas in C++ or Rust.

Re: Why don't more languages offer flow typing?

#55

Earlier quoted context omitted.

Another very common case in TypeScript (and other languages) is union types. Other languages have constructs for checking the underlying type of a union type directly, but typescript is smart enough to figure it out based off of the properties of the constituent types and what you've checked so far in your code. e.g. interface A { type: 'a' } interface B { type: 'b' } type C = A | B; const c: C = ...; if (c.type ===…

That's basically case 1, right? The compiler knows which type is being used at each call site, so it can generate a separate function for each type in the union and eliminate the type check/dead branches. I guess the exception would be if you have a non-homogenous array that you try to map over. In that case there's probably no way around boxing the values.

For consts and function arguments yes, I think. But you could have some mutable variable or field whose value depends on runtime state. In that case, you could have an actual polymorphic type.

Re: Why don't more languages offer flow typing?

#56
I looove flow typing / type narrowing. HTDP taught how to think through it (data type narrowing / checking for and handling different types) while building functions. TypeScript let's me enforce the same process with intellisense warning me whenever I get off track. It's been a joy to see how quickly and solidly the code stacks up.

Re: Why don't more languages offer flow typing?

#57
post #33
post #28

Earlier quoted context omitted.

I think the majority of the convenience of structural typing can be had with explicit casting between structurally equivalent types. It eases pressure on the type checker (checking that two types are structurally equivalent is pretty quick, checking that any expression satisfies something structurally is a little harder) and gets you ultimately what a programmer wants - convenience.

Go's interfaces are a decent 80/20 answer. You pay for them, you opt in, and they sit on type of the base type system, they aren't the primitive the entire type system is based on and they aren't what the compiler works with at the most basic level. I have on a number of occasions wished I could define an interface that could be fulfilled by a field without me having to write a method, but it's not a use case that co…

> Go's interfaces are a decent 80/20 answer. You pay for them, you opt in, and they sit on type of the base type system, they aren't the primitive the entire type system is based on

That's interesting because I see them as the exact opposite. You're not saving or gaining anything of significance, and it's just increasing confusion.

Penny wise, pound foolish, if you will.

Re: Why don't more languages offer flow typing?

#59

Earlier quoted context omitted.

Way before 1.0 (IIRC), Rust in fact used to have structural records, and wanted to try to only have them. But due to the challenges described by you and the article, they went back to regular nominal ADTs. I do think think that was the right call at that time.

In the end, I feel like structural typing is one of those attractive nuisances. It sounds good on the outset, and it does provide a limited amount of convenience, but then it turns out not to be that convenient, and it removes a lot of safety and flexibility by taking intent out of the thing.

There is a fundamental tradeoff between cost-free upcasts and efficient layout, but languages could offer both options and many in between.

IMO in general: in the face of tradeoffs, moving the goal posts to let the programmer decide is an unexplored 3rd option.

Re: Why don't more languages offer flow typing?

#60

Earlier quoted context omitted.

> dynamic and static typing are opposed Any given typing judgement we might want to make about a particular term can be checked statically or not, and it can be checked dynamically or not. If the language has terms (... that might be evaluated) that don't get checked statically or dynamically, then it is going to be weakly typed (with respect to those typing judgements we're considering). If we've already checked som…

Something that's checked dynamically is not a "typing judgment", by definition. It's a proposition established at runtime, possibly even with non-trivial data attached describing "how" the dynamic check succeeds, and possibly affecting program operation in its own right as that proposition object gets "passed" to downstream functions that depend on that dynamic check. These are two altogether different things.

Sure. Tip: if something's true by definition, it's usually not interesting. Substitute the appropriate phrase - "observation of a property which, in the static context, might constitute a typing judgement"? Note that we're here specifically considering things that can be typed statically, as outside of that setting there is no question of whether static and dynamic are opposed.

The rest of your comment seems concerned with the fact that the tagging infrastructure typically needed to check these properties at runtime can also be used for other purposes. That's true, but I don't see the relevance.

Post reply on HN