Need clarification on Scala literal identifiers (backticks)

Reading the Programming in Scala 2nd Ed and I came across this:

literal identifier "The idea is that you can put any string that's accepted by the runtime as an identifier between backtick"

I'm not entirely sure why I would use this? The book gave a use case of accessing the static yield method in Java's Thread class.

So since in Scala, yield is a reserve word, if I use yield with backticks,

Thread.`yield`()

it would ignore the Scala's yield and let me access the Java's Thread class's method yield instead?

Thank you in advance.


Solution 1:

Exactly. Using backticks, you can more or less give any name to a field identifier. In fact, you can even say

val ` ` = 0

which defines a variable with name (one character of whitespace).

The literal definition of identifiers is useful in two cases. The first case is, when there is already a reserved word of the same name in Scala and you need to use a Java library which does not care about that (and of course, why should it).

The other use case comes with case statements. The convention is that lower case names refer to match variables, whereas upper case names refer to identifiers from the outer scope. So,

val A = "a"
val b = "b"
"a" match {
  case b => println("b")
  case A => println("A")
}

prints "b" (if the compiler were dumb enough not to fail with saying case A were unreachable). If you want to refer to the originally defined val b, you need to use backticks as a marker.

"a" match {
  case `b` => println("b")
  case A => println("A")
}

Which prints "A".

Add There is a more advanced use case in this recent question method with angle brackets (<>) where the backticks were needed to get the compiler to digesting the code for a setter method (which in itself uses some ‘magic’ syntax).

Solution 2:

Thank you @Debilski, it helps me to understand this code below from AKKA doc :

class WatchActor extends Actor {
    val child = context.actorOf(Props.empty, "child")
    ...
    def receive = {
        ...
        case Terminated(`child`) ⇒ ...
    }
}

The case :

case Terminated(`child`)

matches a message of type Terminated with ActorRef field equals to child which is defined earlier.

With this statement :

case Terminated(c)

We match every Terminated messages with any reference of ActorRef mapped in c.