Skip to content
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

Add `NoSubstitutionTemplate` to `StringLiteral` Definition #1399

Closed
ericbf opened this issue Jan 9, 2019 · 11 comments
Closed

Add `NoSubstitutionTemplate` to `StringLiteral` Definition #1399

ericbf opened this issue Jan 9, 2019 · 11 comments

Comments

@ericbf
Copy link

@ericbf ericbf commented Jan 9, 2019

Some teams opt to use exclusively template strings in their code (see template literals are strictly better strings for some reasoning).

This is almost supported by ECMA, but for the fact that StringLiteral is expressly defined as either a single quote or double quote string, excluding NoSubstitutionTemplates.

I contend that adding NoSubstitutionTemplates to the definition of StringLiteral will bring the benefit of allowing teams to completely opt to use only template strings instead of mixing quote marks, while having very little risk or downside, if any at all.

NoSubstitutionTemplates by nature are completely defined at "compile" time, essentially being exact same in functionality as standard StringLiterals. Let's make it so in the grammar as well?

@ljharb

This comment has been minimized.

Copy link
Member

@ljharb ljharb commented Jan 9, 2019

Since this seems like it would allow, for example, backticks around strict mode pragmas and import specifiers, that makes it a feature request - which per CONTRIBUTING.md are best suggested in places other than this repo. Am i understanding the request correctly?

@ericbf

This comment has been minimized.

Copy link
Author

@ericbf ericbf commented Jan 9, 2019

That's one interpretation of it, I suppose. In my reasoning, a NoSubstitutionTemplate is analogous (or even equivalent to) a StringLiteral and should have been included as part of the definition from its introduction. A NoSubstitutionTemplate is in fact a "literal string" in that it is literally represented by its value (no opportunity for interpolation or modification) and is a string. That's why I considered it as an issue when creating this.

@ljharb

This comment has been minimized.

Copy link
Member

@ljharb ljharb commented Jan 9, 2019

Perhaps @allenwb can speak to the motivations for not allowing template literals without substitutions anywhere quoted strings are allowed?

@erights

This comment has been minimized.

Copy link

@erights erights commented Jan 9, 2019

Speaking only for myself, not for @allenwb .

Untagged template literals without substitutions are just a degenerate case along two dimensions.

  • Removing the last substitution from a template literal should not change its semantics in a way different than removing any other substitution.
  • Removing a tag should not change the semantics in a (substantially) different way that simply changing to a tag that has that default behavior.

These two regularities make code easier to reason about.

Btw @ljharb Another place this shows up is in the airbnb style guide and eslint settings. They discourage template literals that happen to be in exactly this degenerate case. Other than this, the airbnb style is good. At Agoric, we use the airbnb eslint settings with this change to template literal policy.

@ljharb

This comment has been minimized.

Copy link
Member

@ljharb ljharb commented Jan 9, 2019

@erights the rationale there is that a substitutionless template literal is more likely to be a bug (forgetting an interpolation) than an intentional string, but noted.

@erights

This comment has been minimized.

Copy link

@erights erights commented Jan 9, 2019

As https://ponyfoo.com/articles/template-literals-strictly-better-strings elegantly argues, there are many good reasons to use a substitutionless template literal. Could the default be changed?

@bakkot

This comment has been minimized.

Copy link
Contributor

@bakkot bakkot commented Jan 9, 2019

Removing the last substitution from a template literal should not change its semantics in a way different than removing any other substitution.

Turning this around, I would think that there should never be a position in which a substitutionless template literal is legal but a template literal with a substitution is not. Which suggests that substitutionless templates should not be usable as property names or directives.

@ericbf

This comment has been minimized.

Copy link
Author

@ericbf ericbf commented Jan 10, 2019

@bakkot by the very nature of having different tokens for them in the grammar, they can and should behave differently. Why needlessly restrict the utility of NoSubstitutionTemplate, which is functionally equivalent to StringLiteral in that it doesn't involve interpolation (which in any case could be replaced with concatenation, but that is another story).

The idea is that a NoSubstitutionTemplate is equivalent to a StringLiteral, i.e., `string` is functionally equivalent to "string", while a Template is functionally equivalent to string concatenation, i.e., `hello ${name}` is equivalent to "hello " + name.

I would think that there should never be a position in which a substitutionless template literal is legal but a template literal with a substitution is not.

I don't think this necessarily follows. A substitutionless template literal is quite different from a template literal with substitutions in it, with not the least important of reasons being that the substitutionless template literal is invariable and safe to use at "compile" time, whereas template literals with substations may not be as the interpolated sections can vary.

@devsnek

This comment has been minimized.

Copy link
Member

@devsnek devsnek commented Jan 10, 2019

by the very nature of having different tokens for them in the grammar, they can and should behave differently.

I don't think the composition of the formal grammar matters much here. When using js, we don't call arrow function arguments "covered parenthesized expressions" because the composition of the grammar that allows both (x = 5) and (x = 5) => {} to be valid is irrelevant. From a design standpoint, a template literal with or without substitutions is still a template literal. The primitive idea of what a template literal is doesn't change, even if the name of the grammar production does.

@ericbf

This comment has been minimized.

Copy link
Author

@ericbf ericbf commented Jan 10, 2019

@devsnek point taken.

From a design standpoint, a template literal with or without substitutions is still a template literal.

Is it not reasonable to say that, similarly, a string literal (string without interpolation or concatenation) with "backtick" quotes, double quotes, or single quotes is still a string literal? It's possible for a thing to be categorized as more than one thing. In this case, a NoSubstitutionTemplate is both a StringLiteral and a Template.

@ljharb

This comment has been minimized.

Copy link
Member

@ljharb ljharb commented Jan 29, 2019

Given that this would need to be a new proposal, I'm going to close it per https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md#creating-a-new-proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.