Some Quasi specification issues

Allen Wirfs-Brock allen at
Fri Jun 29 16:34:49 PDT 2012

Here are several issues that I've identified with Quasis as I work to integrate the wiki quasi proposal [1] into the ES6 spec..

1) I think that the default substitutions for untagged quasi should be cooked, not raw.

The wiki defines the default Quasi tag [2] function as producing results based upon "raw" literal text.  This means that something like:

    const name = "Allen",  value="0.99";

would output:
rather than, what was more likely intended:
       ☞	Allen	$0.99

This seems wrong and error prone.  The default substitution should expand escapes rather than using the raw literal text.  More generally,

For any ES string literal that does not contain an unescaped ${, replacing the string delimiters (" or ') with back quote (`) should produce the same string value.  EG,
     "abcdef\nxyz\n" or 'abcdef\nxyz\n'
should produce the same values as:

2) LineContinuations should be removed for cooked quasi literal text.

this is required for consistency with the string replacement principal stated above:


should yield the same value as:

which is the same as "123"

Note however that quasis can still contain literal LineTerminators that become part of the string value.  EG,

yields the same value as "1\n2\n3" (assuming that linefeed is the new line character used in the program text)

3)  The raw tag should be a property of String.

The wiki suggests [3]  that a "raw" tag provides the equivalent to Python raw strings:
       raw`In JavaScript '\n' is a line-feed.`
produces the same value as:
       "In JavaScript '\\n' is a line-feed."

However, the wiki doesn't specify where or how raw is defined.  Rather than defining a new global or requiring a import I suggest that we make "raw" a property of the String constructor. EG,
        String.raw`In JavaScript '\n' is a line-feed.`

4) Should we also have a mostly raw tag that treats everything as raw except for explicit line continuation?
This would allow raw strings to be spread across multiple lines without inserting newlines that are there solely for source code formatting purposes.  EG:

line 1\n\
line 2\n\
line 3\n`

produces the same result as "line 1\nline 2\nline 3\n"

5)  Simplify the "call site object" to be an array
I think the most common use case is going to be for tag functions to use the cooked text. So let's make the "call site object" [4] be the array of cooked literal portions rather than having to indirect through a "cooked" property.  Instead the first argument to tags would be defined equivalently to:

const ungeussableCallSiteId1234 = do {                     // it would sure be nice to have this in ES
     let CSid = [literalSegment1, literalSegment2, ...]; / /... is meta
     CSid.raw = Object.freeze([rawLiteralSegment1, rawLiteralSegment2, ...]);  / /... is meta

Most tag functions would then have a signature like:
     let tag = (lits, subs) =>  { ... }
and within the body lits can be directly processed as a (frozen) Array.  Only if the functions actually uses raw values would it have to do a qualified reference such as lits.raw.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list