Where does the interpolated expression end?

Inside a string, prefixed by s, the $ specifies the beginning of what exactly? Is $ always followed by either a variable name or an opening { ?

I was recently bitten by the following error in my sort compare function:

s"$a.x" < s"$b.x"

I was thinking that a.x and b.x would be evaluated and interpolated into the strings. But lo and behold, only a and b were interpolated, and a literal “.x” was appended in each case. This caused a really hard to find bug in a sorting function, which worked sometimes but not other times.

After encountering this but in my program, I started always enclosing the expression in braces s"ab${c}.${e.f}", but IntelliJ gives a warning about redundant braces.

$ without braces always binds to a variable or method name. More complex expressions than a simple name have to be enclosed in braces. Names that don’t conform to the regex [a-zA-Z][a-zA-Z0-9_]* should also be enclosed in braces.

1 Like

when you say “method name” are you saying that it stops at the open paren following the method name? s"$xyz(3)"

Yes. Sorry that wasn’t really clear. I included methods for completeness, but it applies only to parameterless methods. $ only binds to names, or to expressions enclosed in { }.

You should actually be a bit careful about this in Scala 3 because it has much better eta expansion:

scala>  def foo(i: Int) = i                                                     
def foo(i: Int): Int

scala> s"$foo(3)"                                                               
val res0: String = Lambda$1233/1167607380@4c5406b(3)

What happens here is that the compiler eta expands the expression foo, prints the nonsense name of the resulting function, followed by (3). Perhaps that should become a warning or even error.

1 Like