Hacker News new | ask | show | jobs
by jamesisaac 2717 days ago
So, I was one of (or I suppose the only...) person in the linked issue arguing that competition is useful, and that it makes sense for Facebook's products to be tied into the same ecosystem.

As others have mentioned, when Flow was first launched, TS had an extremely limited type system (e.g. no null checking, no union types). Of course this has improved a lot over time, as the two have converged, but there's still a long way to go for either project to allow JS reach the level of correctness and expressiveness of, say, OCaml or Haskell.

Flow has consistently for the past few years been bringing new ideas to the table from this algebraic data types background, which often have ended up proving to be good ideas, and are in various stages of trickling down to TS.

I worry that if the ecosystem becomes completely dominated by TS, the overall focus will end up back where TS started: rudimentary OOP inspired types, without the underlying goal of overall correctness, which Flow strives for, while TS openly eschews in favour of "pragmatism".

1 comments

You can’t have the same level of correctness as ocaml if you want to maintain the compatibility with JavaScript. Typescript type system is unsound for this reason. You can’t have anything approaching ocaml correctness when in typescript all objects with the same shape are interchangeable.
Yeah I realise you'd never reach the same level of soundness due to the limitations of the underlying JS (although presumably you could get close with a subset?). But that's why it's an interesting challenge, and I think what Flow has shown is that it's possible to get a lot closer than had previously been imagined.

If everyone just accepted the argument 4 years ago that "JS will never be sound" then maybe today TS would still just be Java style `interface` annotations for classes. It's not like the Flow team has reached a ceiling at this point... there's still plenty on their roadmap that would continue to improve soundness and expressiveness.

> You can’t have anything approaching ocaml correctness when in typescript all objects with the same shape are interchangeable.

Could you elaborate? Flow has recently switched to exact objects by default[1], which I would have thought would be enough for a sound approach?

[1] https://medium.com/flow-type/on-the-roadmap-exact-objects-by...

For example in typescript this is valid:

    type A = {name: string}
    type B = {name: string}
    function print(obj: A) { alert(obj.name);}
    let a: A = {name: “hello”};
    let b: B = {name: “world”}
    print(a);
    print(b);
This is because of typescript structural equality and I think that the same applies to flow given your link. Obviously if I want a function to accept an email I don’t want the same function to accept an address, but in typescript you can’t guarantee it because you have no way to get rid of structural equality as far as I understood.
Ah I see. That can be achieved since Flow 0.51 with opaque types[1][2]. It seems like TypeScript hasn't yet caught up with this functionality[3].

[1] https://medium.com/flow-type/hiding-implementation-details-w...

[2] https://flow.org/en/docs/types/opaque-types/

[3] https://github.com/Microsoft/TypeScript/issues/15807#issueco...

Yup that seems to help.
I'm certainly not well versed in OCaml, but my understanding is that it is also structurally typed. This particular example would also be permitted in OCaml, correct?
No, records are nominally typed in OCaml, thus the two types `A` and `B` would be deemed incompatible.
But objects in OCaml are structurally typed (well, row typed).