6 ms·
Static analysis is definitely preferable to cross-compilation and this looks like a great tool. That said, the idea that static type checking makes developers m
by drderidder 12y ago
Static analysis is definitely preferable to cross-compilation and this looks like a great tool. That said, the idea that static type checking makes developers more productive and prevents tons of errors is overstated imho. Type inference is supposed to make coding simpler and more productive (particularly in functional languages) - even C++11 has added it. I'm sure static type checking can benefit some organizations, but in my experience, type related errors are usually easy to find and fix and have rarely if ever been the root cause of our most difficult problems. Dynamic type checking and implicit conversion is one of the more powerful features of JavaScript and certainly no less prone to error or counter-productive than type-casting, making variadic functions or class templates are in other languages.
- inglor 12y agoThis is a form of cross-compilation kind of like how TypeScript is cross compilation. It does require a build step to produce JavaScript - you will not be able to enjoy fiddles as easily and so on. Then again their rationale is very clear and pretty good: You need builds if you're using Facebook's stack anyway (for JSX) so this should not interfere with your current build - which you have to do anyway.
- slashnull 12y agoIf only to remove syntactically invalid type annotations, I guess. Strong typing is not incompatible with the absence of run-time typing information, due to the magic of type erasure.
- ufo 12y agoType erasure is only safe if the whole program is statically typed though - you are still going to need to use runtime checks if you want to interface with dynamic code.
- slashnull 12y agoWell yeah nobody talked about removing JS's duck typing algo.
- oyvindkinsey 12y agoBased on the inference, we can imagine a case where Flow would flag certain boundaries as 'unsafe', allowing a transform to inject dynamic type safety checks using the same type information Flow has available. For instance, you could imagine a function calling into some unknown api, where we would need to constrain the type of the variable to the expected one to avoid `any` being applied to it. While the library files do provide typing of external dependencies, this doesn't protect you from bugs in those libraries! The same applies to api's that are explicitly typed as `any`, but which should return a certain type. Having Flow add a dynamic assertion on the type here would allow the rest of the program to remain type safe, knowing that a violation is guaranteed to halt execution. While dynamic strong typing is also used at Facebook, we're not quite ready to launch this as an extension to Flow.
- drderidder 12y agoReally? It appears to be much more of a static analysis tool than a cross-compiled psuedo-syntax. Here's what it outputs: flow examples/01_HelloWorld/hello.js /hello.js:7:5,19: string This type is incompatible with hello.js:4:10,13: number Found 1 error
- inglor 12y agoEDIT: looks like it supports type annotations similar to closure compiler's (in docs) https://github.com/facebook/flow/blob/master/tests/docblock/docblock.js https://github.com/facebook/flow/blob/master/tests/docblock/... Try running an annotated file in the browser - it's simply not valid ECMAScript syntax and no JavaScript runtime will run it 'as is'. If the code requires transformation by a compiler aware of the language semantics and syntax - it's transpiling in my book. Just like TypeScript is a superset of ECMAScript - so is Flow (in a much lighter, closer to source sense it seems).
- masklinn 12y ago> Try running an annotated file in the browser - it's simply not valid ECMAScript syntax and no JavaScript runtime will run it 'as is'. Of course not, but the point was that it's not a different language, it simply adds type annotations. If you strip out the type annotations, it should be a valid JS file.
- inglor 12y agoThis is also true for TypeScript though. The only thing that's not directly JS in TypeScript is shims for new JS features (from ES6) not yet implemented.
- masklinn 12y ago> This is also true for TypeScript though. AFAIK none of these are valid javascript, event assuming ES6: * class-level variables (resolved as instance variables) * field visibility * initializer constructors (constructor without a body automatically assigning to a field) * enum types That is, you can't remove type annotations (and `interface` declarations which can probably get a pass) and end up with valid JS, which seems to be what flow yields.
- stiff 12y agoJavaScript is a bit special in this respect, I think. Because of the weird type coercion rules, and how it treats null, undefined and because of the presence of NaN many common coding mistakes end up producing mysterious errors pointing somewhere far away from the place in the code that actually produced the problem in the first place. Basically JavaScript continues propagating null/undefined/NaN in many situations where other languages, including other dynamic ones like Ruby and Python, raise an error much earlier. There are other issues as well, JavaScript doesn't check function arity on function calls (the arguments not supplied just get the "undefined" value), control structures do not introduce a new lexical scope etc.
- jackweirdy 12y agoReally? I find it happens as often as NullPointerExceptions. Viva la Maybe type
- drderidder 12y agoYeah, that can be confusing. On the other hand, if you write unit / functional tests then testing for invalid inputs one of the first things you'll probably do. Your comment makes me think a fuzzer to test all those falsey values could be useful.
- stiff 12y agoA lot of JavaScript is UI code though, so unit tests might not be possible, and a suite of comprehensive functional tests with something like Selenium gets dog slow very fast, in my experience.
- nardi 12y agoIn general, this argument is self-defeating: "I don't need a type checker because I write unit tests." Obviously that means you need a type checker, because then you don't have to write 70-90% of your unit tests. Unit tests require time and energy to produce, run, and maintain. A type-checking compiler can remove much of this burden from the developer.
- ep103 12y ago
- jallmann 12y ago> the idea that static type checking makes developers more productive and prevents tons of errors is overstated Then perhaps you are understating the importance of software correctness. While type systems can be an almost religious topic, the benefits of type checking are real -- a whole class of bugs to disregard, less testing code, and a more maintainable codebase for other developers. Moreover, for languages with ADTs and exhaustive type-checking, you are forced to reason about boundary and error conditions. All of which leads to higher quality software, at the minimal cost of up-front work when designing your types and fixing what the compiler/checker says. > type related errors are usually easy to find and fix and have rarely if ever been the root cause of our most difficult problems. Type related errors may be easy to diagnose and fix -- although by definition, in the absence of type-checking, type errors are only so after the fact, eg after causing a crash. Hence the utility of type checkers, especially if it means fewer avoidable errors appearing in production. > Dynamic type checking and implicit conversion is one of the more powerful features of JavaScript and certainly no less prone to error or counter-productive than type-casting, making variadic functions or class templates are in other languages. Type checking doesn't diminish the usefulness/convenience of dynamic languages, but IMO lends more weight to the benefits of strongly static languages -- benefits which are negated by the abuse of "features" such as typecasting or variadic functions.
- drderidder 12y agoNo, software correctness is paramount. I see your point (speaking as a c/c++ dev of realtime software)...but, software correctness is independent of static vs dynamic type checking or implicit type conversion, wouldn't you say? I see companies who feel they don't need automated testing because of TypeScript, or whatever, which concerns me a bit. A trickier problem in JS with completely compatible number types is floating point arithmetic, for example. Anyway, that's why I'm glad this tool is a static code analyzer; it can benefit both the strict typing folks as well as those who want to leverage dynamic types.
- Joeri 12y agoStatic analysis is somewhat like having very minimalistic type-only unit tests. If you already have comprehensive unit tests, you don't benefit much, but if you don't you really notice the quality difference in the code that ships when you run static analysis prior to shipping.
- slashnull 12y agoI like to think that static typing haven't delivered its promises because the current statically typed languages and toolage is inappropriate and immature, but I realize that this might be a symptom of the Smug LISP Weenie syndrome that affects me.
- jamii 12y agoI just ran flow on our js constraint solver and it caught a bug. The dirty checker used && instead of & to check the dirty variables bitflag against the interested propagators bitflag so it was silently doing more work than it had to. I wouldn't even have noticed that there was a problem. We've had plenty of other bugs in the past months that tooks hours to track down but would have been caught in seconds in a sensible language. A lot of them won't be caught by flow either, unfortunately. What I really want is for operations like key lookup to fail instead of just returning me gibberish. Typecasting is at least explicit. In js every single operation is a timebomb.
- lmm 12y ago> in my experience, type related errors are usually easy to find and fix and have rarely if ever been the root cause of our most difficult problems. In a language without a strong type system you rarely appreciate quite how many of your invariants could be lifted into the type system. When I wrote Python most of my errors didn't seem like type errors (e.g. I remember forgetting to close a connection and so leaking connections), but now that I write Scala I can see how I'd structure my program using types so that that would be a type error (I'd use monads to compose the idea of an operation that uses a connection, and then execute them in one place). (Python now has an ad-hoc fix for this specific problem in the form of the "with" statement, just as 3.4 adds an ad-hoc fix for the proliferation of different ways of doing async calls. But a good type system is a general solution to both these problems and more). > Dynamic type checking and implicit conversion is one of the more powerful features of JavaScript In a strongly typed language you can do this in a controlled way; it can be part of the language, and can apply equally well to user-defined structures. Whereas with Javascript you're stuck with those implicit conversions built into the language, and if you want to convert e.g. an address datatype, you're out of luck. > certainly no less prone to error or counter-productive than type-casting, making variadic functions or class templates are in other languages. Then use a language that doesn't have those problems either. There are good languages out there - if Scala isn't for you then how about OCaml or Haskell?