Hello everyone,
I hope that this is the correct list for this post.
Consider the following snippet:
def f(a: String): (Some[String], Boolean) = (Some(a), false)
val (a1: Option[String], a2: Option[String], a3: Boolean) = if (true) f("a") else (None, None, false)
Strangely, it compiles but throws a MatchError exception when run: scala.MatchError: (Some(a),false) (of class scala.Tuple2)
Return type seems to be checked at runtime - at least that is what I understood from running the code in the REPL with -print:
[[syntax trees at end of cleanup]] // <console>
package $line26 {
object $read extends Object {
def <init>(): $line26.$read.type = {
$read.super.<init>();
()
}
};
object $read$$iw$$iw extends Object {
<synthetic> private[this] val x$1: Tuple3 = _;
private[this] val a1: Option = _;
<stable> <accessor> def a1(): Option = $read$$iw$$iw.this.a1;
private[this] val a2: Option = _;
<stable> <accessor> def a2(): Option = $read$$iw$$iw.this.a2;
private[this] val a3: Boolean = _;
<stable> <accessor> def a3(): Boolean = $read$$iw$$iw.this.a3;
def <init>(): type = {
$read$$iw$$iw.super.<init>();
$read$$iw$$iw.this.x$1 = {
case <synthetic> val x1: Object = ($line25.$read$$iw$$iw.f("a"): Object);
case8(){
if (x1.$isInstanceOf[Tuple3]())
{
<synthetic> val x2: Tuple3 = (x1.$asInstanceOf[Tuple3](): Tuple3);
{
val a1: Object = x2._1();
val a2: Object = x2._2();
val a3: Object = x2._3();
if (a1.$isInstanceOf[Option]())
{
<synthetic> val x3: Option = (a1.$asInstanceOf[Option](): Option);
if (a2.$isInstanceOf[Option]())
{
<synthetic> val x4: Option = (a2.$asInstanceOf[Option](): Option);
if (a3.$isInstanceOf[Boolean]())
{
<synthetic> val x5: Boolean = (scala.Boolean.unbox(a3): Boolean);
matchEnd7(new Tuple3(x3, x4, scala.Boolean.box(x5)))
}
else
case9()
}
else
case9()
}
else
case9()
}
}
else
case9()
};
case9(){
matchEnd7(throw new MatchError(x1))
};
matchEnd7(x: Tuple3){
x
}
};
$read$$iw$$iw.this.a1 = $read$$iw$$iw.this.x$1._1().$asInstanceOf[Option]();
$read$$iw$$iw.this.a2 = $read$$iw$$iw.this.x$1._2().$asInstanceOf[Option]();
$read$$iw$$iw.this.a3 = scala.Boolean.unbox($read$$iw$$iw.this.x$1._3());
()
}
};
object $read$$iw extends Object {
def <init>(): type = {
$read$$iw.super.<init>();
()
}
}
}
On the other hand, these ones fail to compile as expected:
val (a1: Option[String], a2: Option[String], a3: Boolean) = f("a")
val (a1: Option[String], a2: Option[String], a3: Boolean) = if (true) f("a") else (None, false)
My question is, if I am correct, why is this being checked at runtime? We know that the function f returns a Tuple3. Shouldn't there be a compile error for this case?
Thanks in advance,
Emre