1

So I had an error where a match expression always yielded unreachable cases looking like this.

class KeyControl(left: String, right: String, up: String, down: String){
    def direction(key: String): (Int, Int) = {
    key match{
      case left => (-1,0)
      case right => (1,0)
      case up => (0,-1)
      case down => (0,1)
      case _ => (0,0)
    }
  }
}

object HelloWorld {
   def main(args: Array[String]) {
      println("Hello, world!")
      
      val kc: KeyControl = new KeyControl("left", "right", "up", "down")
      
      println(kc.direction("up"))
      
   }
}

The correct output should be:

Hello, world!
(0,-1)

However I always got warnings and errors where case right, case up, case down always was unreachable. I couldn't wrap my head around why this happened. In my mind, it checks if key: String = "up" is equal to left: String = "left" [false] right: String = "right" [false] up: String = "up" [true] -> return (0,-1) But since case left always seems to be true I guess I'm wrong. When trying this exact code however in an online IDE I got the error:

HelloWorld.scala:5: warning: unreachable code due to variable pattern 'left' on line 4
If you intended to match against value right in class KeyControl, you must use backticks, like: case `right`

After following their recommendations and changing all cases to `left`, `right`, `up`, `down` the match expression now works perfectly. My question for the people here is why backticks are necessary when matching string values?

Tarmiac
  • 846
  • 1
  • 8
  • 14
  • 2
    What happens is that `case foo` means match whatever and give it the name `foo` this is very useful in a lot of contexts. But since your use case is also a valid one; it would be ambiguous. Thus, the developers needed to find a way to remove the ambiguity and the option they picked was to give a proper syntax to disambiguate both use cases. – Luis Miguel Mejía Suárez Nov 17 '21 at 22:14
  • 2
    Maybe this could help you: https://www.scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#stable-identifier-patterns - using plan variable name like `case left` causes it to match any value. It needs to be converted to Stable Identifier. You could also write it as `case this.left =>` – Kamil Duda Nov 17 '21 at 22:22

0 Answers0