I noticed that there is no || operator available when pattern matching - is | short circuited?
In pattern matching, |
is short circuited. You can't call unapply
or the like (with returned parameters) with the or-operator, where side-effects might be more likely. So short-circuiting is purely an optimization technique (won't affect the correctness of the code except in extraordinary cases such as a side-effecting equals method). This does mean you are limited in your ability to short circuit or not for performance or side-effecting reasons.
To see this, if we write this code:
def matchor(s: String) = s match {
case "tickle" | "fickle" => "sickle"
case _ => "hammer"
}
We see this bytecode (in part)
public java.lang.String matchor(java.lang.String);
Code:
0: aload_1
1: astore_2
2: ldc #12; //String tickle
4: aload_2
5: astore_3
6: dup
7: ifnonnull 18
10: pop
11: aload_3
12: ifnull 25
15: goto 31
18: aload_3
19: invokevirtual #16; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z
22: ifeq 31
25: iconst_1
26: istore 4
28: goto 66
31: ldc #18; //String fickle
33: aload_2
...
66: iload 4
68: ifeq 78
71: ldc #20; //String sickle
73: astore 6
75: goto 82
...
82: aload 6
84: areturn
See the jump on line 28 to avoid testing the "fickle"
case? That's the short-circuit.
|
short-circuits.
object First {
def unapply(str: String): Boolean = {
println("in First")
str == "first"
}
}
object Second {
def unapply(str: String) = {
println("in Second")
str == "second"
}
}
object Run extends App {
"first" match {
case First() | Second() => None
}
//Output: In First
"first" match {
case Second() | First() => None
}
//Output: In Second\nIn First
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With