tc39 / proposal-type-annotations

ECMAScript proposal for type syntax that is erased - Stage 1
https://tc39.es/proposal-type-annotations/
4.27k stars 47 forks source link

Type Annotations - Community Meeting #184

Open romulocintra opened 1 year ago

romulocintra commented 1 year ago

Community meeting scheduling

The champions group has been in talks about hosting our 1st community meeting to talk about the type annotations proposal. To make this happen, we've put together a draft agenda and would love to hear your interest in participating. This GitHub issue will be used to gather availability for the meeting, we are planning to schedule it before September's TC39.

Draft Agenda:

After running the doodle to check folks´ availability, the meeting is scheduled for :

Teleconference details:

Meeting notes : https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit?usp=sharing

romulocintra commented 1 year ago

cc - @theScottyJam, @msadeqhe, @azder, @eemeli, @markcellus, @unional, @ofeenee, @peey, @jithujoshyjy, @lukaszpolowczyk, @brad4d ...

ctcpip commented 1 year ago

11-13 September overlaps with TPAC

ioucyf commented 1 year ago

I would love to be part of the meeting/discussion. I, however, need to get up to date with:

theScottyJam commented 1 year ago

Will this be over Google Meet? Zoom? Something else? Will it be recorded?

callionica commented 1 year ago

I can't be part of the meeting, but if I were there, my community feedback would be: please drop this proposal. I like and use TypeScript extensively, but there's no reasonable way to get types in JS following the path set out here. If the TS team want to make it easy for people to write typed JS without a compile step, just go ahead and do that. Make JSDoc or TS import nice to use. Or come up with a better syntax using regular comments. You don't need browser/JS support for that. The proposal won't allow TS code to work unmodified, stomps on JS adding proper type checking in the future, and complicates browser implementation and the entire ecosystem of JS tools for something that you can currently do: write JS with types.

CodeFromAnywhere commented 1 year ago

Is this a public meeting? would love to know more

romulocintra commented 1 year ago

Is this a public meeting? would love to know more

Yes, is public meeting for all the community interested in giving feedback and talk about the proposal

romulocintra commented 1 year ago

After running the doodle to check folks´ availability, the meeting is scheduled for :

Teleconference details:

Meeting notes : https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit?usp=sharing

romulocintra commented 1 year ago

Will this be over Google Meet? Zoom? Something else? Will it be recorded?

Google Meet, but not sure about the recording

markcellus commented 1 year ago

Unfortunately I don't have a google account (I don't use Google products anymore), so can't see the Agenda or information due to this being behind Google's walled garden. But, due to the controversial nature of this topic, I hope the plan is to keep the discussions focused and productive :wink:. I'm also unable to attend, but if you all can make meeting notes or recording available, that would be great! Thanks for doing this!

khaosdoctor commented 1 year ago

I most likely can participate on this date, will try my best to be there! Look forward for it

matthew-dean commented 1 year ago

@callionica

I can't be part of the meeting, but if I were there, my community feedback would be: please drop this proposal. I like and use TypeScript extensively, but there's no reasonable way to get types in JS following the path set out here

Absolutely same. I use TypeScript every day, it helps my workflow a lot, and I've never liked a TC39 proposal less.

egasimus commented 1 year ago

@romulocintra Thanks for the invitation! Can't guarantee that I will (or won't) be there as my laptop has a learned distaste towards Google products and my own executive functioning is still recovering from a (partially TS-induced) light burnout. So I still mostly exist in a text-only form.

That said, it's great to see so much activity in this repo! Couple weeks ago, all you could hear were the crickets, and now we have several proposals that (in ways even I can comprehend) bring forwards realistic visions for bringing optional typing to JavaScript. Personally, I'd just like to thank everyone who discusses this topic.

Since I may not make it to the meeting, I'm writing here to suggest that the earlier a catchy name is picked for this initiative, the easier it becomes to spread the word and bring sufficient eyeballs on the matter. My proposal is:

Standard Types.

As for syntax, building upon JSDoc's short form, and comment forms like value //:Type or value /*:Type*/, seem like a solid starting point, thanks to the backwards compatibility of comment-based syntax and the familiarity of JSDoc.

trusktr commented 1 year ago

Copy of meeting chat:

Romulo Cintra 9:01 AM https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit

Asumu Takikawa 9:02 AM Here are the slides I'll be presenting today for anyone who wanted to follow it locally: https://docs.google.com/presentation/d/1j1XRPw5iLZqcFNw7yJywdeQuia3eh9zBnAKdtcGLaKQ/edit?usp=sharing

Romulo Cintra 9:03 AM https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit

Rob Palmer 9:03 AM Meeting notes: https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit

Rob Palmer 9:04 AM Slides are black for me Still black Meeting notes doc (please sign your name!): https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit

Chris de Almeida 9:07 AM Meeting notes doc (please sign your name!): https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit

Chris de Almeida 9:14 AM https://docs.google.com/presentation/d/1OraKn6TUdmtug-lkgijq-43Xou_1lB1_DJ54x6ssnRY/edit?usp=sharing

👆 slides referenced from March plenary

Peeyush Kushwaha 9:16 AM Link to grammar?

Gil Tayar 9:16 AM https://tc39.es/proposal-type-annotations/grammar.html Peeyush Kushwaha9:17 AM Thanks!

Homa Wong 9:25 AM Reflection-based runtime checking requires metadata. Does that mean a compilation step will be necessary? And will that be part of this proposal?

Andrew McCloud 9:31 AM Best comparison i've seen https://github.com/stereobooster/type-o-rama

Joe Pea 9:32 AM https://hegel.js.org/ is neat, but it was on pause for a while, kinda still early stages compared

Asumu Takikawa 9:34 AM We have a type system comparison doc here, this is what Dan is referring to: https://docs.google.com/spreadsheets/d/1db9I5Yn495VIdOUFCKVbpoVlAyHlgW8fgyHwuXX4Ro4/edit#gid=1730464012

Joe Pea 9:34 AM What's that other one? "Pego"?

Peeyush Kushwaha 9:34 AM Thanks for sharing the document

Homa Wong 9:34 AM What's the teams lake on the "interface - type" duality, and will "namespace" be part of the proposal?

Joe Pea 9:34 AM oh, I misheard, it was Hegel

Asumu Takikawa 9:36 AM (we can add the type comparison to the github repo so it's easier to find)

Peeyush Kushwaha 9:36 AM Yes, and it seems the grammar on the repo is outdated as well

Asumu Takikawa 9:37 AM Homa Wong: can you clarify what you mean by interface-type duality?

Péter Frivalszky-Mayer 9:40 AM I think Homa means that a lot of things in TS can be defined as either interface or type and both get the job done, so it mostly comes down to personal preference.

Joe Pea 9:40 AM https://assemblyscript.org/ is another JS type checker (output to both JS or Wasm), borrowing on TypeScript syntax.

A small group of us have started chisseling away at https://github.com/bytescript/bytescript, another "TS to Wasm" effort, and we would like to align with ES syntax if types proposal gets official enough (stage 3?)

Asumu Takikawa 9:43 AM https://tc39.es/proposal-type-annotations/grammar.html

Homa Wong 9:47 AM Also notice that the spread operator (...) is missing from the proposal.

Joe Pea 9:50 AM I don't think it was mentioned, but interesting ideas here:

https://github.com/tc39/proposal-type-annotations/issues/188 Homa, namespace could be like so?

{}: namespace { ... }

but namespace is "deprecated" I'd say. It was a pre-ESModules thing.

Asumu Takikawa 9:50 AM Homa Wong: thanks we'll note that down, if you could file a Github issue for this that would be appreciated too

Peeyush Kushwaha 9:53 AM The examples are very TypeScript specific all throughout the repository, and other things seem to only be addressed in abstract things (like tokensoup). Should the proposal language be more neutral?

Rob Palmer 9:54 AM The grammar on-screen is token soup. Opaque Types are on line 64 of the spreadsheet comparison.

Andrew McCloud 9:55 AM https://github.com/niieani/typescript-vs-flowtype#flow-only-concepts

Dan Fabulich 9:55 AM https://flow.org/en/docs/types/opaque-types/

Homa Wong 9:55 AM

but namespace is "deprecated" I'd say. It was a pre-ESModules thing. It is "deprecated" for using it as an alternative to the ESModules. But it is not deprecated as a form of organizing the types.

I have this issue opened about this topic: https://github.com/tc39/proposal-type-annotations/issues/167

{}: namespace { ... }

It's a erasable type declaration same as "interface" and "type"

Joe Pea 9:56 AM What about things like "protected" and "private"? Would we leave that to JS /**? comments? generic calls seem to be ok in this proposal:

https://github.com/tc39/proposal-type-annotations/issues/188

Asumu Takikawa 9:57 AM Protected and private modifiers in classes should be included in the currently proposed grammar (https://tc39.es/proposal-type-annotations/grammar.html, if you search for "protected")

Romulo Cintra 9:59 AM https://docs.google.com/document/d/1ecYpaEj5XObkOCUzZ_Y6GlYTTydjPjb1urg09MGYAG4/edit

Lucas Santos 9:59 AM Se ya peeps, very nice!

Péter Frivalszky-Mayer 10:00 AM Thank you, great work!

Asumu Takikawa 10:00 AM Thanks all for attending!

trusktr commented 1 year ago

@unional based on #188, this is "erasable" because it results in an empty block at runtime:

{}: interface { etc }
{}: type foo = etc

same as this today:

{}
{}

EDIT: Oh, this works too (multiline comment):

:{
    // anything in here, f.e.:

    type Foo:<T> = T[];

    interface Bar:<T> {
        x: T;
    }
}

@msadeqhe is there single line comment? : anything here?

unional commented 1 year ago

Um, the keywords interface, type, (and namespace) is to defined them outside of the code so that they can be reused:

interface X { ... }

const x: X = ...
const y: X = ...

So I'm not sure if allowing them in {}: interface (as in function foo(): interface {...} { ... }

would be beneficial.

Of course, I can understand it allows extensibility of the type, just not sure what's the use case of it yet (may be more complicated type-level programming, as the example you have {}: { type ...; interface ...; "return ??" })

trusktr commented 1 year ago

@unional

So I'm not sure if allowing them in {}: interface (as in function foo(): interface {...} { ... }

It wouldn't be like that, it would be like follows, based on #188. If you have this TypeScript code:

// this is top level of a file

export interface Foo { /*...*/ }

export function makeFoo(foo: Foo) {}

then this would be the new equivalent:

// this is top level of a file

// This is a "standalone multiline type comment"
:{
  export interface Foo { /*...*/ }
}

// now use the `Foo` type somewhere else:
export function makeFoo(foo: Foo) {}

The key principle is: pretend that the :{ and the } are erased from the type checker's vision, totally ignore it.

The :{} simply defines an area where any syntax can be used. Really it is just another form of a comment, not even a type system. Even this is valid, and has no meaning (it is up to the userland tool, f.e. TypeScript, to define any meaning):

:{
  blah #$% blah
}

console.log('it works.') // this will run, the rest is just a comment.

It seems to be a token soup area, which might not be ideal according to today's meeting. But comments like /* ... */ also contain token soup, but the whole inside is simply ignored, so I think that technically the same can be done with comments like :{ ... } unless we specify new standard syntax inside of them later.

egasimus commented 1 year ago

Are people actually taking :{} syntax seriously? :frog:

It seems to be a token soup area, which might not be ideal according to today's meeting. But comments like / ... / also contain token soup, but the whole inside is simply ignored, so I think that technically the same can be done with comments like :{ ... } unless we specify new standard syntax inside of them later.

Sounds like opening a portal to hell. :man_shrugging:

Was anything discussed that positively rules out a comment-based syntax (as in https://github.com/tc39/proposal-type-annotations/issues/192) and necessitates a new breaking change to the language?

lillallol commented 1 year ago

Was anything discussed that positively rules out a comment-based syntax (as in https://github.com/tc39/proposal-type-annotations/issues/192) and necessitates a new breaking change to the language?

I suggest you to read the old meeting notes (links quoted in the first paragraph of the context repo README.md). There they give generic answers like: comments are not ergonomic. That is so so wrong form my experience, and that is true for both library creator and consumer.

The reality is that native comments is the best solution to the problem of static type checking before even the context proposal existed. Unfortunately admitting that, will mean that the context proposal should be dropped, and tsc should have never been a compiler (i.e. supersets were a mistake all along).

I will just quote this:

That generally, if you push on simplicity anywhere, you can get it everywhere eventually. So simplicity is the thing you should be driving, not complexity, but they didn’t know that. And I think if you have bought into that, you have emotional connection now to this format, and you’ve been telling people that it’s complicated for a reason, and it’s good that it’s complicated. And then this little piece of syntactic fluff shows up, which is solving the same problems without any complexity at all. You look stupid. And also, you have invested a lot of time and energy into learning this thing, which turns out is becoming irrelevant. And that’s a tough thing. And if you’re a consultant, it’s even harder, because you’ve established a standing in the community that you have clients because this stuff, and this stuff is no longer the thing. And so, a lot of them took this really, really hard.

Douglas Crockford creator of JSON[link]

egasimus commented 1 year ago

The reality is that native comments is the best solution to the problem of static type checking before even the context proposal existed. Unfortunately admitting that, will mean that the context proposal should be dropped, and tsc should have never been a compiler (i.e. supersets were a mistake all along).

I think you may be right.

Still, even if the result of these discussions ends up being very different from the text of the original proposal, I believe that the problem space could benefit massively from a TC39-blessed solution, and that the most appropriate one would be the simplest and most compatible one.

Standardizing an extended comment syntax that supports type annotation would put JS on par with Python's doc strings, or Rust's doc comments. Since JS remains dynamically typed, it's not a big stretch to view type annotations as a machine-readable kind of documentation.

msadeqhe commented 1 year ago

@msadeqhe is there single line comment? : anything here?

No. Thanks for your suggestion to have something like ::-style comments.

Sounds like opening a portal to hell. 🤷‍♂️

@egasimus, It's just similar to code blocks from C and C++:

int get_number() {
    {
        int x = 0;
    }
    int x = 0;
    return x;
}

BTW with ::-style comments (: in :<T> is optional within them, because the whole statement is a comment):

// anything in here, f.e.:

::type Foo:<T> = T[];

::interface Bar:<T> {
    x: T;
}

In a nutshell the rules are:

trusktr commented 1 year ago

Interesting. The thing about this that is better than :{ ... } is not needing to close the comment, not needing block indentation. With exports, and without the extra :, it looks like the following for TypeScript (@unional):

:: export type Foo<T> = T[];

:: export interface Bar<T> {
    x: T;
}

:: export namespace {
  // ...
}

Not sure if we should avoid this conversation in this thread. I'll move to #188 for this.

theScottyJam commented 1 year ago

I opened an issue to discuss more deeply the concerns I briefly brought up in the meeting - about the grammar still being fairly complex.

callionica commented 1 year ago

Have the proposers had any revelations as a result of the community meeting or is the plan still to ask the software with the highest number of attackers (every feature is a target) and the highest number of users (every feature’s energy cost is huge globally) to add extra code to the JS parser whose only runtime effect - beyond increased attack surface and energy use - is to encourage users to ship more unused data between server and client?

unional commented 1 year ago

I'm not sure if the proposal/discussion is heading the right direction.

I understand people who don't want additional syntax thus pushing for #188 or #176.

I think one of the major issues people have is the extra syntax for nothing in runtime. So we increase the file size, parsing cost for no additional benefit.

The problem, IMO, is that we scope the proposal to precisely that: the type are erasable, thus can be ignored by the engine.

If that is the direction, maybe we can drop the proposal. Adding a specific comment or comment syntax and leaving it open will create more fracture to the ecosystem. People will be more divided than ever, different code, different packages will use different syntax within the "comment space" supported by certain tool, and they are not cross-compatible, meaning the types from one package cannot be understood by another package.

To me that make no sense.

When asked about TypeScript, Brendan Eich himself commented that at some point, JavaScript will introduce types. It may look like TypeScript, it may look different, but he envisioned that it will happen sometime, somehow.

I think this proposal is that "sometime, somehow". It's about learning from existing tools, like TypeScript and Flow, and properly define a type system that will work at runtime.

I understand people want fewer syntax. I'm in the same camp too (think of lisp). But some syntax are definitely needed and I don't think we should "leave it open" for vendors to invent their own.

Will it be hard? Yes. Should it be done? I think so.

If you have debug JavaScript in the browser, you probably know that most of the time it is very difficult because the error occurs way too late. The source of error is multiple stack frames above. A runtime type system will fail the code much earlier, make it much easier to understand and detect.

Of course, type checking are expensive. So the "erasable" part of the proposal is still relevant. And it can be an opt-in support by the runtime. e.g. adding a type-checking option in the runtime to turn on/off the support.

My two cents, 🌷

azder commented 1 year ago

On a re-read, I think these two are antithetical:

But some syntax are definitely needed and I don't think we should "leave it open" for vendors to invent their own.

vs

Of course, type checking are expensive. So the "erasable" part of the proposal is still relevant.

In both cases, I guess, you just don't interpolate it into EcmaScript declarations, expressions etc. for clarity sake

unional commented 1 year ago
  • If you standardize it, and bake it into the language proper, why erase it?

I think the term "erasable" maybe a bit misleading, or I didn't use it the right way. May be "ignorable" is a better word? The engine will still need to tokenize and parse it into AST, but then can be ignored when the AST is processed.

If you erase it, on the other hand, why force vendors to comply to something that they might find... sub-optimal for their use case?

IMO, the confusion is still on the erasable part. In addition, this assume the result is "sub-optimal" for their use case. So it's still the issue of expectation. If we do not have a MVP that actually bring values to runtime, the additional processing doesn't seem to worth it.

When I was writing the comment above, I re-read the original proposal in the readme, and actually most of my concerns are already addressed. It's just that the discussions seem to a bit carried away.

Here is my own take, feel free to comment about it:

It is an opt-in to JavaScript in the sense that the runtime can parse and then ignore the type information and the code will still work. It can also use the type to email much earlier warnings/errors so that user can figure out what's wrong. This can even be focused on the server/development side, because if we can process the types during development, it is sufficient in most use cases.

Adding type to JavaScript is hard. Because type based on category theory and set theory and operating at a higher dimension of the value (JavaScript). We can do this incrementally, but the MVPs need to be sound and brings actual values to the runtimes/engines if they choose to utilize them.

Type information can be defined in standalone from or in embedded form (type X = ... vs function foo(a: boolean) { }) to maximize it usefulness. This is open for debate as Haskell style may work just fine (I'm not an expert in Haskell so I don't know if it is feasible):

type SomeType := (a: number, b: number) => void

type foo := SomeType
function foo(a, b) { ... }

New syntax is needed. And it should not leave the inner details to the vendors to create their own extension/syntax, which will fracture the community.

Maybe all types can be default as "module-public", i.e. skipping the extra export type ... everywhere. But in this case, the namespace concept is strongly needed so that we can provide a clean type API for each module file. And there is a special indicator for "global-public", for types that are added to the global object such as window.

P.S.: About #188, not strictly against it (anyway it is just my opinion), but IMO it should be considered as a fully defined syntax. Thinking of it as a comment runs the risk to not treating it as a full syntax and end up with escape rules that doesn't make sense as syntax.

Not a fan of #176, as I believe a proper syntax is needed (as mention in the above comment)

matthew-dean commented 1 year ago

@msadeqhe I instinctually had a similar proposal, except for the following:

  1. I think having two new comment / annotation forms is still too complex. It should be :: for everything, with special parsing rules. It is absolutely possible to clearly define parsing to handle all the existing use cases with just ::. Adding both : and :: is not necessary and IMO adding the smallest surface area should be a goal.
  2. I think that this feature should be called "notes" and not comments, and be available at runtime via a Reflect API extension (as an array of strings per inspected object)