Hacker News new | ask | show | jobs
by conaclos 1194 days ago
Is there a difference between

   dedent`something ${code}`
and

   dedent(`something ${code}`)
? Not sure to understand the advantage of tagged strings here...
1 comments

The difference is on the tag side. "Tag functions" receive the string segments separately from the interpolated values, so like:

    function exampleTag(stringSegment, ...values) {
      console.log(stringSegment);
      console.log(values);
    }

    const myNumber = 123;
    
    exampleTag`foo ${myNumber} bar ${myNumber}`;

    // Prints:
    // ['foo', 'bar', '']
    // [123, 123]
This gives the tag function a way to access the interpolated values themselves, before they get coerced to a String. You're correct, though, that it really doesn't make much of a difference for a dedent function.
It is actually important for a dedent function when the interpolands contain newlines. Consider this example:

    function fmt(q, a) {
      return dedent`\
        Question: ${q}
        Answer: ${a}
      `;
    }
Since `dedent` is basically syntactic sugar for developer convenience, we want this function to be equivalent to this:

    function fmtDesugared(q, a) {
      return `Question: ${q}\nAnswer: ${a}\n`;
    }
Now consider this input:

    console.log(fmt("a\nb", "c\nd"));
    // should print:
    Question: a
    b
    Answer: c
    d
But if `dedent` only got to see the string after interpolation—like this—

    function fmtWrong(q, a) {
      return dedent(`\
        Question: ${q}
        Answer: ${a}
      `);
    }
then the input to `dedent` would be

      Question: a
    b
      Answer: c
    d
and so `dedent` would not strip any indentation. That is, `dedent` is meant to identify the maximal common leading indentation in the template as written by the developer, which should not depend on the values of the interpolands.

A stale GitHub issue on the dmnd/dedent repo has a real-world example where this matters and led to a subtle bug: https://github.com/dmnd/dedent/issues/22

That is an absolutely fantastic point, and one I hadn’t considered. Thanks for the explanation, and also for teaching me the word “interpolands”. :)