Feature: preprocess template literals #971

Closed
jussi-kalliokoski opened this Issue Mar 7, 2015 · 7 comments

Projects

None yet

3 participants

@jussi-kalliokoski

One thing I've been thinking about a lot when using template strings is that it would be sweet to be able to define some preprocessing for template strings, especially when used to just create multiline strings without variables. This could be added by being able to specify specially treated tags. For example:

var html = minify`<html>
  <head>
  </head>
  <body>
  </body>
</head>`;

then if you pass in a html minifier as a preprocessor tag named minify, you'd get

var html = "<html><head></head><body></body></html>";

I don't have my own horse in the race as I no longer for example use angular that much, where this would be especially handy. :)

@kittens kittens added the enhancement label Mar 7, 2015
@kittens
Member
kittens commented Mar 7, 2015

This would likely be conflating runtime and compile-time logic which is kinda iffy and a slippery slope IMO. You wouldn't be able to deal with interpolated expressions since you'd obviously need runtime knowledge. Not sure how helpful this would be either since you'd just hoist the literal so it's only ran once. Thanks for the suggestion though! I'll tag this as "revisit" as something to potentially revisit in the future.

@kittens kittens closed this Mar 7, 2015
@kittens kittens added the revisit label Mar 7, 2015
@kpdecker
Contributor

My reading of the spec effectively defines this behavior FWIW: http://www.ecma-international.org/ecma-262/6.0/#sec-gettemplateobject Step 5 and Note 2 dictate that there is only ever one template object for a given raw string.

Implementing this would drastically improve performance of tagged templates and prevent issues where users try to write code around this behavior, i.e.

var map = new Map();
function tag(templateObj) {
  map.set(templateObj, extraData);
}

It's a bit of a reach but full spec compliance would need it... this does not address the question of if it's worth the complexity of implementing realm.templateMap :)

@kittens
Member
kittens commented Jun 25, 2015

Yeah, I know. It's actually noted in a disabled Traceur test comment. There's no way to do it without a runtime.

@kpdecker
Contributor

It's not full compliance as that is at the global level and that would be a nightmare to manage across builds (in a performant manner), but what about "hoisting" the raw string definition to the current compilation context? I.e. this:

var _taggedTemplateLiteral = require("babel-runtime/helpers/tagged-template-literal")["default"];
var _myTaggedTemplateLiteral1 = _taggedTemplateLiteral(["", " ", ""], ["", " ", ""]);

var data = [1, 2, 3];
function fn(strings, value1, value2) {
  return strings[0] + value1 + strings[1] + value2 + strings[2];
}

test(function () {
  fn(_myTaggedTemplateLiteral1, data[0], data[1] + data[2]);
});};
@kittens
Member
kittens commented Jun 25, 2015

I'm having trouble working out what the original input was. Making it file-dependent is probably worth it in normal mode (ie. not loose mode).

@kpdecker
Contributor

Original:

var data = [1,2,3];
function fn(strings, value1, value2) {
  return strings[0] + value1 + strings[1] + value2 + strings[2];
}

test(function() {
  fn`${data[0]} ${data[1] + data[2]}`;
});
@kpdecker kpdecker added a commit to kpdecker/babel that referenced this issue Jun 30, 2015
@kpdecker kpdecker Convert template objects to singletons
Create file-scoped template objects that are instantiated once and reused between different tagged template evaluations. This is a closer match to the spec behavior which demands reuse, but does not match the spec exactly with respect to scoping as it’s possible to have similar template objects defined in different file scopes within the same program. For now we are not able to cleanly handle this case as it would require a registry or similar lookup mechanism that is consistent across different combinations of builds and optimizers.

This has a 40x increase in six-speed throughput.

Partial fix for #971
e0aaaaf
@kpdecker kpdecker added a commit to kpdecker/babel that referenced this issue Jul 1, 2015
@kpdecker kpdecker Convert template objects to singletons
Create file-scoped template objects that are instantiated once and reused between different tagged template evaluations. This is a closer match to the spec behavior which demands reuse, but does not match the spec exactly with respect to scoping as it’s possible to have similar template objects defined in different file scopes within the same program. For now we are not able to cleanly handle this case as it would require a registry or similar lookup mechanism that is consistent across different combinations of builds and optimizers.

This has a 40x increase in six-speed throughput.

Partial fix for #971
de23a29
@kpdecker kpdecker added a commit to kpdecker/babel that referenced this issue Jul 19, 2015
@kpdecker kpdecker Convert template objects to singletons
Create file-scoped template objects that are instantiated once and reused between different tagged template evaluations. This is a closer match to the spec behavior which demands reuse, but does not match the spec exactly with respect to scoping as it’s possible to have similar template objects defined in different file scopes within the same program. For now we are not able to cleanly handle this case as it would require a registry or similar lookup mechanism that is consistent across different combinations of builds and optimizers.

This has a 40x increase in six-speed throughput.

Partial fix for #971
eed7502
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment