ASI edits

# Isiah Meadows (6 years ago)

I know this is probably bad timing (considering this PR and the fallout that followed), but I was thinking that it'd be nice if we could insert a [no LineTerminator here] clause in a few places, to remove some of the ASI hazards for those going semicolon-free, along with some extras for consistency:

One of the practical effects would be this: this source (taken from the spec):

a = b + c
(d + e).print()

is currently interpreted as:

a = b + c(d + e).print();

but would, with this proposal, be interpreted as this, which is a lot more intuitive with what people would expect:

a = b + c;
(d + e).print();

I know there's risk of web compat concerns, but I doubt they'd be significant for anything that's not minified via the Closure Compiler (which limits line length by default for reasons of old IE). Also, for most non-ASI people, they probably just forgot a semicolon anyways, and here is a concrete example of this, where ESLint was fixing a linter violation incorrectly because it wasn't reading it as you'd expect.


Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

# Claude Pache (6 years ago)

Le 12 janv. 2018 à 22:09, Isiah Meadows <isiahmeadows at gmail.com> a écrit :

I know this is probably bad timing (considering [this PR][1] and the fallout that followed), but I was thinking that it'd be nice if we could insert a [no LineTerminator here] clause in a few places, to remove some of the ASI hazards for those going semicolon-free, along with some extras for consistency:

  • Before the [ in the second rule of [MemberExpression][2] and the fourth rule of [CallExpression][3]
  • Before Arguments in the last rule of [MemberExpression][2], the third and sixth rule of [CallExpression][3], and [CoverCallExpressionAndAsyncArrowHead][4]
  • Before the ( in [FunctionDeclaration][5], [FunctionExpression][6], the first, fourth, and fifth rule of [MethodDefinition][7], [GeneratorMethod][8], both rules in [GeneratorDeclaration][9], and [GeneratorFunction][10]

One of the practical effects would be this: this source (taken from the spec):

a = b + c
(d + e).print()

is currently interpreted as:

a = b + c(d + e).print();

but would, with this proposal, be interpreted as this, which is a lot more intuitive with what people would expect:

a = b + c;
(d + e).print();

I know there's risk of web compat concerns, but I doubt they'd be significant for anything that's not minified via the Closure Compiler (which limits line length by default for reasons of old IE). Also, for most non-ASI people, they probably just forgot a semicolon anyways, and [here][11] is a concrete example of this, where ESLint was fixing a linter violation incorrectly because it wasn't reading it as you'd expect.

I think that the BC incompatibility issue is more than just a risk. I recall (but I couldn’t find it) that someone gave the example of some library that reads better when used as:

foo
  (bar)
  (baz)

Also, cases you have forgotten, and where I really wish there be a [NLTH] rule, are after some contextual keywords that are used in prefix position, namely get, set and static (as it is already the case for async). See tc39.github.io/proposal-class-fields/#sec-asi-hazards-in-class-bodies, tc39.github.io/proposal-class-fields/#sec-asi-hazards-in-class-bodies for context. This is not only to satisfy my coding style, but also to ensure consistency when further contextual keywords will be added in the top level of class bodies, since those future keyword will require such a [NLTH] rule in order to be compatible with previously written field declarations that take advantage ASI.

# Isiah Meadows (6 years ago)

Inline

Isiah Meadows me at isiahmeadows.com

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com

On Sat, Jan 13, 2018 at 9:54 AM, Claude Pache <claude.pache at gmail.com> wrote:

Le 12 janv. 2018 à 22:09, Isiah Meadows <isiahmeadows at gmail.com> a écrit :

I know this is probably bad timing (considering [this PR][1] and the fallout that followed), but I was thinking that it'd be nice if we could insert a [no LineTerminator here] clause in a few places, to remove some of the ASI hazards for those going semicolon-free, along with some extras for consistency:

  • Before the [ in the second rule of [MemberExpression][2] and the fourth rule of [CallExpression][3]
  • Before Arguments in the last rule of [MemberExpression][2], the third and sixth rule of [CallExpression][3], and [CoverCallExpressionAndAsyncArrowHead][4]
  • Before the ( in [FunctionDeclaration][5], [FunctionExpression][6], the first, fourth, and fifth rule of [MethodDefinition][7], [GeneratorMethod][8], both rules in [GeneratorDeclaration][9], and [GeneratorFunction][10]

One of the practical effects would be this: this source (taken from the spec):

a = b + c
(d + e).print()

is currently interpreted as:

a = b + c(d + e).print();

but would, with this proposal, be interpreted as this, which is a lot more intuitive with what people would expect:

a = b + c;
(d + e).print();

I know there's risk of web compat concerns, but I doubt they'd be significant for anything that's not minified via the Closure Compiler (which limits line length by default for reasons of old IE). Also, for most non-ASI people, they probably just forgot a semicolon anyways, and [here][11] is a concrete example of this, where ESLint was fixing a linter violation incorrectly because it wasn't reading it as you'd expect.

I think that the BC incompatibility issue is more than just a risk. I recall (but I couldn’t find it) that someone gave the example of some library that reads better when used as:

foo
  (bar)
  (baz)

Do you have any ideas where I could look to potentially find it? I've never seen that kind of DSL before, and that's an interesting use case I haven't considered.

Also, cases you have forgotten, and where I really wish there be a [NLTH] rule, are after some contextual keywords that are used in prefix position, namely get, set and static (as it is already the case for async). See tc39.github.io/proposal-class-fields/#sec-asi-hazards-in-class-bodies for context. This is not only to satisfy my coding style, but also to ensure consistency when further contextual keywords will be added in the top level of class bodies, since those future keyword will require such a [NLTH] rule in order to be compatible with previously written field declarations that take advantage ASI.

I thought about those, and I would ideally like those to be similarly chnaged, but I decided against including them in this particular proposal, since I wanted to focus on [ and (, and I wasn't as keen on web compat (considering it's actually a style many people prefer).

# Claude Pache (6 years ago)

Le 14 janv. 2018 à 03:31, Isiah Meadows <isiahmeadows at gmail.com> a écrit :

Inline

Isiah Meadows me at isiahmeadows.com <mailto:me at isiahmeadows.com>

Looking for web consulting? Or a new website? Send me an email and we can get started. www.isiahmeadows.com, www.isiahmeadows.com

On Sat, Jan 13, 2018 at 9:54 AM, Claude Pache <claude.pache at gmail.com <mailto:claude.pache at gmail.com>> wrote:

Le 12 janv. 2018 à 22:09, Isiah Meadows <isiahmeadows at gmail.com> a écrit :

I know this is probably bad timing (considering [this PR][1] and the fallout that followed), but I was thinking that it'd be nice if we could insert a [no LineTerminator here] clause in a few places, to remove some of the ASI hazards for those going semicolon-free, along with some extras for consistency:

  • Before the [ in the second rule of [MemberExpression][2] and the fourth rule of [CallExpression][3]
  • Before Arguments in the last rule of [MemberExpression][2], the third and sixth rule of [CallExpression][3], and [CoverCallExpressionAndAsyncArrowHead][4]
  • Before the ( in [FunctionDeclaration][5], [FunctionExpression][6], the first, fourth, and fifth rule of [MethodDefinition][7], [GeneratorMethod][8], both rules in [GeneratorDeclaration][9], and [GeneratorFunction][10]

One of the practical effects would be this: this source (taken from the spec):

a = b + c
(d + e).print()

is currently interpreted as:

a = b + c(d + e).print();

but would, with this proposal, be interpreted as this, which is a lot more intuitive with what people would expect:

a = b + c;
(d + e).print();

I know there's risk of web compat concerns, but I doubt they'd be significant for anything that's not minified via the Closure Compiler (which limits line length by default for reasons of old IE). Also, for most non-ASI people, they probably just forgot a semicolon anyways, and [here][11] is a concrete example of this, where ESLint was fixing a linter violation incorrectly because it wasn't reading it as you'd expect.

I think that the BC incompatibility issue is more than just a risk. I recall (but I couldn’t find it) that someone gave the example of some library that reads better when used as:

foo
 (bar)
 (baz)

Do you have any ideas where I could look to potentially find it? I've never seen that kind of DSL before, and that's an interesting use case I haven't considered.

I’ve finally found, see: esdiscuss.org/topic/consider-adding-more-no-lineterminator-here-to-avoid-problem-caused-by-omit-the-semicolon#content-3, esdiscuss.org/topic/consider-adding-more-no-lineterminator-here-to-avoid-problem-caused-by-omit-the-semicolon#content-3

Maybe not a significant example, but don’t underestimate the creativity of hackers.

Also, cases you have forgotten, and where I really wish there be a [NLTH] rule, are after some contextual keywords that are used in prefix position, namely get, set and static (as it is already the case for async). See tc39.github.io/proposal-class-fields/#sec-asi-hazards-in-class-bodies, tc39.github.io/proposal-class-fields/#sec-asi-hazards-in-class-bodies for context. This is not only to satisfy my coding style, but also to ensure consistency when further contextual keywords will be added in the top level of class bodies, since those future keyword will require such a [NLTH] rule in order to be compatible with previously written field declarations that take advantage ASI.

I thought about those, and I would ideally like those to be similarly chnaged, but I decided against including them in this particular proposal, since I wanted to focus on [ and (, and I wasn't as keen on web compat (considering it's actually a style many people prefer).

As someone who uses semicolon-less style, [, ( and other punctuation marks are not issues, but get, set and static in class fields are. My analysis: tc39/proposal-class-fields#7, tc39/proposal-class-fields#7

But regardless of your coding style, the historical behaviour of get, set and static in classes introduces some irregularity, which is always bad, while ( and [ do not:

class C {
    post // implicit semicolon here
    foo () { }
}

class D {
    get // no implicit semicolon here
    foo () { }
}

There are also issues around in and instanceof, but those are more likely to produce a syntax error in case of non-working ASI, and I think they are more problematic to correct.

# Michael Haufe (6 years ago)

Matt Might's MC Lexer is one example of a currying based DSL:

< matt.might.net/articles/lexing-and-syntax-highlighting-in-javascript

For example, to emulate what Lex provides:

// state (regex) (action) ;

<INIT> [_A-Za-z]+ { return(ID) ; } <INIT> [0-9]+ { return(NUM) ; }

in JavaScript you'd do:

INIT (/[_A-Za-z]+/) (function () { return ID ; }) ; INIT (/[0-9]+/) (function () { return NUM ; }) ;

or more modernly:

INIT (/[_A-Za-z]+/) (() => ID );

INIT (/[0-9]+/) (() => NUM ) ;