Ecma262: Add `NoSubstitutionTemplate` to `StringLiteral` Definition

Created on 9 Jan 2019  路  11Comments  路  Source: tc39/ecma262

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?

feature suggestion

Most helpful comment

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.

All 11 comments

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?

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.

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

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.

@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.

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?

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.

@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.

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.

@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.

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.

Was this page helpful?
0 / 5 - 0 ratings