Tagged template functions aren't normal functions in the same way that constructor functions aren't normal functions. They should never be called apart from in a special way. Constructors, with a new
, tagging functions with an interpolated string literal.
We have a convention that constructors must be in Pascal Case so it is clear to the caller that it's a constructor.
- Is there a similar convention for tagging functions?
- If not, would enforcing that they have a trailing underscore be ambiguous to any other convention?
function tagger_(s, name, food) {
return `${s[0]}${name}${s[1]}${food}${s[2]}`
}
const name = 'Dave';
const food = 'ice-cream'
const message = tagger_`Hello World! My name is ${name} and I like ${food} for dinner`;
console.log(message);
The argument for this not being a normal function is that the first argument isn't a string.
const log = console.log;
function tagger_(s) {
console.log(`Has raw property: ${!!s.raw}`);
}
tagger_(`Hello World!`);
tagger_`Hello World!`
Likewise the s.raw
property contains the string, unescaped. There would be no practical way to spoof this. Even if one could, it would be very bad practice.
function tagger_(s) {
console.log(`s.raw: ${s.raw}`);
}
tagger_`This\nhas\tspecial characters`
The Duck Typing Problem
Whilst it may be possible to create a duck-typed object to pass into the method such that it won't fail immediately, the interface of the engune-generated object might extent (e.g. maybe an escapedRaw
property is added). This would mean anything calling the method as a normal function would break.
When we write a normal function were totally in control of it, this isn't the case here because the s
parameter type isn't controlled by the writer if the function.