tc39 / proposal-class-fields

Orthogonally-informed combination of public and private fields proposals
https://arai-a.github.io/ecma262-compare/?pr=1668
1.72k stars 113 forks source link

Issues with ASI #7

Closed leobalter closed 6 years ago

leobalter commented 7 years ago

The current grammar for FieldDefinitionLists requires a closing semicolon:

https://tc39.github.io/proposal-class-fields/#sec-updated-syntax

ClassElement [Yield, Await] :
  ...
  FieldDefinitionList [?Yield, ?Await] ;
  static FieldDefinitionList [?Yield, ?Await] ;

I feel like it should optional, but maybe it's intentional and I'm here to request clarification.

Thanks

bakkot commented 6 years ago

@zenparsing We discussed that specific question in committee and decided that they did not. See notes, slides.

I was initially against allowing ASI here, but I've since been convinced it's not worth adding another exception, mostly because there doesn't seem to be any group of users which would be served by it. (The people who rely on ASI really object to having more required semicolons even if that means more edge cases, and the people who don't won't run into such ASI issues anyway.

And as far as I can tell, no one puts a linebreak between get and m(){}, so personally I don't think the new NLTH restrictions are really that big of a concern. As evidence of this claim, I note that both TypeScript and babel acted as if there was a NLTH restriction after get in class bodies for years, and apparently no one noticed except me when I was looking into ASI for class fields for this proposal, and then no one noticed when that behavior was fixed.

zenparsing commented 6 years ago

@bakkot Thanks for the links! I certainly agree that in current practice users almost universally place contextual keywords on the same line as the following token.

Still, for this particular case (field declarations without an initializer) my 🕷 sense is tingling quite strongly.

littledan commented 6 years ago

@zenparsing What do you think we should do for next steps to evaluate this concern?

littledan commented 6 years ago

@waldemarhorwat Do you have any more thoughts on this issue?

zenparsing commented 6 years ago

@littledan I have further thoughts on this topic but I'm not quite ready to discuss them yet. I'll follow up soon!

zenparsing commented 6 years ago

My biggest worry (that ASI would overly constrain MethodDefinition in both classes and object literals) turned out to be unjustified. We can still extend the method syntax with leading operator characters and other things down the road if we choose (and are willing to accept the mild ASI hazards).

The lesser worry is whether relying on NLT for new contextual keywords within class bodies (and object literal methods) creates a confusing situation, since some of the contextual keywords (get, set, and static) will not require NLT but some of them will (async, and all future keywords).

Before async, we had this situation:

Which is fairly simple.

What is the situation now? Internally, the syntax is a mess, but what is the simple intuition?

I suppose that the simple intuition, if we admit ASI here, is that contextual keywords should never end a line, regardless of what parsing context we might be in. This intuition seems acceptable to me.

It's unfortunate that we have to sacrifice internal consistency and simplicity in order to accommodate history and ergonomics (ASI in this case), but it's a tradeoff that we've had to make many times before, and it's probably the right call here (shrug)...

Unless @waldemarhorwat has any other thoughts?

bakkot commented 6 years ago

I suppose that the simple intuition, if we admit ASI here, is that contextual keywords should never end a line, regardless of what parsing context we might be in.

Yeah, that's my position.

(Though I might be happier if we could add NLTH restrictions to static, get, and set in class bodies, and relax the NLTH restriction on async in object literals. This would require splitting the grammar, but wouldn't be hard. Then the rule would be "contextual keywords should never end a line except in object literals", and that would actually match what the grammar demanded. Probably this isn't worth worrying about, though, since I believe it is already the case that people don't end lines with contextual keywords in practice.

No idea how risky that would be, though given that almost all tooling got these wrong until relatively recently, I suspect it might be doable.)