tc39 / proposal-string-cooked

ECMAScript proposal for String.cooked built-in template tag

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

String.rare: a half-cooked idea

conartist6 opened this issue · comments

I think there might actually be three functions worth considering:

  • String.raw, as exists already does no processing of escapes
  • String.cooked, as proposed here processes valid javascript escapes
  • String.rare, which processes some escapes: \`, \\, and \${

The reason you want to process \`, \\, and \${ even if you don't process any other escapes is that these three escapes always have meaning in a template string. Because they always have meaning, they create "embedding holes" in the language inside the template string: certain string content which has no valid syntactic representation.

The most obviously difficult example is trying to write a template string inside itself:

let js = String.rare;

js`js\`Hello\${' world!'}\``; // '`Hello ${' world!'}`';

if you had used String.raw then embedded content would be the unparseable:

js\`Hello\${' world!'}\`

While obviously String.cooked would handle this specific case, it only does so by making the assumption that all other escapes in the embedded language are JS escapes, which may or may not be correct.

I think the general problem is how to write any arbitrary text in the language, include backtick and ${. This is very inconvenient now. If you use escaping (cooked strings), then u can't use String.raw. (which means u need to escape all \) If you use String.raw then it even worse: there is no syntactic form to write backtick and ${.

But I think String.rare (do half escape) is not a good solution, escaping already a mental burden, String.rare make it even complicated. I think what we really need is real "raw string" which can embed arbitrary text in the source code of JS.

@hax I'm sorry, I'm not clear on your position. You said it's too much cognitive burden to have a method that serves this use case, but then you said that what is really needed is some way of solving this use case. Do you see some even simpler way of solving this problem?

@conartist6 I mean, the real problem and requirements is not escaping or substitutions of selected special chars, but how to express those chars literally. So String.rare does not solve the true issue

I wrote a proposal to solve the real issue behind that and will present it to the committee in Feb meeting.

https://github.com/hax/proposal-raw-string-literals

There's a pretty important difference between what you are and aren't escaping. I think if the embedding layer (raw-string) assigns some meaning to a character (like \\), it should be responsible for not passing that special meaning down into the embedded layer (which would should see \). But if the character doesn't have special meaning for the embedding layer (e.g. \n in raw JS strings) then exactly those characters should be embedded (\ and n). That's what I've proposed, and to my knowledge it would solve the problem completely.

Your solution is essentially to allow users to choose which embedding holes they want to have in their raw string. Mine is just to define a method that does not need to have any embedding holes.

I understand ` and ${ is special so only unescape them is a "solution". But IMO, it's more like a workaround, because u still need to manually escape those chars, and people are forced to remember what chars are "rare".

Note: u actually don't need to escape \, though there is a limitation that \ can't be the last char of template literal.

It's a bit funky though because you can write a literal \ without escaping it as \\ but you can't write a literal \\ without escaping it as \\\\

@conartist6 Not sure what u mean. U can use String.raw`\\` to get two backslashes.

Oh right, I forgot.