-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CS2 Discussion: Features: Type Annotations #4918
Comments
From @ozjd on July 24, 2016 18:20 Types? K.I.S.S.
The resulting JS would have to be something like:
and inserted up top would be something like: Thoughts? |
From @rattrayalex on July 24, 2016 23:28 Static types are definitely preferable to runtime types, as they can be useful during development. Flow has a lot of tooling built around it already, and performs a lot of valuable, complex inference work. |
From @rattrayalex on July 24, 2016 23:29 It'd also be nice to keep the typing syntax as close to Flow/TypeScript as possible, given that they are the community standards for typed JavaScript. |
From @dadleyy on July 27, 2016 17:33 I'm not too inclined to see a type system make it into this project. I think it would be a significant departure from the original language and takes away some of the simplistic beauty of it. Type systems are amazingly helpful in compiled languages like go and c++ but in browser-side applications there is a lot of power in weak typing; I'm thinking about error-first callbacks that either accept an |
From @MemoryChips on July 27, 2016 18:30 In typescript there is a type 'any' which I would guess covers your issue. |
From @rattrayalex on July 28, 2016 1:15 @dadleyy I think if you familiarize yourself with Flow and/or TypeScript, you will find that your concerns do not apply. |
From @JimPanic on July 28, 2016 11:16 Flow looks really nice, but I'd have to (again) get used to inline type specs. Elixir handles this in a different way that is really easy on the eyes as it doesn't clutter the actual function signature, but you only annotate it: defmodule LousyCalculator do
# ...
@spec add(number, number) :: number_with_remark
def add(x, y), do: {x + y, "You need a calculator to do that?"}
end http://elixir-lang.org/getting-started/typespecs-and-behaviours.html Maybe it is possible to incorporate Flow with Coffeescript in the long run, though? (Instead of implementing our own…) |
From @dadleyy on July 28, 2016 16:11 @rattrayalex I guess as long as any sort of typing is optional my concerns are moot but that needs to be the case, otherwise we're talking about a not-insignificant departure from the original coffeescript (and es6 too). Would there be any sacrifices/breaking-changes to the language's grammar because of typing? I have to imagine that building a single compiler that supports optional typing is much more difficult to build than one without typing at all though, and holding up support for all the es6 goodies we're trying to bring to coffeescript because sometimes we want to add types to our symbols seems like a bummer. What if however, while building the new compiler if we were to keep tying in mind and make it easy to extend the compiler to support them and later created some sort of Flow seems like it's very much a "post-processing" system; wouldn't a tool like that just belong in a codebase's build system after having compiled coffeescript into js? In the same regard, isn't solid test coverage using tools like jasmine/mocha also a good defense against the problems that a typing system try to solve? |
From @rattrayalex on July 28, 2016 17:7 @dadleyy again, I think it'd be very helpful if you familiarized yourself with Flow (read the docs, install, add the types to a toy project, read up on the benefits of static typing, etc). But, yes, I should be explicit that types would be both optional and gradual. This issue is to add support for Flow for those who want to use it, not to require usage of Flow for all users. For example, Babel has flow support built-in (enabled via a plugin) but most Babel users do not use Flow. |
From @carlsmith on July 28, 2016 17:20 Worth mentioning that we could maybe reuse some ideas from ASM here. It converts this C code... int f(int i) {
return i + 1;
} ...into this JavaScript... function f(i) {
i = i|0;
return (i + 1)|0;
} |
From @carlsmith on July 28, 2016 17:49 It's also worth mentioning that once you add a feature, everyone has to use it, whether they want to or not. You can't just opt out of a feature, unless you can disable it entirely, as other people will use it, and you will need to read their code. I can decide not to use an English word in my own sentences, but I still have to use the word whenever someone else includes it in one of their sentences. Just reading a word is still using it. |
From @MemoryChips on July 28, 2016 18:15 You may prefer to not see types in other peoples code but I think it helps the readability. In Typescript, you can set the compiler to implicit any which which allows you to avoid the requirement for types in your code. Rob |
From @rattrayalex on July 28, 2016 21:25 @carlsmith - in some languages, types are required everywhere. For example, you can't write any Java code without using types. I'm not proposing this kind of requirement for coffeescript. |
From @carlsmith on July 29, 2016 0:9 I know?? I was responding to @ozjd, where he said "The resulting JS would have to be something like"... function () {
testType(String, a);
return "You said " + a;
} We may not need to have type-checking functions if we use ASM style type-casting, and let the JS engine throw errors. Perhaps not though. I haven't thought this through, but it seemed worth mentioning, as it might solve at least some of the problems that would come up if we added typed variables to CoffeeScript. I also responded to your comment that types would be optional, which is a perfectly valid point, but people often confuse that with meaning that you don't have to use them if you don't want to, which is a bit of an overstatement. We would still be complicating the language for every user. Personally, I'm totally against adding static types to CoffeeScript. You can't change anything more fundamental than a language's type system. The original proposal was for type hints, so the compiler would treat them like comments, except that they are in the AST for other tools to work with. They have no semantics, only syntax. I'm not in favour of type hints, but am happy to discuss it and see if anyone can make a compelling case for them. Statically typed CoffeeScript is another language entirely. |
From @rattrayalex on July 29, 2016 3:13 Ah, gotcha. Apologies. With Flow, it's really more like type hints -- they're stripped out entirely by the time they hit runtime, even in development. |
From @objectkit on August 1, 2016 14:6 Type annotations could possibly be accommodated by decorators?
That way soft typing and hard typing could be toggled just by switching the behaviour of the decorator? The information is still there in the code, and easy to see, communicating intent. The decorator implementation used during testing and development could do strict type checking, and switched to a mirror image placeholder decorator at run time in shipped code which would do no type checking... |
From @rattrayalex on August 3, 2016 5:3 @objectkit see the discussion on decorators: coffeescript6/discuss#9 EDIT: whoops, you're active on that thread 😅 In any case, @objectkit – have you investigated Flow at all? Any drawbacks to that system that you see? |
From @objectkit on August 4, 2016 6:28 @rattrayalex Hey - I have to be honest, I think theres a bit of confusion going on - it could be my own - so just to clarify:
But with that said, opt in type annotations in CS is a good idea. I took a look at Flow, and it seems to have the right attitude, but would incur the introduction of a new syntax into the next CS With gradual type annotations, this
could be expressed as (something like) this
Assuming I'm still on the same page, if a new syntax were introduced, to support a gradualistic approach to their introduction would introduce compilation overhead (e.g. when to discard, when to enforce by introducing type checking code in transpiled code). IMO, at certain stages of development, implicit run time type checking is a very good thing! But the only way I can see getting the best of both worlds is by decorators. That way, strict decorators could be imported during testing and development, placeholder decorators could ship with output code once tested.
or
Using decorators in place of type annotations could work, intent is semantically clear (apart from the ampersand right now!), gives developers liberty to opt-in or opt-out of typing, and they can always roll their own decorators, or use a decorator library.... I think decorators would go with the spirit of CS in context of enforcing type safety. KISS, but at times, be picky! The advantage of syntax over decorators though is enforcement at compile time, not run time (when decorators kick in)... |
From @rattrayalex on August 5, 2016 4:38 Static types are great for a lot of reasons, only one of which is "check that this kind of bug won't happen". They also give the editor a lot of useful hints about the program; see the gifs on https://atom.io/packages/atom-typescript for some examples of what's possible. Decorator-provided types have been an option for a long time, and yet nobody's opted to build a (widely used) library that provides them, so I'm going to assume that's not an option people find valuable. On the other hand, developers have been flocking to TypeScript and Flow, and dynamic languages like Python are introducing static typing through projects like MyPy and Pep484. Let's keep this conversation focused on static types, if that's okay. Runtime types can always be done in an outside library, and provide a different set of benefits. |
From @JimPanic on August 5, 2016 5:57 I agree. I wonder how much of that static analysis shown in the gif relies on TypeScript's actual types. It seems from the snippet at hand this very example of reassigning different types could well be part of the CS compilation process. Might not even need annotations for that? |
From @rattrayalex on August 5, 2016 16:1 I really recommend anyone on this thread learn more about static typing, TypeScript and Flow specifically, and try the languages out for a bit. @JimPanic I think you're talking about Type Inference. Flow does a lot of inference – almost as much as it can – but there are definitely times when that's not possible. |
From @objectkit on August 5, 2016 17:30 @rattrayalex I understand static typing- I was simply trying to communicate an alternative way to accommodate the use of type enforcement in the language at run time in a way that doesn't significantly alter CS- I totally agree with the merit of static typing at compile time - if it won't compile, it should be evident and an IDE should report it. Run time bugs in a language host executing the code can be a right PIA and can happen with transpiled ES, even if CS compilation is successful. I'm personally a fan of types, and especially when they can be introduced gradually - e.g. turning a quick proof of concept code into a robust formal expression of the code when needed. I remember ActionScript 1,2 and 3 succession and its commitment to ECMAScript. And even Microsofts attempt at typed JS all the way back in the early 00's before TypeScript. A language that is flexible enough to transition from sketch to formalism definitely has its benefits, and I really hope this language goes in that direction- to be able to write CS 1 to begin, then to formalise it with types in the next edition. That would hopefully make transition possible from existing CS code to this. It's tricky. Could we attempt working on a new general purpose parser / lexer / compiler for CS first, starting with an independent grammar definition of CS, then once succeed in an alternative CS compiler, formalise a new edition of it? That approach may work? I suspect the workflow of designing the language being distinct from the implementation of the compiler would have lots of benefits and give a concrete goal. First release should compile CS 1.10.0, next release will compile the next agreed language edition, with hopefully minimal impact on the implementation of the compiler. A multistage workflow? I think I can see why you were considering Babel... |
From @zeekay on August 5, 2016 22:16 I'd love optional typing ala TypeScript. In terms of syntax I've always been fond of the Haskell-inspired syntax used by contracts.coffee.
|
From @mrmowgli on August 20, 2016 23:7 I am wondering if it would make sense to create an alternate comment type, that implied pre-processing or optional hinting? In other words I like the idea mentioned by @JimPanic with Elixr, but I don't like the @ symbol reuse. I also expect there would be a number of cases where we would want to hint code or apply a preprocessor, and really this should be ignored by previous versions of coffeescript. Adding a comment modifier would let both happen. For example #-spec (number, number) : String
(x, y)->
# Normal comment
"delta: #{y - x}"
|
From @rattrayalex on September 9, 2016 15:39 Closing as this has been marked as "no action" in https://github.com/coffeescript6/discuss/blob/master/Features.md I'm personally not opposed to re-opening in the future. |
From @GeoffreyBooth on October 23, 2016 22:46 Update: see Contracts.coffee for an implementation! Unfortunately that project hasn’t been updated since 2013, so there would be significant work to port it to CoffeeScript 1.11 or 2. At the very least it can serve as a design inspiration. Looking at its syntax, though: square :: (Num) -> Num
square = (x) -> x * x
square "a string" # throws a runtime error It makes me wonder if the first line, that defines the contract, could be a comment like Javadoc. Then some other tool besides the CoffeeScript compiler could do the work that Contracts.coffee is doing (of creating new code that validates the types at runtime). The Contracts.coffee readme refers to a more recent project, Contracts.js, so maybe that could be part of the solution. If the contracts part can be implemented as a separate build step outside of the CoffeeScript compiler, then it be a separate project and not subject to the limitations of the CoffeeScript compiler (or the need to get a consensus within the CoffeeScript community that this should be added to the language). |
From @aleclarson on October 23, 2016 23:40 I like the idea of using Flow definitions (Bluebird example here) so we can keep static typing out of CS entirely. Are there any disadvantages to this approach? It could also be cool if there was a CS-like "language" that transpiles to a Flow definition, because right now Flow definitions are rather ugly (IMHO). |
From @zeekay on October 24, 2016 2:1 Contracts.js only checks contracts at run-time -- but yeah, the syntax is very nice. |
From @aurium on October 24, 2016 15:59 This kind of type testing will not work when testType = function(type, data) { if (data !instanceof type) throw TypeError 'Expected type' } I love the @carlsmith's translation to ASM.js notation To solve the "clear type setting" problem i like the @objectkit's decorators based proposal @params String, Number
@returns Result
fun = (name, value) -> #impl however the Well, why not get this information from a comment? This will help some project to migrate as this notation will not crash CS1 and it can be directly used for doc generators like codo or JSDoc (after transpiling). # @param [String] name something's identifier
# @param [Number] value the weight in Kg
# @returns [Array<SomeThing>] a list of something
fun = (name, value) ->
# @member [Number] x
x = 5
. . . |
From @GeoffreyBooth on December 11, 2016 17:45 See also #3743. There are some good options discussed on that thread. |
From @mitar on December 11, 2016 20:37 I think comment-based type annotations would be the best. I propose the action should be that there is an official way to add types through comments, which is tested and works. I had in the past issues trying to get CoffeScript comments go through properly to Flow. It would be great if that would be something supported and tested in unit tests of CoffeeScript itself. |
From @GeoffreyBooth on December 12, 2016 0:22 I think comment-based type annotation should maybe get its own thread. Of interest would be examples of how to do it currently, assuming it’s already possible; especially with Flow if possible. CoffeeScript clearly already supports comments, so I don’t know what would be needed in the language to improve things; though it can’t hurt to have additional tests to ensure that CoffeeScript supports the proper types of comments that Flow requires. If there’s a “standard” way that works especially well and seems like a recommended practice, we could consider documenting it, either in the official docs or (more likely) in the wiki. |
From @rattrayalex on December 12, 2016 13:40
As someone who's been following along on many threads, I'm a bit concerned that off-threading is making conversations hard to follow. When sub-proposals are moved to new threads, the interesting points, caveats, and tradeoffs brought up in those threads don't make it back to the new threads. Might be worth keeping "proposed solution" conversations on the same threads as the problem statements, at least until a given proposed solution has picked up significant steam, at which point it might be best moved to an issue/PR on the main coffeescript repo. |
From @dadleyy on December 16, 2016 5:29 @rattrayalex I've played around with typescript a bunch the past few months and have really started to enjoy building browser side software using a compiled, typed language, which makes me critcal about my own comments back in july. I think the addition of compile-time type safeguards forces engineers apply good design principals to the code they write - especially interfaces ❤️. Still, I'm of the opinion that at this point there is no clear path to introducing types to coffeescript that would not fundamentally change the language's appeal to those that are looking for a terse compile-to-javascript language, not to mention the complexity type checking would add to the compiler itself. For me, the biggest "win" would be the ability to write my code in the concise & beautiful syntax coffescript provides with the ability for a downstream process to do some kind of static analysis based on opt-in (comments) annotations and provide compile-time "type" errors. |
From @GeoffreyBooth on December 16, 2016 5:33 @dadleyy I think there’s a middle ground, where something comment-based can interact with a tool like Flow to get type checking in CoffeeScript without needing the compiler to do the checking. If there are people who are familiar enough with a particular solution that they feel comfortable writing a guide explaining how to do it, I think it would be a good addition to the CoffeeScript Wiki or main documentation. |
From @rattrayalex on Dec 16, 2016 Appreciate the followup @dadleyy ! I agree with @GeoffreyBooth that an officially-supported/documented way of using Flow through type comments is probably the best way forward. Though I haven't yet seen an example of that actually being done successfully, so I'm not sure if it's as simple as it sounds. |
From @GeoffreyBooth on Dec 16, 2016 @rattrayalex why don’t we reopen this issue, and it becomes (at least) one of documentation? Where the task is for someone to write a guide on how to use type checking via comments and Flow or similar tools. And if as part of that guide we find that there’s something the compiler can do to make that process work better, that can spin off into its own effort. |
From @rattrayalex on Dec 17, 2016 Sounds good! |
From @ArmorDarks on Feb 19, 2017 I'm surprised how much resistance got type annotation in the beginning. Though, I'm glad that to the end of the thread people started to change their position. It would be great to have type annotation in CS. Regarding decorators: they aren't full solution to this issue. First of all, it is still unclear will decorators make their way into JS at all (since they are still only a proposal with experimental implementations via babel), but even if they will appear in JS and CS, decorators results in runtime type checking with a lot of limitations, and, as already mentioned above, in most cases you want to have static type checking. Also, not to mention, that type checking with decorators could be implemented as external library, so there is no reason to make it part of CS core. Type annotation through comments seems to be an option, but I think not all people will be happy with it. Though, I'm not opposed to have this option too. Btw, Flow now supports annotation with comments too, so there is no need to use flotate anymore. See here. Did someone try it? Maybe it's possible to make it work with CS? And also this seems to be possible with Google Closure Compiler too. See example here. Looking on this from another perspective, since we already have Flow and TypeScript, maybe type checking shouldn't be responsibility of CS indeed. After all, we already have tools for it. But the issue here is that so far it's impossible to use type annotation in CS and pass the result to Flow or TypeScript for type checking. |
From @mrmowgli on Mar 18, 2017 Ok I looked at the flow comment integration mentioned by @ArmorDarks, Flow typing in comments. Should work. Has anyone successfully used this in a project? |
From @ArmorDarks on Mar 19, 2017 I personally didn't try, and probably won't, because we're slowly moving away from CS to ES6. I think this won't be an issue at all if CS could be transpiled through Babel. Really, this is one of reason we're leaving CS — it is so damn hard to integrate into nowadays JS pipelines. I also must correct myself. I said:
That's not true. In fact, runtime type checking is quite cool and allows to do a lot of nice things, like checking against schema incoming through AJAX data, etc. This something that is impossible with static type checking, because it's done during compilation and unavailable in runtime. But in many cases still you'd like to have static type checking, or even both. We've made small research about available popular solutions, you can read results here: https://github.com/LotusTM/Kotsu/issues/165 If anyone is okay with runtime type checking, I can't recommend more tcomb. It is compact and elegant lib with very powerful API for checking types in runtime. |
From @mrmowgli on Mar 19, 2017 Interesting :) I'll check those out! The annotation thing I think could be handled very nicely with functional programming styles like in this thread. I imagine those of us that are going to stick with CS are going to want to try Flow or find some ways to bring tools like tcomb in. Hopefully I'll get a chance to see if Flow will work well in CS, or someone will tell us how it worked for them! |
From @ArmorDarks on Mar 19, 2017
It is possible to write wrapper around, let's say,
Any runtime type checker like For example, with t = require 'tcomb';
sum = (a, b) ->
t.Number a
t.Number b
a + b
sum(1, 's') # throws '[tcomb] Invalid value "s" supplied to Number' In fact, syntax somehow alike to decorators. But yeah, with Flow it is completely different story... |
From @rattrayalex on Mar 19, 2017 The difficulty of supporting flow – even through comments, which seems pretty unergonomic – is a major part of the reason why I built LightScript, which recently hit npm for beta use. LightScript doesn't plug into the flow typechecker yet (planning stages), but it supports the flow type syntax and tcomb, I think pretty smoothly. There's also basic support for ESLint. I'd welcome feedback from anyone willing to give it a try, and would love help in building the flow typechecker integration if anyone's up for the task. |
From @mrmowgli on Mar 21, 2017 I think either way this needs to be addressed in CoffeeScript, so I'll keep digging. |
From @zeekay on Mar 22, 2017 I'd love to see the CoffeeScript syntax extended to support type annotations (think Python's typing module). Ideally I think these type annotations would extend the CoffeeScript AST, which could be used by an adapter for any given type checker. We'd probably throw them out when outputting JS, although runtime checking ala contracts.coffee would be pretty neat. A unified set of type annotations which could be adapted into the appropriate type checker would prevent us from getting locked-in to a specific type checking tool and simplify experimenting with different type checkers. |
From @GeoffreyBooth on Jul 27, 2017 This is possible now in #4572. See documentation for how to use comments with Flow for static type checking. If you’d like to try it out, I’d love to know how well it works (or doesn’t) for you! |
From @GeoffreyBooth on Aug 2, 2017 Implemented Flow comments syntax via #4572. If people would like to propose alternative implementations for static type checking, please open new issues. |
From @GeoffreyBooth on Oct 18, 2017 Hey folks, I’m looking for testers for #4753. That PR should allow using all parts of Flow’s comments-based syntax via CoffeeScript comments. If anyone has a current CoffeeScript project they’d like to add Flow comments to, or a current JS Flow project they’d like to convert to CoffeeScript with the Flow types in comments, that would be a great way to test this. Also, if someone can create a single |
From @rattrayalex on July 23, 2016 4:23
I've assumed it'd be next to impossible to add type annotations to CoffeeScript, but thought we should open an issue to discuss if it might be possible. Static Typing is undergoing a renaissance of sorts these days, with developers flocking to new statically typed languages and adding static annotations to dynamic languages like Python (see PEP484) and JavaScript (via Flow and TypeScript).
Flow supports gradual typing for JavaScript, and has some decent tooling to make development easier. They have loose plans to ingest an ESTree AST, which could allow integration of Flow and CS6.
I don't think TypeScript would be a viable target for CS6, as it doesn't play well with Babel (a probable target of CS6) and requires "complete type coverage", which wouldn't likely gel well with CoffeeScript developers, who don't like typing (pardon the pun).
While this would be awesome, I struggle to see how it could work, at least with Flow-like syntax and readability:
Copied from original issue: coffeescript6/discuss#12
The text was updated successfully, but these errors were encountered: