Template literals serve a wide range of use-cases in string formatting.
This has led to situations where these strings span a larger number of lines and become more complicated as well.
Currently you cannot place documentation directly inside a template string, because a template literal variable requires an expression to be provided. For example, the following is illegal:
const query = `a & b ${/* comment */} & c & d`;
As a minimal workaround, you need can inject through ${'' /* comment after empty string */}.
Comments would allow you to document segments of a (large or complex) template string, without having to split up the string into multiple parts (e.g. variables). Which introduces naming problems, dislocates the string order and/or requires multiple separate template-concattenations to occur (which may not be possible if a specialized template tag function is used).
Pairing the comment with an empty string works for simple string substitution, but not if you're running a template function that does more complex context-specific handling of substitutions, like a SQL or HTML parser.
However, we still need to think about how it's reflected into a template function. If it's treated as an interpolation point, we still have the same issue where a template function might mess it up. I guess this would just be completely ignored, so in your example there would be one literal segment comprised of a & b & c & d and no interpolation segments at all?
I had a tempting thought that technically you could make empty interpolation points not produce an error and instead be omitted from the template; but I suspect it is better to have a stricter syntax which only permits interpolation points without an expression if they instead only have comments. Then it is forwards compatible in case the empty interpolation may serve some purpose in the future.
Comments are definitely not whitespace; "whitespace" and "comments" may both often be erasable tokens but that doesn't mean one is a subset of the other.
Neither comments nor whitespace are syntactic tokens. Yes they're not the same thing at the lexical level, but when talking about syntax, that distinction is gone.
Simple white space and single-line comments are discarded and do not appear in the stream of input elements for the syntactic grammar. A MultiLineComment (that is, a comment of the form /*…*/ regardless of whether it spans more than one line) is likewise simply discarded if it contains no line terminator; but if a MultiLineComment contains one or more line terminators, then it is replaced by a single line terminator, which becomes part of the stream of input elements for the syntactic grammar.
Comments behave like white space and are discarded except that, if a MultiLineComment contains a line terminator code point, then the entire comment is considered to be a LineTerminator for purposes of parsing by the syntactic grammar.
Given that comments are not present at the syntax level, it may be better to reduce the impact on the language spec (and implementations) by not introducing comments at the syntax level.
However, I do think that ${} does not convey intent while ${/**/} does.
With ${/**/} you can presume the intent to comment on something, but with no text present. While ${} may be either malformed code.
I know I don't understand JS' approach to backwards compat; I'm assuming that anything that is a syntax error today may become valid code tomorrow. So ${} can still become an empty comment marker should that pan out better for the ecosystem.