String identity template tag
Mike Samuel
mikesamuel at gmail.com
Fri Dec 14 19:03:53 UTC 2018
On Fri, Dec 14, 2018 at 12:51 PM Isiah Meadows <isiahmeadows at gmail.com>
wrote:
> I'll point out Kai could be on to something, although I disagree `zip`
> would be the right abstraction. Maybe `Array.interleave(...arrays)`? You
> could do `Array.interleave(template, args).map(String).join("")` for
> similar effect, and it'd be more generally useful.
>
> The key here is that iteration would stop after the index hits any array's
> length, so it'd be polyfilled kinda like this:
>
> ```js
> Array.interpolate = (...args) => {
> let ret = []
> let lengths = []
> let count = 0
> for (let i = 0; i < args.length; i++) {
> lengths[i] = args[i].count
> }
> for (let index = 0; ; index++) {
> for (let i = 0; i < args.length; i++) {
> if (index === lengths[i]) return ret
> ret[count++] = args[i][index]
> }
> }
> }
> ```
>
> (This could be optimized, though.)
>
As a data point, something like this loop appears in most of the template
tags I've written but
it's never had these precise semantics so I didn't bother putting it into
template-tag-common <https://www.npmjs.com/package/template-tag-common>.
That library makes it easy to split the operation of a template tag into 3
stages:
1. An optional configuration stage accessed by calling the template tag as
a regular function: mytag({ /* options */)`...`
2. Static analysis over the strings. This is memoized.
3. Computing a result from (options, strings, results of step 2,
interoplated values)
The final loop (step 3) in the template tags I maintain tends to looks like
function computeResult(options, staticState /* from step 2 */, strings,
...values) {
let n = values.length; // Could do Math.max(strings.length - 1,
values.length);
let result = strings[0]; // Usually strings.raw
for (let i = 0; i < n;) {
const interpolatedValue = f(options, staticState[i], values[i]);
// Sometimes code here looks backwards at the result to see if it needs
to avoid token-merging hazards.
result += interpolatedValue;
result += strings[++i];
}
return wrapResult(result); // Produce a value of a type that
encapsulates the tag's security guarantees.
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20181214/b50a528e/attachment-0001.html>
More information about the es-discuss
mailing list