
Facebook Launches Flow, Static Type Checker for JavaScript - davemo
https://code.prod.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-javascript/
======
DigitalSea
What a great tool. Facebook are absolutely killing with the last year or so
with all of their open source contributions and releases. First HHVM, Haxl,
React.js (amongst other things) and now Flow, this is fantastic. I am really
liking how companies like Facebook & Google are concentrating their efforts on
the web language of the future: Javascript. The support for JSX alone is a
MASSIVE feature (expected given React.js and JSX).

Good job Facebook.

~~~
kulkarnic
Is this a serious post, or are you being sarcastic? I honestly can't tell. JS
the language of the future? Why? It has probably the worst gotchas of any
language I've coded in, it's verbose, and weird scoping. Nor is it especially
nice to optimize for/with.

I can certainly see being stuck with Javascript (just like we're stuck with
the x86 instruction set even if simpler alternatives exist), but I'm not sure
it's something I rejoice about. Javascript is like anti-Batman: a language we
all deserve, but not one we need.

~~~
spion
ES6 adds lambdas, destructing assignment, default/rest/ spread arguments and
template strings - all of those reduce verbosity. And there is `let` which has
a "normal" scope, although I'm not really sure it needs that. Additionally,
generators let you use normal control flow constructs for IO, if you prefer
that to FP.

While its no Haskell, it certainly isn't much more verbose than other dynamic
languages anymore. And a typesystem like TypeScript or Flow pretty much
eliminates the rest of the gotchas.

Off the top of my head, there are two embarrassing holes: bigger integers and
parallelism. Can't think of anything else at the moment (macros maybe, but
they're a double-edged sword wrt tooling). Wonder if anything else is missing?

~~~
alexjeffrey
a cryptographically secure pseudorandom number generator would be nice, too.

~~~
ricardobeat
Server-side js has that already. On the clientside it would be useless.

~~~
ajuc
What about p2p?

~~~
nextw33k
There is a problem with JavaScript in that there is no security mechanism
currently in place to ensure the JS file you are running is what you expect to
be running.

Imagine your on your favourite social network that used a JS based encryption
in a p2p chat to your friend. On that same page advertisers are pushing
content to you. That content could be a malicious JS file which can eavesdrop
on your conversation, all the while you think its encrypted.

------
ep103
This looks like such a better step in the right direction than than the types
of tools MS and Google have been putting out. Dynamically discerning the
underlying code, and allowing optional type annotation works _with_
javascript, as opposed to attempting to turn js into a completely different
(and weakened) language.

That said, I am curious what solutions this solves that isn't already solved
by enforcing good code coverage. Full disclaimer, the largest js projects I've
worked on were in the tens of thousands of lines, not hundreds of thousands,
but type checking just seemed completely unnecessary provided a good coding
guide and test coverage were maintained and enforced.

~~~
discreteevent
The main benefit of types for me is not correctness but documentation and
tooling. It's fine not to have types in code I write myself or with one or two
others. But if I have to deal with a large codebase that I wasn't involved in
writing then types make it so much quicker to understand. Just being able to
quickly find all references to a type or all a method's call sites makes it
possible to "reverse engineer" the design from the code.

This tool claims it can do advanced inference. If it were possible to hook it
up to an editor or IDE to analyse existing untyped js in this way it could be
invaluable.

~~~
avik
We have some basic editor support, more is coming soon. Flow exposes several
commands that are useful through an editor, like type-at-pos (give it a
position, it gives you back the inferred type), suggest (give it a file, it
dumps out an annotated file), autocomplete (gives you suggestions at a given
position), etc. Also, we require annotations at module boundaries, so you're
modules are going to have well-typed interfaces that serve well for both
documentation and stability.

~~~
hyp0
I strongly agree with module typing (and being more relaxed within). Because
of caller dependence on modules, the difficulty of changing static types
becomes a benefit. Plus, they need to be documented anyway; and tooling
support helps use they as if they were primitives.

As others have said, I love the approach of inference giving static type
benefits, for free. If you get tooling support, at no extra work, why not
adopt it?

But static types can be a hard sell for JS programmers. What sort of reception
has it gotten inside facebook?

