E07901: a double-quoted String is never interpolated - '${' needs a backtick String

Category: E07xxx Full resolution · Reported in phase: SYMBOL_DEFINITION · Classification: DOUBLE_QUOTED_STRING_NOT_INTERPOLATED · All error codes

What went wrong

A double-quoted String holds '${': "${count} items". A double-quoted String is plain text - it is never interpolated - so it would print the characters '${count} items', not the count. Only a backtick String interpolates. Double quotes DO interpolate in Kotlin, Groovy, Dart, PHP and the shells, which is where the habit comes from.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 43 (How do I escape characters in EK9 string interpolation?)
  • ek9 -q 909 (How does $ work inside backtick strings in EK9?)

How to fix it

The error message spells out both rewrites of the String it is on. To interpolate, use a backtick String:

  • "${count} items" --> `${count} items`

For the literal text, use a backtick String and escape the dollar:

  • "${count} items" --> `\${count} items`

In a backtick String a '$' that opens no interpolation is escaped too:

  • "cost $5 for ${count}" --> `cost \$5 for ${count}`

('\$' is not an escape in a double-quoted String - "\${count}" keeps the backslash - so the literal text needs the backtick form.)

Common causes

  • Writing a Kotlin, Groovy, Dart, PHP or shell string template
  • JavaScript template literals use '${' too - but only in backticks, exactly as EK9 does
  • A regular-expression replacement naming a group, "${day}" - write `\${day}` so the group reference reaches the regex unchanged

See also

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E07901: a double-quoted String is never interpolated - '${' needs a backtick String

#!ek9
defines module error.e07901.bad

  defines text for "en"

    ItemText

      itemsInBasket()
        -> count as Integer
        //Invalid: a text body's double-quoted String is no different
        "${count} items in your basket"

  defines program

    DoubleQuotedInterpolation()
      stdout <- Stdout()
      count <- 2

      //Invalid: a double-quoted String is never interpolated
      stdout.println("${count} items")

      //Invalid: an expression is no different
      total <- "Total: ${count * 2}"

      //Invalid: a backslash is not an escape for '$' in a double-quoted String, so this still holds '${'
      escaped <- "\${count} items"

      //Valid: a '$' that opens no interpolation is plain text in a double-quoted String
      price <- "Price: $42"

      //Valid: a backtick String interpolates, and '\$' in one keeps the literal text
      interpolated <- `${count} items`
      literal <- `\${count} items`

      stdout.println(`${total} ${escaped} ${price} ${interpolated} ${literal}`)

Fixed: Use a backtick String to interpolate, and \$ in one for a literal $

#!ek9
defines module error.e07901.good.fix

  defines text for "en"

    ItemText

      itemsInBasket()
        -> count as Integer
        //Invalid: a text body's double-quoted String is no different
        `${count} items in your basket`

  defines program

    DoubleQuotedInterpolation()
      stdout <- Stdout()
      count <- 2

      //Invalid: a double-quoted String is never interpolated
      stdout.println(`${count} items`)

      //Invalid: an expression is no different
      total <- `Total: ${count * 2}`

      //Invalid: a backslash is not an escape for '$' in a double-quoted String, so this still holds '${'
      escaped <- `\${count} items`

      //Valid: a '$' that opens no interpolation is plain text in a double-quoted String
      price <- "Price: $42"

      //Valid: a backtick String interpolates, and '\$' in one keeps the literal text
      interpolated <- `${count} items`
      literal <- `\${count} items`

      stdout.println(`${total} ${escaped} ${price} ${interpolated} ${literal}`)

Fixed: Use a backtick String

#!ek9
defines module error.e07901.good

  defines program

    CountItems()
      stdout <- Stdout()
      count <- 2

      //A backtick String interpolates
      stdout.println(`${count} items`)

      //'\$' in a backtick String keeps the literal text
      stdout.println(`\${count} items`)

Questions and answers

These Q&A entries show E07901 and its fix: