Need clarification on Scala literal identifiers (backticks) - scala

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.

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

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.

Related

When is case syntactically significant?

A/a case, not case case.
Apparently case a matches anything and binds it to the name a, while case A looks for an A variable and matches anything == considers equal to A. This came as quite a surprise to me; while I know Scala is case sensitive, I never expected identifier case to affect the parsing rules.
Is it common for Scala's syntax to care about the case of identifiers, or is there only a small number of contexts in which this happens? If there's only a small number of such contexts, what are they? I couldn't find anything on Google; all I got were results about pattern matching.
There is one more that is similar in nature, called a type pattern. In a type pattern, a simple identifier that starts with a lower case letter is a type variable, and all others are attempt to match actual types (except _).
For example:
val a: Any = List(1, 2, 3)
val c = 1
// z is a type variable
a match { case b: List[z] => a }
// Type match on `Int`
a match { case b: List[Int] => a }
// type match on the singleton c.type (not a simple lower case identifier)
// (doesn't actually compile because c.type will never conform)
a match { case b: List[c.type] => a }
Type matching like the the first example is lesser-known because, well, it's hardly used.

Selector of pattern match being exhaustive

Looking at the Scala doc for sealed classes, it says:
If the selector of a pattern match is an instance of a sealed class, the compilation of pattern matching can emit warnings which diagnose that a given set of patterns is not exhaustive, i.e. that there is a possibility of a MatchError being raised at run-time.
I don't quite understand what they meant in this paragraph. My understanding is that if a switch case, doesn't cover all the possibilities, then we'll get a warning at compile time, saying we might get an error at run time. Is this correct?
I find it strange, because how can we cover ALL the scenarios in a switch case? We would have to match all possible strings, which is just silly, so I take it my understanding is incorrect. Someone care to elucidate, please?
What the paragraph is saying is that in-case you have a fixed hierarchy structure like this:
sealed trait Foo
class Bar extends Foo
class Baz extends Foo
class Zab extends Foo
Then when you pattern match on it, the compiler can infer if you've attempted to match on all possible types extending the sealed trait, in this example:
def f(foo: Foo) = foo match {
| case _: Bar => println("bar")
| case _: Baz => println("baz")
| }
<console>:13: warning: match may not be exhaustive.
It would fail on the following input: Zab()
def f(foo: Foo) = foo match {
^
f: (foo: Foo)Unit
Note the beginning of the document says:
A sealed class may not be directly inherited, except if the inheriting
template is defined in the same source file as the inherited class.
This is unique to Scala, and can't be done in Java. A final class in Java cannot be inherited even if declared inside the same file. This is why this logic won't work for String in Scala, which is an alias for java.lang.String. The compiler warning may only be emitted for Scala types that match the above criteria.
I find it strange, because how can we cover ALL the scenarios in a switch case? We would have to match all possible strings
Yes, if the selector has type String (except it isn't a sealed class, because that's a Scala concept and String is a Java class).
which is just silly
No. For strings, you just need a catch-all case, e.g.
val x: String = ...
x match {
case "a" => ...
case "b" => ...
case _ => ...
}
is an exhaustive match: whatever x is, it matches one of the cases. More usefully, you can have:
val x: Option[A] = ...
x match {
case Some(y) => ...
case None => ...
}
and the compiler will be aware the match is exhaustive even without a catch-all case.
The wildcard character allows us to cover all the scenarios.
something match {
case one => ...
case two => ...
case _ => ...
}
It is selected whenever all other cases don't match; that is, it is the default case. Further information here.

Scala: pattern matching Option with case classes and code blocks

I'm starting to learn the great Scala language ang have a question about "deep" pattern matching
I have a simple Request class:
case class Request(method: String, path: String, version: String) {}
And a function, that tries to match an request instance and build a corresponding response:
def guessResponse(requestOrNone: Option[Request]): Response = {
requestOrNone match {
case Some(Request("GET", path, _)) => Response.streamFromPath(path)
case Some(Request(_, _, _)) => new Response(405, "Method Not Allowed", requestOrNone.get)
case None => new Response(400, "Bad Request")
}
}
See, I use requestOrNone.get inside case statement to get the action Request object. Is it type safe, since case statement matched? I find it a bit of ugly. Is it a way to "unwrap" the Request object from Some, but still be able to match Request class fields?
What if I want a complex calculation inside a case with local variables, etc... Can I use {} blocks after case statements? I use IntelliJ Idea with official Scala plugin and it highlights my brackets, suggesting to remove them.
If that is possible, is it good practice to enclose matches in matches?
... match {
case Some(Request("GET", path, _)) => {
var stream = this.getStream(path)
stream match {
case Some(InputStream) => Response.stream(stream.get)
case None => new Response(404, "Not Found)
}
}
}
For the first part of your question, you can name the value you match against with # :
scala> case class A(i: Int)
defined class A
scala> Option(A(1)) match {
| case None => A(0)
| case Some(a # A(_)) => a
| }
res0: A = A(1)
From the Scala Specifications (8.1.3 : Pattern Binders) :
A pattern binder x#p consists of a pattern variable x and a pattern p.
The type of the variable x is the static type T of the pattern p. This
pattern matches any value v matched by the pattern p, provided the
run-time type of v is also an instance of T , and it binds the
variable name to that value.
However, you do not need to in your example: since you're not matching against anything about the Request but just its presence, you could do :
case Some(req) => new Response(405, "Method Not Allowed", req)
For the second part, you can nest matches. The reason Intellij suggests removing the braces is that they are unnecessary : the keyword case is enough to know that the previous case is done.
As to whether it is a good practice, that obviously depends on the situation, but I would probably try to refactor the code into smaller blocks.
You can rewrite the pattern as following (with alias).
case Some(req # Request(_, _, _)) => new Response(405, "Method Not Allowed", req)
You cannot use code block in pattern, only guard (if ...).
There are pattern matching compiler plugin like rich pattern matching.

How to account for all cases of an enum on the right-hand side of a pattern match

Exhaustive pattern matching is great, but it only appears to work on the left-hand side of the case (=>) operator.
I am curious if there is a way that a person can verify that the output of a function (or expression) can be bound to that enumeration. The goal would be to have the compiler tell me when I forget to output an item from the enumeration.
In my example, I make use of the following enumeration containing three items:
object MyEnum {
sealed trait t
case object E1 extends t
case object E2 extends t
case object E3 extends t
}
And here is a pattern-match expression that would produce a compile-time warning (as we already know):
def foo( e : MyEnum.t ) : Boolean =
e match {
case MyEnum.E1 => true
case MyEnum.E2 => false
case MyEnum.E3 => true // if we leave this line out, we get a warning
}
Scala would complain if we left MyEnum.E3 out of the pattern matching expression, citing a non-exhaustive pattern match. This is profoundly beneficial, but I wonder if the reverse is possible.
Can we account for all cases of MyEnum.t on the right-hand side of =>?
Here is an example that highlights this:
def bar( s : String ) : Option[MyEnum.t] =
s match {
case "a" => Some(MyEnum.E1)
case "b" => Some(MyEnum.E2)
case "c" => Some(MyEnum.E3) // if we leave this out, no warning
case _ => None
}
In this example, if we leave out the line with MyEnum.E3, then the compiler just carries on as if nothing is wrong. The assertion I would like to make, is:
forall MyEnum.t (aliased as e) there exists Some(e) | None
I understand that this could be easily covered by a run-time test, but I'm curious if there is a way to check this statically.
Thanks.
I am going to push my luck and claim it is not possible (let's keep this a secret from Odersky). If the Scala compiler was able to detect such situations, I think it would be even slower than it already is ;)
The only way I could see is to define foo similarly to how you have done, and define bar by making it iterate over foo to make a reverse map, but that doesn't make much sense to me, and might not work in your specific case.
I think your case is a very good example for when unit tests are useful, so why not just write one?
No, it is not possible, because this is equivalent to the Halting Problem, which was proven unsolvable in 1936.

How to pattern match multiple values in Scala?

Let's say I want to handle multiple return values from a remote service using the same code. I don't know how to express this in Scala:
code match {
case "1" => // Whatever
case "2" => // Same whatever
case "3" => // Ah, something different
}
I know I can use Extract Method and call that, but there's still repetition in the call. If I were using Ruby, I'd write it like this:
case code
when "1", "2"
# Whatever
when "3"
# Ah, something different
end
Note that I simplified the example, thus I don't want to pattern match on regular expressions or some such. The match values are actually complex values.
You can do:
code match {
case "1" | "2" => // whatever
case "3" =>
}
Note that you cannot bind parts of the pattern to names - you can't do this currently:
code match {
case Left(x) | Right(x) =>
case null =>
}
The other answer correctly says that currently there is no way to pattern-match multiple alternatives while extracting values at the same time.
I'd like to share a coding pattern with you that comes close to doing this.
Scala allows you to pattern-match alternatives without extracting values, e.g. case Dog(_, _) | Cat(_, _) => ... is legal. Using this, you can simply extract the values yourself within the case block.
Here's a somewhat contrived example:
abstract class Animal
case class Dog(age: Int, barkLevel: Int) extends Animal
case class Cat(apparentAge: Int, cutenessLevel: Int) extends Animal
val pet: Animal = Dog(42, 100)
// Assume foo needs to treat the age of dogs and the apparent age
// of cats the same way.
// Same holds for bark and cuteness level.
def foo(pet: Animal): Unit = pet match {
case animal#(Dog(_, _) | Cat(_, _)) =>
// #unchecked suppresses the Scala warning about possibly
// non-exhaustiveness even though this match is exhaustive
val (agelike, level) = (animal: #unchecked) match {
case Dog(age, barkLevel) => (age, barkLevel)
case Cat(apparentAge, cutenessLevel) => (apparentAge, cutenessLevel)
}
???
}
Assume that ??? actually stands for doing something that is equal for dogs and cats. Without this coding pattern, you would need to have two cases, one for dogs and one for cats, forcing you to duplicate code or at least to outsorce code into a function.
Generally, the coding pattern above is suitable if you have sibling case classes that share fields that behave identically only for some algorithms. In those cases, you cannot extract those fields to a common superclass. Still, you would like to pattern-match in a uniform way on those fields in the algorithms that treat them equally. This you can do as shown above.