~~~
avik
Still early days but the reception has been strongly positive. We may be a
biased bunch but we like our code mostly statically typed with the flexibility
provided by dynamically typed languages. A large part of this culture is due
to the immense internal success of Hack
([http://hacklang.org/](http://hacklang.org/)).

------
slashnull
Another comment that just occurred to me: JavaScript becoming gradually typed
is an interesting reflection of the recent history of the optimization of
JavaScript interpreters, which consist of deducing where semantically dynamic
objects behave like static class instances, then inlining the accessors and
where beneficial, the "class methods", and specializing && JITing the
semantically dynamic functions that almost always take as argument "instances"
of this "class".

(ref this absolutely fascinating paper

[http://bibliography.selflanguage.org/_static/implementation....](http://bibliography.selflanguage.org/_static/implementation.pdf)

and this piece of V8 dox quoting the aforementioned paper

[https://developers.google.com/v8/design](https://developers.google.com/v8/design))

It seems that adding a type system to a dynamic language has little real
drawbacks compared to designing language and type system at the same time, for
both performance and type safety considerations.

~~~
avik
Yes, so the conclusion one might draw is that if your code is implicitly
typed, it will run fast as well as probably do well when run through a static
type checker.

------
slashnull
At last!

This all seem extremely cool.

I went straight from hacking Scala and Haskell as a hobbyist to doing (mostly)
front-end JS job, and I've always found that my code, and a lot of good
libraries I read, naturally emulate something close to Hindley-Milner typing,
by using objects as tuples/records and arrays as (hopefully well-typed) lists,
as well as the natural flexibility of objects as a poor substitute for Either
types.

I'm definitely pleased to see that the designers of this library have also
realized that strongly-typed javascript was just a few annotations and a type
inference algorithm away.

I'm just wondering why are nullable types inmplemented as such and not as a
natural consequence of full sum types, which are inexplicably absent.

~~~
inglor
Strongly typed JS is actually pretty hard - probably not by Haskell and Scala
standards - but if you take promises for example the signature of `then` is:

Promise<A,E> -> ((A -> (Promise<B,F> | B)),(E -> (Promise<C,G> | C))) ->
Promise<B|C,E|G|C>

That is - a promise's then - takes the promise (as this) and executes either a
`.then` fulfillment handler or a catch handler.

If the `fulfill` handler executes the value is unwrapped and either a new
value, or a Promise over a new value and its own type of error is returned.

Now, if the `reject` handler is executed the error is unwrapped and either a
new value, or a promise over a new value or a new error is returned.

This is quite simple and easy to use because it behaves like try/catch in the
dynamic type system of JS with recursive unwrapping - however it is
challenging to reason about when you're starting to type code and you want to
actually have correct type information with promises.

Static languages generally approach these problems with pattern matching on
the type - in JS that's not common nor is it feasible at runtime - you just
expect a value of a certain type. When I implemented promises in another
language (swift) this was a lot of fun to work through and not very trivial -
if their compiler cna do this I'd be very impressed.

Promises are just one example.

Anyway - this looks cool. I definitely agree that full sum types would've made
more sense - having explicit nullables is usually a smell (like in C#).

~~~
slashnull
I don't want to say what I'm about to say, but...

I don't care about the type signature of promises. I actually don't care about
the type of anything which has a complicated type; I think it's just
incredibly winning that I will now be able to describe the shape of the raw
data circulating in my code.

I've always found really annoying, in Haskell, to see incredibly complex type
idioms emerging to allow stuff that doesn't _really_ deserve it. And yes, I'm
talking about monad transformers.

Don't get me wrong, I think that Haskell and the typing techniques and idioms
it has fostered are a tremendous achievement, but right now, I'm more focused
on bringing my web code, which right now is unfortunately a jungle of
implicitly-typed garbage, closer to a safe and predictable better-typed form.

I tried to do that in Haskell in the back-end, but everytime I tried, I lost
mind-boggling amounts of time dealing with the monadic stack of the framework
I tried.

As the saying goes, I'm not clever enough to use dynamic typing, and bugs
happen. Unfortunately, I'm also not clever enough to use _real_ strong typing,
and nothing compiles, let alone gets done.

Hence why I'm immensely thankful to see facebook embracing gradual typing in a
way that lets me leverage my knowledge of algebraic typing.

~~~
tel
I'd like to argue from a Haskell backend perspective that monad transformers
deserve exactly the complexity they expose. They give you a handle to factor
side effects in sensible ways and to express that code requires exactly some
set of effects and no others.

It is not always clear how to factor code which does not have this rigor into
effect-typed form. It can be extraordinarily difficult to recognize what
effects are being carried out in which parts of code at first—especially if
you haven't been forced into the discipline early. Thus, I find it
unsurprising that you feel the translation effort is challenging.

But, coming from the other angle—building things with well-defined effect
typing from day zero and composing pieces atop one another to reach your final
complexity goal—works exceedingly well. Better, it forms a design which can be
translated to untyped settings and retain its nice composition properties.

Which is to say not much more than: there is some logic to all that madness
and once you're on the "other side" it's hard to judge these "incredibly
complex type idioms" as anything other than useful and nearly necessary for
sane code reasoning.

I miss transformer stacks _a lot_ when using other languages.

~~~
slashnull
... said the monk, sitting cross-legged with an air of zen inner peace ; )

I think it all boils down to considerations of idealism vs. realism, in the
end, and yes, I have to admit, I managed to get a sort of _big picture_
understanding of Yesod and its ORM, and it's definitely a cool design. Can't
say I know as much about Happstack, but the hello worlds were smaller. And the
authors didn't have to invent _two_ dependency management tools to get it to
compile... /off-topic

I actually used something akin to monads to write a quick and dirty parser
combinator library... In PHP! It was really fun, but I have to admit that it
got really hard to keep track of what was function, what was return, what was
supposed to be passed along to the next function and so on without any _real_
typing. For the first time I... I wanted monads.

But still, I have 99 problems and I'd say 97 of them are undefined, nulls,
erroneous typecasts, unexpected layers of wrapping, and so on. I wrote bad
code, my teammates did, and here we are. I want to get rid of those so that I
can, at last, have _real_ problems.

Then I'll port my REST server in Haskell ; )

~~~
tel
I'm not a big user of Yesod, so I can't speak too much to that, though it is
notoriously difficult to get Yesod to compile unless you use Stackage.

I would say that types are really difficult to do in your head. It's tedious
and error-prone. That said, the advantages are high so it's valuable, e.g.
your parser combinators in PHP.

Parser combinators are actually a great example of where monad transformers
shine. You can see them as nothing more than a stack of `State` atop `Maybe`
which dramatically simplifies the presentation and why they work. Better, you
can rip out `Maybe` and replace it with `[]` to get non-deterministic parsers
"for free"—all of the code remains the same.

I actually happened to write up about this recently:

    
    
        https://gist.github.com/tel/df3fa3df530f593646a0
    

But yeah, gradual typing is seductive for existing codebases. You _can_ just
make the jump and beat them with hammers of frustration until the compiler
gives you a thumbs up---but it's nobody's cup of tea. If you want discipline,
you are far better off setting the rules from t=0 and going from there.

Let me know when you start porting to Haskell. That'll be an exciting time.

------
paulddraper
Similar to the Google Closure Compiler
([https://developers.google.com/closure/compiler/](https://developers.google.com/closure/compiler/)),
which has been around for years, just with fewer features.

It has static type checking with optional type annotations and type inference.

It doesn't have compiler-time constants, dead code removal, inlining, or other
optimizations.

But....still really cool.

~~~
avik
One obvious thing to try is to use Flow's type inference to emit GCC
annotations and see whether those optimizations kick in. (Of course, Flow can
also try to replicate whatever GCC does, but that will take some time. No
reason not to, though.)

------
drapper
How this compares to TypeScript? At the quick glance I noted:

\- more powerful type system (union types, hurray)

\- support for JSX

\- no windows binaries

\- supports more of ES6 stuff

\- ...but has no support for modules yet

\- no generics (??)

How about performance? and workflow? Didn't yet find this: does it use a
normal "write then compile" model like TS or has something like Hack (if I'm
not mistaken it has a daemon running in the background, checking the code as
you write it).

Wonder why FB decided to roll this on instead of using TS.

~~~
inglor
Some comments on that:

\- Has other comments have said: TypeScript is getting (already in master
branch) union types.

\- Support for JSX isn't really a huge deal.

\- Windows support will probably come - it's an open source library. I hope
it's not the OCAML tooling.

You make some great points about generics and using their own type system
instead of TS, especially since TS has investments from both Microsoft and
Google (with AtScript which supersets it).

They state they use a model like Hack - and the repo also looks this way but
I'm also curious, it looks like a very peculiar choice.

------
drderidder
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.

~~~
stiff
JavaScript 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.

~~~
drderidder
Yeah, 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.

~~~
nardi
In 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.

------
fdomig
From my perspective, the static type checking is more or less the same as
TypeScript's `--noImplicitAny` option as the first example on flowtype [1]
shows, the same can be achieved with

    
    
        tsc --noImplicitAny hello.tsc
    

which will result in

    
    
        hello.ts(2,14): error TS7006: Parameter 'x' implicitly has an 'any' type.
    

I do not see much difference.

[1]: [http://flowtype.org](http://flowtype.org)

~~~
masklinn
TS bolts on a straightforward nominative type system without type unions (or
non-nullable types), so it can't handle a variable typed as `number | string`,
it'll immediately drop down to `any`. That is, flow aims to remain useful in
the face of more JS idioms. It won't make a difference between nullable and
non-nullable either, so AFAIK

    
    
        function length(x) {
          return x.length;
        }
    
        length(null);
    

can never be a compile-time error in typescript.

~~~
Arnavion
Union types are present in the master branch of the TS compiler. The compiler
also uses instanceof and typeof === ... to reduce the range of types inside a
branch, similar to Flow.

~~~
johnny_reilly
Due to ship with TypeScript 1.4 - see recent blog post:
[http://blogs.msdn.com/b/typescript/archive/2014/11/18/what-s...](http://blogs.msdn.com/b/typescript/archive/2014/11/18/what-
s-new-in-the-typescript-type-system.aspx)

------
hippich
Make sure to checkout [http://ternjs.net/](http://ternjs.net/) too. It does
not have types validation I believe, but it does many other things and in
combination with eslint allows catching most errors before packaging.

Tern.js actually detect types, and may be it would be possible for eslint to
incorporate it somehow to detect invalid use of types.

One big ternjs plus for me is the fact that tern.js knows about require.js
modules and can look in other require'd files.

~~~
nilliams
Thanks, I remember seeing this a while back but didn't realise it was
RequireJS-aware. The demo is pretty great.

------
mjackson
This is HUGE!

Thanks to everyone at Facebook who worked on this. You guys are awesome.

Also: The fact that this is written primarily in OCaml (as opposed to JS) is
an excellent example of people choosing the right tool for the job.

~~~
nevir
IMO OCaml is the wrong tool for the job in this case (even if it is a better
language for this sort of tool).

JavaScript has a weird ecosystem where it is extremely helpful to have all of
your tools in the same language. browser-based IDEs, Node, portability, etc,
and just one fewer runtime to juggle.

Same reasons why closure is awkward as a Java program.

~~~
lpw25
OCaml has excellent compile-to-JavaScript support. Facebook use this to
compile their Hack type-checker for an in-browser IDE. I imagine they do
something similar for Flow.

~~~
avsm
They do indeed use js_of_ocaml in the Flow test suite to compile the full Flow
parser to JavaScript and then test that.

See the related discussion on packaging it in the OPAM pull request:
[https://github.com/ocaml/opam-
repository/pull/3083](https://github.com/ocaml/opam-repository/pull/3083)

------
chrisan
Found a nice comparison of the various "things"(?) adding static typing to JS:
[http://www.2ality.com/2014/10/typed-
javascript.html](http://www.2ality.com/2014/10/typed-javascript.html)

------
tadruj
I really like how Facebook went about getting as much information about types
as possible without the coderess, not forcing her to do unnecessary stuff.
Behavior design on the code level at its finest.

And on the side note, I bet Facebook did this just to make nerds install OCaml
and show them the light :)

------
pgroves
Does someone know how these types of projects come to fruition in a big
company like Facebook? Are people working on them full time (with no other
workload)? Do engineers build them on the weekend? How do they get 'funded'?

~~~
nbm
That is a surprisingly hard question to answer.

I think the key is that these projects actually provide value - they make
things faster, more reliable, more scalable - whether that's the code's
execution or the people writing the code (or debugging issues, or whatever).

They generally aren't solutions seeking problems - they are responses to
problems that exist.

Engineers generally don't build things like this on the weekend - unless they
like to structure their time like that, I guess. It may or may not be a full-
time job, but the job whatever it is isn't some search for abstract
perfection, it is again to solve real problems encountered by others in the
company. Often it is a part-time component built as part of trying to solve
some more direct goal - like fighting spam, or serving bits, or whatever.

Often it is something the engineers just do - it makes sense to break things
up into libraries, or services, or whatever, and they do that, and then that
library or service is usable/useful elsewhere, and that's it. Other times they
may suggest and motivate it as a goal-in-itself in a team goal setting
situation.

I doubt that's a particularly useful answer, but maybe with further questions
I can make it more useful to you?

~~~
logicalmind
I find this type of work within companies (like google's famous 20% rule) an
interesting contrast with non-tech companies. At a "normal" company if you
attempt to spend time doing something of this sort, you'd get immediate
pushback from higher ups who would likely say "this is not our core
competency". With the secondary excuse being that they would not want to
release any work like this for fear that it would help the competition.

It does raise the interesting question of whether facebook employees are doing
this work just to avoid the work that is the "core competency" of the company.
Especially given the fact they don't gain a competitive advantage from
releasing the work that facebook paid for into the wild. By this I mean, the
company benefit would seem to be attract other talent. And the personal
benefit for the devs is to get their name out there are something cool and
interesting. Certainly, working on the best way to advertise to users is a lot
less exciting/sexy than working on static type checking for javascript.

~~~
nbm
Different people find different things exciting/sexy to differing degrees.
Some people like building stuff that others can see. Some people like building
stuff that others will use. Some people like building stuff that makes other
people build stuff faster. Some people like building stuff that is highly
reliable, really fast, really scalable, or really efficient. Some people even
find improving advertising really exciting - they expound on how ads can be
win-win, and even that they can only find their full effectiveness when they
are, or something like that.

I don't think anyone is "avoiding" any work - there's just tons of work that
needs to get done, and people mostly choose to work on that stuff that
interests them. One could say that product engineers "avoid" infrastructure
work and infrastructure engineers "avoid" product, but I think that would be
inaccurate in most cases.

~~~
logicalmind
It is a great luxury to be able to work on what you like, especially as a dev.
Unless you're a well-known person, I don't think it's that easy to work on
what you like, even at google. At least not anymore. Hopefully you guys at
facebook can keep the MBA's off your backs long enough to do more cool stuff!

------
antoinelyset
Flow seems to be close to a true application of type theory and is written in
OCaml. Well done Facebook.

------
leopoldfreeman
Just tried it. Not good for projects depending heavily on 3rd party libs. I
have to define all the interfaces in a 'interface file' to keep 'flow' silent.
This seems an impossible job for our project.

~~~
joshkpeterson
It's the same with typescript. The community will take care of most libs over
time.

------
jenius
I know it's very early, but just curious if anyone is working on a node
binding for this, or if one exists already? Would love to try it out in our
stack, but it would require a javascript interface.

------
swalsh
Question, in the doc it shows a code snipped that has the functioned defined
as such "function foo(x: string)"

What mechanism ensures this becomes valid javascript? does the code need to be
compiled?

~~~
inglor
This is _not_ valid JavaScript.

The code has a build step - yes. You will not be able to run this code without
a step. It could be awesome if they allowed annotations in comments like other
tools do - there is a GH issue on that and it looks like it should be possible
[https://github.com/facebook/flow/blob/master/src/typing/comm...](https://github.com/facebook/flow/blob/master/src/typing/comments_js.ml)

------
emmanueloga_
There's some tremendous effort being poured into making a crippled language
like javascript usable, but when talking about solutions for maintainable
frontend code, I'm more excited about compile-to-js languages like haxe [0],
purescript [1] or ceylon [2].

The caveats I heard about transpilers often boil down to difficulty of
debugging and lack of libraries. But with the amazing browser dev tools we
have, debugging potential issues is not that painful. Every language compiling
to js provides FFI and/or some escape hatch so you can write javascript
manually, for performance tuning or for using 3rd party libs.

Even if you do write "raw" javascript, some sort of compile step is
unavoidable, for running jshint, concatenating, minifying, etc. Why not walk
the extra mile and use a better language?

BTW, I'm not saying a tool like this is not super-useful, specially if you
already have thousands of lines of js code that you can't get rid of. Congrats
to the Facebook team for the release!

0: [http://haxe.org/](http://haxe.org/)

1: [http://purescript.org/](http://purescript.org/)

2: [http://ceylon-lang.org/](http://ceylon-lang.org/)

~~~
jbergens
If everybody agreed that most other languages are much better and more
productive than javascript then we should have had one of them in the browsers
already. And if the problem is just social/organizational then we might never
get anything better than javascript, in which case Flow is awesome.

I think Dart seems to be a great language and IE, Firefox and Safari should
have implemented it years ago, but they didn't. Now I think TypeScript is a
great addition to javascript and I hope they build it into the browsers but I
suppose they won't (maybe EcmaScript 7 will have some parts of TypeScript in
it, or parts from AtScript from Google).

By the way, you probably still want minification and concateneted files when
you create js from other languages. That stops me from using them, I would
have many levels of tools between my source code and the production code.

------
pspeter3
Does it support structural typing? That seems to be the strongest advantage of
TypeScript.

~~~
avik
Yes, it does. You can define object types like { x: number; y: string }, tuple
types like [number, string], function types like (x:number) => string, etc.

------
Bahamut
Whatever people's thoughts on the language itself, JavaScript has built itself
into a juggernaut in the amount of tooling available that fit into various
opinions that developers can choose from. The number of large frameworks (in
terms of popularity and usage) is not really found elsewhere. The number of
smaller plugins are vast.

It helps that companies like Google and Facebook have invested a significant
amount of research power into designing frameworks and tooling around it. Just
from there two companies alone, we have tools like React, Angular, Karma, JSX,
Jest, and now Flow. Tooling that involves the browser more include Polymer and
Traceur (ES6 to ES5 transpiler).

To contrast this, I have been doing development with Cordova the past week &
writing Cordova plugins to fill in missing functionality - the plugin
ecosystem with Cordova is horrid, and the documentation is often awful. To
compound it, Android developers don't seem to believe in documenting their
libraries well.

I will take the JS ecosystem any day when confronted with a choice like that.

~~~
k__
"Whatever people's thoughts on the language itself, Java has built itself into
a juggernaut in the amount of tooling available that fit into various opinions
that developers can choose from. The number of large frameworks (in terms of
popularity and usage) is not really found elsewhere. The number of smaller
plugins are vast. It helps that companies like Google and Oracle have invested
a significant amount of research power into designing frameworks and tooling
around it. Just from there two companies alone, we have tools like GWT,
Android, MySQL..."

~~~
Bahamut
I don't really see the Java ecosystem as comparable - sure, there's a lot of
stuff, but I haven't seen nearly as much as in JS.

------
quest88
Great work, no doubt.

My personal preference is to have annotations because it helps future readers
and maintainers understand the code better. Instead of looking through the
function to see that the variable is in-fact a number, I'd rather just read
"@param x {number}". And at that point, one may as well as use closure.

------
void_star
This is really cool. Does anyone have pointers to relevant papers that
inspired/influenced their type system?

~~~
avik
The implementation is heavily influenced by Pottier's work on subtyping +
inference.
[https://hal.inria.fr/file/index/docid/73205/filename/RR-3483...](https://hal.inria.fr/file/index/docid/73205/filename/RR-3483.pdf)

Also, some techniques from Typed Racket (occurrence typing):
[http://www.ccs.neu.edu/racket/pubs/popl08-thf.pdf](http://www.ccs.neu.edu/racket/pubs/popl08-thf.pdf)

Many other papers have influenced the design in some way or the other. For
example, Abadi/Cardelli's theory of objects.

------
kaonashi
This is what I wished Typescript was.

Looks really handy.

------
davemo
If you are interested in learning more about Flow check out the docs [1] and
github repo [2].

[1] - [http://flowtype.org/](http://flowtype.org/)

[2] - [https://github.com/facebook/flow](https://github.com/facebook/flow)

------
skybrian
Apparently this is just type checking. It's not going to do any dead code
removal like Closure Compiler in advanced mode or provide a better syntax like
TypeScript. Whether that's good or bad depends on what you're looking for.

~~~
derek
It's certainly possible that these could be used in combination. GCC
optimizations aren't significantly enhanced by JSDoc annotations, so
presumably this could generate code for GCC to optimize without losing major
benefits on either side.

The React.js team has been explicit about the library being GCC advanced mode
compatible, so they certainly have awareness of its capabilities. Whether they
are using them together internally or they use a different solution for tree
shaking et al is another question.

------
slackstation
I wonder, how does this compare to Google's Dart.js? Like Dart, it introduces
a type system into JS and like Dart, it requires a compile step between Flow
code and JS that will run in a browser. What does Flow do differently than
Dart?

~~~
dangoor
Dart is a different language with different semantics. It is not the same as
JS.

Flow starts with JS and adds a static type system (with attempts to infer
types directly from the code). With the exception of the type annotations,
Flow is JavaScript. Dart is not JavaScript.

------
hyp0
Static types without performance benefits. So far, all _popular_ static type
systems have had the performance benefits, so it's unclear how much people
value the other benefits (quality and documentation).

I wonder which will have the most impact: code quality or types as
documentation (esp for tooling)?

They are adapting to common idioms, rather than designing it from the ground
up. This ad hoc approach is a great way to build useful tools (and startups),
but it's also usually a _mess_. Like NN4. But, they seem to be type experts -
plus they're using ocaml. Maybe _ad hoc_ by experts _is_ the way to get these
ideas adopted?

~~~
avik
If you can feed inferred static types to something like Google Closure
Compiler, you do get performance benefits.

Also, if you're code is implicitly statically typed (as checked by Flow) you
will likely hit all the right optimizations in the underlying JavaScript VM.

------
gregwebs
Even without the flow analysis and better typing, incremental compilation is a
huge improvement over TypeScript, which re-parses type declarations on every
compilation. That quickly leads to large compile times when you have type
definitions for third-party components (even though you may only be using one
definition in the file, the entire definition is parsed).

The existing available definitions from the DefinitelyTyped project is a huge
productivity booster. Apparently Flow also has similar .d.flow files, but it
will probably be a while until they exist for common projects.

~~~
McKayDavis
I was going to comment that this sounds like an opportunity to get mileage out
of the huge amount of typeinfo already provided by DefinitelyTyped by building
a tool to convert .d.ts into .d.flow files.

After investigating this thought, it looks like this already at the top of the
list for future plans for Flow:

[http://flowtype.org/docs/coming-soon.html](http://flowtype.org/docs/coming-
soon.html)

------
hyp0
This looks great, in typesystem/tooling/presentation, and sounds perfect for
facebook; but for mainstream adoption, it needs to meet (or be closer to) the
ideal of _free-benefits_ :

(1) zero-work: works instantly with existing code and esp third party
libraries; and

(2) instant-benefit: provides _some_ compelling benefit in that zero-work case
above (of course, it's OK if it provides more benefit if you do more work,
adding type annotations etc).

------
szx
This might be a stupid question, but is there a way to leverage object
annotations [1] for runtime checks of data coming from e.g. an API or FFI call
(node.js module calling C++ code)?

[1] [http://flowtype.org/docs/react-example.html#general-
annotati...](http://flowtype.org/docs/react-example.html#general-annotation-
strategy)

------
elwell
Is the type syntax friendly with CoffeeScript?

~~~
inglor
Looking at the source - it looks like it's not friendly with CoffeeScript in
particular at the moment.

It'd be quite possible to add the ability to output these annotations to the
CoffeeScript compiler itself though. Could be an interesting fork.

------
eric_bullington
Best tech news I've seen this year, in terms of potential to directly improve
my workflow and my clients' applications.

I'm surprised I didn't hear more about this before since it was apparently
unveiled at the "Flow" conference. Wasn't at the conference and somehow I
missed any prior mention of it.

------
hyp0
One of the authors of Flow offered to answer questions, but their comment is
greyed out as a dupe (and it isn't a dupe - something went wrong):

[https://news.ycombinator.com/item?id=8625406](https://news.ycombinator.com/item?id=8625406)

~~~
dang
If you see "[dupe]" on a dead comment you can be sure that that is why it was
killed.

The problem was that there were two identical comments, the software killed
one as a dupe, and avik deleted the other one. The software tries to fix this
very scenario—it normally would have automatically unkilled the remaining
member of the pair. But there are some corner cases where that doesn't work,
and avik seems to have outsmarted it.

We'll take a look and try to fix the fix.

------
alkonaut
How does static checking work with dynamic types? Can the type checker figure
out if a field/method exists on a type given that it can be added dynamically?

Edit: I assume it just checks bool/number/string and doesn't care about
prototypes?

~~~
avik
It does care about prototypes. So it checks for inconsistencies between
methods added to a prototype and their uses. The tradeoff is that for
dynamically added properties, it doesn't always remember where they are
defined and where they remain undefined (it knows they are defined
"somewhere").

------
MrBuddyCasino
That is quite impressive. No type annotations needed, and control flow is
taken intro consideration (hence the name I guess).

If I am not mistaken, this tech could be used to build IDEs roughly similar to
whats available for Java, couldn't it?

~~~
bri3d
It looks like it's designed for the IDE use case - on cursory inspection of
the code, it contains an autocomplete database and a client-server
architecture designed for editor plugins (with useful interfaces like "type at
character index").

I'm surprised that they don't seem to have launched with a public editor
plugin and that the documentation doesn't seem to mention it.

~~~
avik
The source also has an emacs plugin, named flow-types.el

------
poxrud
Looks like a great tool. The documentation at
[http://flowtype.org/](http://flowtype.org/) is excellent. Should be easy to
add it to a Gulp/Grunt workflow.

~~~
SloopJon
I'm confused by the usage of the utility itself. I ran it on the hello.js, and
it reported the expected type mismatch. I then tried to run it on the file in
the answer sub-directory, but it kept telling me about the previous file.

~~~
poxrud
That's because it checks every file that has /* @flow */. I'm guessing you're
not running it on a specific file but instead on all files in the current dir
and sub directories.

------
applecore
In terms of layering a static type system on top of JavaScript, how does this
interact with Coffeescript and other languages that compile to JavaScript?

~~~
inglor
It doesn't, at least not any more than TypeScript or other compile-to-js
languages interact with each other.

If CoffeeScript is to support these annotations one day - it would require the
CoffeeScript compiler to support them itself in order to generate correct
annotated JavaScript for Flow.

------
sebastianconcpt
Can someone explain in simple words what is the problem that this would fix?
I've never felt the need for this, why should I care?

~~~
DougBTX
It makes it easier to catch some types of bugs without having to run the code.

[http://en.wikipedia.org/wiki/Type_system#Static_type-
checkin...](http://en.wikipedia.org/wiki/Type_system#Static_type-checking)

~~~
sebastianconcpt
Thanks, I guess for those who separates runtime from devtime it might be a
problem

------
aikah
I'm really curious about the accuarcy of that tool,really really curious given
how javascript "types" work.

~~~
slashnull
JavaScript actually has a pretty small number of type primitives; I'd say that
the bad rap about JS's typing is due to the absolutely mind-boggling type
conversion rules (which are nevertheless part of the specification).

Even if that wasn't the case, their design just avoids the issue by not trying
to do any typecast, ever.

------
avik
Hi, I'm Avik Chaudhuri, I'm one of the authors of Flow, and I'll be happy to
answer questions.

------
szx
Awesome. FYI, the Language Reference Next/Back links don't match the order in
the left navbar.

------
aliakhtar
Or you can just use GWT which saves you from having to use javascript at all,
and lets you write java (along with all its IDEs, type checking, code
structure, and other benefits) which is compiled to highly efficient
javascript: [http://www.gwtproject.org/learnmore-
sdk.html](http://www.gwtproject.org/learnmore-sdk.html)

~~~
krapp
"Java" which "compiles" to javascript is not Java. It's javascript with a
ludicrous amount of syntactic sugar applied.

~~~
aliakhtar
All the language features of java: generics, inheritance, type safety,
interfaces, and soon to come: lambdas and other Java 8 features, are all
supported. Plus your code is organized in java packages. So, I'm not sure
you've ever tried GWT.

Things like multi threading which aren't possible in javascript aren't
supported, but a lot of the JRE which is used in most code, does come out of
the box. Its a huge improvement over regular javascript, anyway. And client +
server code can be shared.

~~~
krapp
Those are features of the IDE, and of Java, certainly. But type safety doesn't
really exist in javascript. Structures like interfaces and classes don't
really exist. Inheritance is different. Scope is different.

What you have is a javascript framework which emulates the behavior of Java to
the degree that javascript permits, but can't really implement it.

I'm not saying it isn't a useful tool, or that the javascript it generates
isn't far, far superior to anything I could roll on my own - but...

>Things like multi threading which aren't possible in javascript aren't
supported

...it isn't Java.

~~~
dragonwriter
> But type safety doesn't really exist in javascript. Structures like
> interfaces and classes don't really exist.

You know where else none of that exists? In the machine code on which the JVM
rests and to which Java code can be JIT compiled by the JVM before execution.

So, if you can't have it compiling to JS, you never could have it on the JVM,
either.

~~~
krapp
It's not the same thing at all. Javascript isn't machine code, and it isn't
bytecode. It's its own completely separate high-level language, that executes
in an unsafe, unpredictable and highly mutable environment.

~~~
aliakhtar
You should tell that to google adwords, inbox, and AWS console, then. All of
them are developed with GWT, and haven't functioned in any unsafe,
unpredictable, or highly mutable way.

------
dgreensp
Looks nice. Is it written in ML?

~~~
avik
Yes, OCaml.

------
lechevalierd3on
Has any one tried to make it work with a google closure code base? I am still
trying.

------
smartpants
[http://flowtype.org/](http://flowtype.org/)

Direct link

------
phazelift
Static? I use my own type-checking/enforcing lib as a base for everything I
write in JS or CS
([https://github.com/phazelift/types.js](https://github.com/phazelift/types.js)).
It's only 1.8kb, dynamic and never fails on me.

------
zghst
Waiting for more ES6 support! I am spoiled by 6to5.

------
debacle
Man, I really want to work at Facebook. If only they didn't require
relocation.

------
UnixHakr
Very nice. I wonder how hard this would be to throw into Jasmine/QUnit type
scenarios.

~~~
Joeri
I'm wondering whether I can add it into my team's svn pre-commit hook that
already does jshint checking. It's remarkable what a difference in runtime js
errors and overall code quality that pre-commit hook made for us.

------
noobplusplus
Who writes JS these days? Will it go with Angular/jQuery?

~~~
qgmr101
You got downvoted by people with broken sarcasm detectors...

~~~
aflinik
Poe's law doesn't make it very easy.

