6 ms·
Flow is much better with opaque types. Also nominal types for classes. And correct variance. And adhering to liskov substitution principles. And exact objec
by mirekrusin 3y ago
Flow is much better with opaque types.
Also nominal types for classes.
And correct variance.
And adhering to liskov substitution principles.
And exact object types.
And spread on types matching runtime behavior.
And proper no transpilation mode with full access to the language.
And has 10x less LoC than ts.
ps. before somebody says "flow is dead" have a look at flow contributions [0] vs typescript contributions [1]
[0] https://github.com/facebook/flow/graphs/contributors https://github.com/facebook/flow/graphs/contributors
[1] https://github.com/microsoft/TypeScript/graphs/contributors https://github.com/microsoft/TypeScript/graphs/contributors
- eyelidlessness 3y agoFWIW, classes in TypeScript become nominal types when they have a non-public member. But I definitely do feel real FOMO over Flow’s opaque types.
- mirekrusin 3y agoYes, ts is full of this kind kind of adhoc-ifs-like glued together, also exactness check only when it's literal object etc. Flow is more principled.
- eyelidlessness 3y agoI mean. I think this specific case is a lot more principled than you seem to think. It’s certainly well reasoned from a perspective of structural typing by default.
- mirekrusin 3y agoYes, they have their reasons. They always do, tradeoff etc, I know. It doesn't change the fact that ie. adding private member is breaking change in your library which is kind of funny (until it's not funny of course). Also stuff like: class Foo { private foo = 1 } class Bar {} const a: Bar = new Foo ...typechecks so that's it for nominality. It's all ifs all the way down.
- eyelidlessness 3y agoIt’s only a breaking change if you’ve been using a class to stand in for an interface (happens to the best of us I’m sure!). You can still avoid it being one after the fact by introducing a non-breaking interface consistent with what you were already accepting/expecting. And yeah, I’m not a fan of that class instance assignability case. Not to make excuses for it, but I have other reasons I generally prefer to expose interfaces (distinct from classes, even if they’re identical in shape and even have the same internal purpose) at most API boundaries; avoiding that particular footgun just turns out to be a nice happy side effect of the preference.
- nsonha 3y ago> adhering to liskov substitution principles what does this even mean? > And has 10x less LoC than ts Prolly b/c Flow isn't able to express the advanced types (albeit with 10x LoC) in the first place.
- mirekrusin 3y agoYou can google, gpt or look at wikipedia for "liskov substitution principles". It's related to object oriented programming, more specifically to inheritance and what is allowed as substitution as superclass vs subclass depending on which position it sits in argument vs return value. It's very interesting read if you don't know about it and you're using OOP. What advanced types do you have in mind? ps. the way you're using "albeit" sounds like you think flow has 10x larger codebase, it has 10x smaller codebase
- nsonha 3y agoI know what SOLID is, questioning how exactly you think Flow has "liskov substitution" as a feature.
- mirekrusin 3y agoL in SOLID refers to Liskov substitution principles. It's the only one from the SOLID list which can be typechecked - others are design principles. "Flow adhering to it" means that violating code will be flagged by type system. It matters because unlike other principles, violations can cause runtime errors.
- nsonha 3y ago> L in SOLID refers to Liskov substitution you think? > Flow adhering to it" means that violating code will be flagged by type system Shocking that type system can flag things
- recursive 3y agoCheck out the react codebase, which is presumably the flagship use of flow. It has hundreds of FLOW FIXME annotations. It's easier have a lot of features and small code base if the you don't handle the difficult cases.
- hu3 3y agoOnly hundreds? Not bad then. I expected thousands.
- mirekrusin 3y agoIt's the other way around. Handling difficult cases leads to more type errors. If type system is lax, it won't flag them but they can fail at runtime. React has very little of $FlowFixMe annotations for its codebase. In typescript projects on the other hand it's normal to see unsafety as normal code (casting, non null assertions, implicit and explicit anys etc).
- recursive 3y agoReact vs "typescript projects" doesn't seem very fair. React would presumably be the pinnacle of style with respect to flow. Maybe not true, but it's not just some random project. Additionally, I've read a lot of typescript code, and the react codebase. My experience is different than yours. I see more type workarounds in react. FWIW "$FlowFixMe" occurs 822 times in commit hash cf5ab8b8b2c92523aba0b982fb403add053a9110 out of 498900 lines of *.js source. That includes blanks and comments. I don't have any good stats on the occurrence of type assertions in typescript.
- mirekrusin 3y agoYes, it's probably not fair. I think you're double counting it (original files + emitted files)? git clone git@github.com:facebook/flow.git grep -roh '$FlowFixMe' flow | wc -l 423 Yes, it's not easy to grab good stats, my experience is that in ts projects you have much more of explicit type annotations vs flow which has better inference, a lot of type casting (unsafe), implicit and explicit anys (unsafe), null assertions (unsafe), unsafe OO etc. The code in flow has very interesting feel. Missing explicit type annotations are noticeable, feels like js. Optional names in type signature means functions have very Haskell'ish feel: const foo /*: number => string */ = x => x.toString() I use flow in comments so I don't have transpilation. Access to full language means a lot here. Typescript has some nice things that flow doesn't (ie. template literal types) - but recent activity in flow is very interesting. They've put a lot of effort into making flow understand typescript constructs. Many people don't realize how close they now became. Even some constructs are implemented first in flow (type guards, in ts scheduled for not yet released v5.5 I believe; NoInfer landed first in flow), then in typescript. It seems they have opportunity to make flow compatible with typescript enough that you could consume ts typedefs from flow - and when it happens it's definitely going to help opening doors wider for adoption. [0] https://github.com/search?q=repo%3Afacebook%2Fflow+%24FlowFixMe&type=code https://github.com/search?q=repo%3Afacebook%2Fflow+%24FlowFi...
- vundercind 3y agoTried Flow first, back in the day. I was ready to give up the whole idea as not-at-all-worth-the-trouble if Typescript had been as mediocre an experience. Fortunately it wasn’t and now I get to not-hate working in JavaScript.
- mirekrusin 3y agoYes there was a time when atom/vscode integration was shit. They also fucked up typings in terms of community management. Those two alone probably put them into downward spiral. But the language is being developed with activity stronger than ever. And it is well designed and pleasure to code in.
- deleted 3y ago[deleted]
- baw-bag 3y agoflow is dead (for jobs). I'm gonna annihilate Dart (apart from jobs)
- mirekrusin 3y agojava is great for jobs as well.
- yen223 3y agoFlow regularly crashed with bizarre segfaults errors, the last time I used it.
- mirekrusin 3y agoSounds like vscode integration few years ago, yes.