-
Notifications
You must be signed in to change notification settings - Fork 2k
Meta: Support Some Form of Static Typing? #4563
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
I’m working on a PR to improve support for comments, to allow comments to “follow” the next or previous token into the final output. So something like this: foo = (x###: ?number###)###: string### ->
x ? "default string" foo = function (x/*: ?number*/)/*: string*/ {
return x || "default string";
} The same logic could apply to backticks (embedded JS). There are many problems to solve to get this to work. For one thing, it’s more or less straightforward to attach a comment (or embedded JS block) to a ”literal” token like If it is solvable, though, or solvable even for limited cases (literal and identifier tokens only, for example) then this could be used to enable the comment-based Flow syntax, or with backticks could enable the regular Flow syntax. And there’s nothing Flow- or TypeScript- or static types-specific about this, so it would pass muster in terms of not muddying up the language. It just makes comments and embedded JS more versatile in that you can use them in more places. Currently you can only use comments or embedded JS where statements are allowed (i.e. on a line by itself) rather than anywhere interspersed with other code. |
@GeoffreyBooth Although I think allowing comments and backticks in those places would be good and useful, I don't think it is a solution for the type system support. Even wrapping in backticks would be too onerous and would prevent tooling being built on top. So let's keep in mind that some limited support might come from this approach, but focus the discussion here on a more full-fledged support. foo = `<T>`(x`: T`)`: T` -> x would not get much love imho. |
This related thread is worth reading: coffeescript6/discuss#12 One thing we could agree on in that thread was that if there’s a way to implement static types via comments and Flow now, without any changes to the compiler, someone should write up an explainer on how to do that and we should add that info to the docs. Obviously such an implementation isn’t as convenient as purpose-built types support, but until such an implementation ever gets built, we might as well document what people can achieve today. Especially if such an implementation never gets built as part of the CoffeeScript compiler itself, as opposed to a preprocessor or a fork. Such an exercise will also help illuminate what an ideal typing system and syntax would look like, especially if there’s a non-trivial app (like the Todos example) implemented with it. It would give us a good starting point for discussion along the lines of “okay so we have this, and what are its deficiencies? What should we add to the compiler to make this experience better?” And if it’s not possible to implement even the comments-based version of Flow support, then that’s another issue. I suspect that our current support for comments is insufficient to enable that syntax, and that’s what I’m trying to achieve in my comments branch. But more generally, this would point to a separate deficiency in the compiler, that our support for comments isn’t as robust as it could be; and that’s something we should fix regardless of how people feel about static types. In the meantime, @xixixao do you want to try seeing if you can implement Todos using comments-based Flow? Or any other static types system you think might work with CoffeeScript 2 as it is today. And if you’re able to achieve that, we can use that example as our baseline. |
@GeoffreyBooth TypeScript doesn't support comment syntax at all. Flow doesn't work with generics (which is arguably a Flow bug, but might not be resolvable):
^ another problem is that the scoping could be wrong, because CoffeeScript scoping works differently to JS. As I wrote in my previous comment, using comments or backticks would be too onerous for practical use. I don't think there is any value in documenting what you can currently do, because no one is going to use it. |
In #4572 I’ve added documentation for how to use comments with Flow for static type checking. It’s not as elegant as TypeScript or regular Flow, but I don’t think it’s so onerous that people wouldn’t use it; what do you think @xixixao? If inline comments like |
@GeoffreyBooth - that's pretty amazing! I hate the idea of writing such things as comments instead of as syntax, but it's better than nothing for now! When are we going to have a release with this? Just a question - wouldn't it be better to have some actual syntax for type annotations in CoffeeScript and then transpile that down to TypeScript? I understand that that's a lot more work but isn't that the "best" that could be done? |
What syntax? It can't clash with CoffeeScript. That's whole crux of the problem... |
Not a fan of the documentation, as it doesn't align with the elegance of CoffeeScript, but it's not factually incorrect. It's unlikely I'll have the time to look into this any time soon, but someone else could pick it up. |
@xixixao A preprocessor could convert something like fs = require 'fs'
CoffeeScript = require 'coffeescript'
code = fs.readFileSync process.argv[1]
code = code.replace /#:(.+)#/, '###:$1###'
code = CoffeeScript.compile code, {bare: yes, header: no}
console.log code This is obviously very minimal. I’m sure if you invested some time you could create a preprocessor that enables a more elegant syntax, that you convert into the comment-based syntax before the CoffeeScript compiler gets to it. Because your step would happen before the CoffeeScript compilation, you don’t need to worry about clashing with CoffeeScript’s syntax, as my example here does. You could even go further, and write a postprocessor that converts these comments into something else. That’s essentially what flow-remove-types does. Such a postprocessor could conceivably convert comments into TypeScript type annotations, for passing to the TypeScript checker rather than Flow. That’s why I invested a lot of time into #4572, to enable such add-ons. As you wrote above, there’s no appetite for adding static types to CoffeeScript proper, so this is the next best thing. I agree it’s inelegant, but until someone implements a better solution, I feel like we should at least document this in case anyone wants static types with CoffeeScript. @boris-petrov There are no plans at the moment for adding type annotations to CoffeeScript directly. Any workarounds will involve including the annotations within backticks or comments, possibly coupled with pre- or postprocessors to improve readability. If you build such an add-on, I would be happy to link to it from the docs. I’m planning to release #4572 with 2.0.0-beta4, which should come out as soon as #4572 and #4607 are merged in. |
Static types are now possible via #4572. Clearly there are more elegant solutions possible, but the specific problem posed by this issue is resolved. Please open new issues for other implementations of static types you would like to discuss. |
Let's preface this with:
Keeping that in mind, a scenario in which I think we could support some type system:
What I think we could do is support a syntax that could be used by an existing type system. Afaik there are two popular existing choices in ES6 ecosystem: TypeScript and Flow (add more if you know of any).
No reason to beat around the bush: TypeScript will be much harder to support. It's got more extra syntax to JS.
I imagine that the following code would be possible:
Which with Flow would report an error.
I think it might be interesting to figure out the upsides and downsides here and if there is any interest in having this supported. At this point it's very theoretical, as I'm not even sure how much effort it would take to support all of the typing syntax.
The text was updated successfully, but these errors were encountered: