LeverLabs

Flow, a Diamond in the Rough?

written by Onne Gorter on 2015/11/03

Yesterday I talked about TypeScript and my experience with it for my last game. The short, it has your back, but it also adds some overhead.

For my latest prototype, I decided to go back to javascript. But using ES6, which works out of the box on a modern browser. Somehow typescript felt too heavy for my kind of work.

But now I do miss a tool to check my typo's. So I tried flow. After setting it up, it gave me 1026 errors, on a project of 3000 lines. But most are in this category:

index.js:392
392:         this.tx = x
             ^^^^^^^ assignment of property `tx`
392:         this.tx = x
                  ^^ property `tx`. Property not found in
333: class ShipButton {
           ^^^^^^^^^^ ShipButton

Which is weird, as that class does have a tx property. Checking out the flow sources, I found this: comment. And thank you facebook engineers, they kept the function mine_fields around. Lets bring it back, commit.

Bam, 435 errors.

index.js:137
137: Vec2.prototype.mag = function() { return Math.sqrt(this.x*this.x + this.y*this.y) }
                                                        ^^^^^^ property `x`
137: Vec2.prototype.mag = function() { return Math.sqrt(this.x*this.x + this.y*this.y) }
                                                             ^ property `x`. Property not found in
1932:         var m = thrust.mag()
                      ^^^^^^ Number

Lots are of this variety. Which is funny, thrust is a Vec2. Flow seems to know this as it points to the correct method that will be called. But at the same time it inferred that thrust is a Number? Should figure out what is going on. Likely a bug in flow. But likely also helped by annotating my code with types.

Lets try weak mode which keeps the checks locally. 27 errors. Now we are talking.

index.js:2174
2174:                 count += 1
                      ^^^^^^^^^^ +=
2174:                 count += 1
                               ^ number. This type is incompatible with
2174:                 count += 1
                      ^^^^^^^^^^ string

But a lot of these. And that count is really a number, not a string in sight. What is going on? Changing out that += for = count + 1 removes the warning. That is a hint. Ultimately I came up with this patch. Basically when inferring types in weak mode, don't jump to conclusions when we don't know the type.

That brings me down to 10 errors. I fixed 7. Exactly the kind of mistakes I was hoping to find.

Weak Mode for all your Javascripts?

That gives me hope. Perhaps flow in weak mode can just be applied to most javascript files? What if flow check myfile.js just does its thing. No flow init no /* @flow */. A jslint on steroids.

Anyways, it was fun taking my ocaml shoes out for a run again ...

Submit to Hacker News