Need clarification on Scala literal identifiers (backticks)
Asked Answered
L

2

69

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.

Legwork answered 4/7, 2011 at 22:37 Comment(0)
P
132

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).

Passel answered 4/7, 2011 at 22:52 Comment(6)
There also seems to be a special case for package objects. E.g. in Predef.scala, there is this line: scala.`package` // to force scala package object to be seen. Not sure it's a special case though… Any comment?Omor
Normally, you would not need to refer to a specific package object but just import whatever method you need from the package. In the Predef, I guess, this is a bit special because you explicitly want to expose those methods. Apart from that, it is not really special. It turns a keyword into an identifier just the same.Passel
Ok, maybe it’s not exposing but something else.Passel
You can also define a package object with: object `package` {}Morrison
It also allows one to have a script called my-script.scala with object `my-script`.Illusage
Another case where literal identifiers can be very useful: producing JSON with a Scala reserved word as field name (e.g. {"type": "foo"}) using Play's JSON API. https://mcmap.net/q/281694/-scala-reserved-word-as-json-field-name-with-json-writes-a-play-equivalent-for-serializednameThera
M
20

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.

Mchail answered 22/8, 2013 at 21:52 Comment(3)
+1 Happens to be the precise situation I was looking for when i googled!Rhythmandblues
what type and value is c?Marilyn
an ActorRef but not especially the child instanceDonothing

© 2022 - 2024 — McMap. All rights reserved.