Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

feat: integrate flow type-checker #82

Closed
wants to merge 5 commits into from

Conversation

Gozala
Copy link
Contributor

@Gozala Gozala commented Apr 8, 2019

This change adds flow comment syntax & runs flow check on lint that will fail on type missmatches.

Additionally more type-friendly CID.matchCID alternative to CID.isCID is added which
returns CID if value is CID or void otherwise.

Method .equals is updated so parametre can by an arbirtary value, not just CID. It makes
working with CIDs & type-checker a lot easier as it avoids refining v to CID type before
being able to call cid.equals(v).

--

I'm using flow check right now but that should probably be moved to aegir ipfs/aegir#347. I suggest to address that separately.

@Gozala
Copy link
Contributor Author

Gozala commented Apr 8, 2019

/cc @vmx

src/index.js Show resolved Hide resolved
src/index.js Show resolved Hide resolved
This change adds flow comment syntax & runs flow check on lint that will fail on type missmatches.

Additionally more type-friendly `CID.matchCID` alternative to `CID.isCID` is added which
returns CID if value is CID or void otherwise.

Method `.equals` is updated so parametre can by an arbirtary value, not just CID. It makes
working with CIDs & type-checker a lot easier as it avoids refining `v` to `CID` type before
being able to call `cid.equals(v)`.
Copy link
Member

@vmx vmx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain in which cases matchCID() is better? I'm a bit hesitant to add new methods to the public API that are similar to the existing API.

package.json Outdated
@@ -5,7 +5,7 @@
"leadMaintainer": "Volker Mische <volker.mische@gmail.com>",
"main": "src/index.js",
"scripts": {
"lint": "aegir lint",
"lint": "aegir lint && flow check --color=always",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to start slow. So type checking would be its own command type-check or so. This way it also won't run on CI yet. I'd like to address @mikeal concerns about new contributors. I'd like to add the type check as separate check so that it's also clear to contributors that their code basically works and that it's just the types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this to at least "release" script ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could even add it to CI, I just want it to be a distinct test step.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vmx so I've added "check": "flow check --color=always". I would like it to run before pull is being submitted, however I'm not exactly sure what the convention here is (I tend to have npm test setup to do all the checks) so please advice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, I've figured it out 1bc1670

.prettierignore Outdated
@@ -0,0 +1,2 @@
**/*.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please remove this file, I don't want to clutter the root directory too much.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sorry that was a mistake, just had to stop vscode from reformatting everything & forgot to omit it from commit

src/index.js Show resolved Hide resolved
src/index.js Show resolved Hide resolved
src/index.js Show resolved Hide resolved
@Gozala
Copy link
Contributor Author

Gozala commented Apr 9, 2019

Can you please explain in which cases matchCID() is better? I'm a bit hesitant to add new methods to the public API that are similar to the existing API.

So when type-checker sees code like below where x has non specific type say CID|Buffer It can’t refine that type within if block

if (CID.isCID(x)) {
  x //: Buffer|CID
}

If instead it was something like:

if (x instanceof CID) {
   x//:CID
}

That is because calls to some functions can’t refine type of the bindings in the caller. However functions can refine type and return refined type, which is what this CID.matchCID does

var cid = CID.matchCID(x)
// now flow knows it’s type is `?CID`
if (cid) {
  cid //:CID because it’s not void
}

@Gozala
Copy link
Contributor Author

Gozala commented Apr 9, 2019

I would like to address @hugomrdias comment here #83 (comment) because I don't want to further derail API change proposal into typing debate

Regarding type checkers im in favour of typescript with jsdoc (maybe some type definitions), full ts or flow (flow doesn't feel right after seing FB react and jest teams drop flow for ts) are too much of an overhead.

I agree that flow team has being really bad & at this point in time I would probably prefer TS myself even though type system is significantly less expressive. However adopting TS is far more costly because you have to buy-into whole tooling / syntax. With flow type comments bar is dramatically lower as you just add comments. As of JSDOC it's not even remotely the same, it better than nothing but I'd definitely won't call it a type checker. What we do in this pull request is actually both.

@vmx
Copy link
Member

vmx commented Apr 9, 2019

However adopting TS is far more costly because you have to buy-into whole tooling / syntax.

Not anymore. @hugomrdias talks about TypeScript via JSDoc Syntax. It's like flows inline comments (just not inline).

@hugomrdias
Copy link
Member

One can do the same type checking as normal ts, generated documentation and more.

@vmx
Copy link
Member

vmx commented Apr 9, 2019

@Gozala: FYI, the CID.isCID(x) comes from the 'is-class' module, so it's only true if x is really a CID instance. But I guess that can't be expressed in flow.

@Gozala
Copy link
Contributor Author

Gozala commented Apr 9, 2019

However adopting TS is far more costly because you have to buy-into whole tooling / syntax.

Not anymore. @hugomrdias talks about TypeScript via JSDoc Syntax. It's like flows inline comments (just not inline).

One can do the same type checking as normal ts, generated documentation and more.

I'm aware, but that JSDoc syntax is even more limited e.g. you can't say define / expose interface. Nor I see how you would define generic methods.

I might be biased towards flow as I find JSDoc syntaxt to be difficult to comprehend. I will understand if choice is made in favor of TS.

@Gozala
Copy link
Contributor Author

Gozala commented Apr 9, 2019

@Gozala: FYI, the CID.isCID(x) comes from the 'is-class' module, so it's only true if x is really a CID instance. But I guess that can't be expressed in flow.

I understand that even if it was plain static method as:

class CID {
 isCID(x) {
   return x instanceof CID
 } 
}

It still would refine x with-in the isCID scope but not in the caller scope.

@vmx
Copy link
Member

vmx commented Apr 9, 2019

I might be biased towards flow as I find JSDoc syntaxt to be difficult to comprehend.

I also don't like the JSDoc syntax :)

@hugomrdias
Copy link
Member

You can define interfaces and import them where ever you want and you can use ts syntax instead of jsdoc in the comments.
Generics I never tried ..

@hugomrdias
Copy link
Member

I'm not trying to campaign for TS, just sharing what I learned about it.
But it scares me a bit that everyone is moving to TS even internal FB teams.
Doesn't seem wise for me to start using flow now.

@Gozala
Copy link
Contributor Author

Gozala commented Apr 16, 2019

@vmx I have addressed all the comments. Please let me know what would you like to do with this.

@vmx
Copy link
Member

vmx commented Apr 23, 2019

@Gozala I still want to give flow a try. Though I'd like to have the matchCID() removed. I don't like to introduce new public APIs that are mainly there to make type-checkers happy. For new APIs we should make sure that the APIs work well with types.

@Gozala
Copy link
Contributor Author

Gozala commented Apr 23, 2019

@Gozala I still want to give flow a try. Though I'd like to have the matchCID() removed. I don't like to introduce new public APIs that are mainly there to make type-checkers happy. For new APIs we should make sure that the APIs work well with types.

Alright, I’ll make a change to remove it then.

I just wanted to avoid introducing a friction that could lead to a bad experience with a type checker. I do understand your argument.

@vmx
Copy link
Member

vmx commented Jun 18, 2020

IPFS is now using TypeScript in JSDocs, for more information see ipfs/js-ipfs#2945. Hence there's no point of introducing Flow here anymore.

@vmx vmx closed this Jun 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants