Why aren't interpolation values in tagged template calls saved as a cached array?

Richard Gibson richard.gibson at gmail.com
Mon Jul 27 22:34:58 UTC 2020


There is no "interpolation values array"; a tag function receives a single
frozen array of static template contents (unique per call site) and a
distinct argument for each substitution value. Source code can collect them
*into* an array by use of ... "rest" syntax, but every evaluation of that
construct for a function call creates a new array
<https://tc39.es/ecma262/#_ref_4403>. But if there were a data structure to
modify in place, I think doing so would break the currently-specified
behavior of reentrant tagged templates and therefore not be an option.

Authors can use memoization and similar techniques to minimize garbage, and
there's certainly room for implementations to detect optimizable patterns,
but changing already-published semantics is rarely an option.

On Mon, Jul 27, 2020 at 5:30 PM #!/JoePea <joe at trusktr.io> wrote:

> > to start with, assuming the same `arguments` object is passed twice to
> two different invokes of a callback, would break down to ES3 and lower.
>
> I know, that's what I mentioned (it is historical, will never be the
> same object). :)
>
> > interpolated values you are passing around are always different, so I
> can't understand why would you expect an always same Array in there
>
> That's true. However, making a new array each time causes garbage
> collection that can otherwise be avoided.
>
> The interpolation values array could be made immutable for the user,
> while only the engine could be allowed to modify the content. The
> length of the array will never change. This will be much better than
> making a new array every time.
>
> Imagine, for example, hundreds of templates being called repeatedly
> for animations. It would simply be better if the values (f.e. numbers)
> were the only things changing. People could of course pass new objects
> as values on each update, but then that's their problem and an
> experienced developer will know about the cost in that case.
>
> > none of these suggestions would improve anything in the wild
>
> You don't think this idea would help for performance in some way?
>
> #!/JoePea
>
> On Sun, Jul 26, 2020 at 11:33 AM Andrea Giammarchi
> <andrea.giammarchi at gmail.com> wrote:
> >
> > there is some fundamental misconception of the ECMAScript standard in
> these examples ... to start with, assuming the same `arguments` object is
> passed twice to two different invokes of a callback, would break down to
> ES3 and lower.
> >
> > Secondly, interpolated values you are passing around are always
> different, so I can't understand why would you expect an always same Array
> in there ... it's not the same as the template one, which is immutable, aka
> frozen, and it can carry any different value at any different position.
> >
> > Accordingly, the current standard for template literals tags function is
> nearly perfect, and none of these suggestions would improve anything in the
> wild (using template literals since 2015, I think I've consumed them all in
> all flavours).
> >
> > Regards.
> >
> > On Sun, Jul 26, 2020 at 8:08 PM #!/JoePea <joe at trusktr.io> wrote:
> >>
> >> The following doesn't work either, and obviously it probably will
> >> never change because it is historical:
> >>
> >> ```js
> >> argsArrays = []
> >>
> >> function html() {
> >>     argsArrays.push(arguments)
> >> }
> >>
> >> let n = 0
> >> let n2 = 0
> >>
> >> function render() { return html`1st: ${n++}, 2nd: ${n2++}.` }
> >>
> >> render()
> >> render()
> >>
> >> console.log(argsArrays[0] === argsArrays[1]) // false!
> >> ```
> >>
> >> So yeah, just wondering why our only option is to use `...args` and
> >> create new arrays each time, thus the performance is not optimized
> >> like it is with the string parts.
> >>
> >> #!/JoePea
> >>
> >> On Sun, Jul 26, 2020 at 10:49 AM #!/JoePea <joe at trusktr.io> wrote:
> >> >
> >> > What I mean is,
> >> >
> >> > We can currently do this (try it in console):
> >> >
> >> > ```js
> >> > arrays = []
> >> >
> >> > function html(parts) { arrays.push(parts) }
> >> >
> >> > let n = 0
> >> > let n2 = 0
> >> >
> >> > function render() { return html`1st: ${n++}, 2nd: ${n2++}.` }
> >> >
> >> > render()
> >> > render()
> >> >
> >> > console.log(arrays[0] === arrays[1]) // true! <-------------------
> This!
> >> > ```
> >> >
> >> > But why don't specs allows us to do the following as well? (don't run
> >> > it, it doesn't work as intended)
> >> >
> >> > ```js
> >> > partsArrays = []
> >> > valuesArrays = []
> >> >
> >> > function html(parts, values) {
> >> >     partsArrays.push(parts)
> >> >     valuesArrays.push(values)
> >> > }
> >> >
> >> > let n = 0
> >> > let n2 = 0
> >> >
> >> > function render() { return html`1st: ${n++}, 2nd: ${n2++}.` }
> >> >
> >> > render()
> >> > render()
> >> >
> >> > console.log(partsArrays[0] === partsArrays[1]) // true!
> >> > console.log(valuesArrays[0] === valuesArrays[1]) // This would be
> >> > convenient too! I think?
> >> > ```
> >> >
> >> > Instead, if we want an array of the values, we have to use `arguments`
> >> > or `...args`. For example:
> >> >
> >> > ```js
> >> > // ... same ...
> >> > function html(parts, ...values) {
> >> >     partsArrays.push(parts)
> >> >     valuesArrays.push(values)
> >> > }
> >> > // ... same ...
> >> > console.log(partsArrays[0] === partsArrays[1]) // true!
> >> > console.log(valuesArrays[0] === valuesArrays[1]) // false! New array
> every time.
> >> > ```
> >> >
> >> > Seems like it would've been great to have the cached values arrays
> >> > too. Why isn't this the case?
> >> >
> >> > #!/JoePea
> >> _______________________________________________
> >> es-discuss mailing list
> >> es-discuss at mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20200727/793cdad0/attachment.html>


More information about the es-discuss mailing list