<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><br>
</p>
<br>
<div class="moz-cite-prefix">On 07/07/17 17:04, Dmitry Petrashko
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:356BE109-1EFD-4C93-BCED-D6BF758508B3@gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<div style="font-family:sans-serif">
<div style="white-space:normal">
<p dir="auto">On 7 Jul 2017, at 17:17, Maurizio Cimadamore
wrote:</p>
</div>
<div style="white-space:normal">
<blockquote style="border-left:2px solid #777; color:#777;
margin:0 0 5px; padding-left:5px">
<p dir="auto">I understand. In our mind, 'var' is simply a
way to tell the compiler "type missing here, please fill
it out" - and we'd like to keep the type inference as
orthogonal as possible from other related semantics.</p>
</blockquote>
</div>
<div style="white-space:normal">
<p dir="auto">This is also how it behaves in scala if you
don’t ascribe the type in pattern. The type will be filled
in by typer. Based on <a
href="http://cr.openjdk.java.net/%7Ebriangoetz/amber/pattern-match.html"
style="color:#3983C4" moz-do-not-send="true">http://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html</a></p>
<pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">exprswitch(b) {
case Box(var n) -> n;
};
</code></pre>
<p dir="auto">is equivalent to this in Scala:</p>
<pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">x match {
case Box(n) => n;
};
</code></pre>
<p dir="auto">Or am I misinterpreting? </p>
</div>
</div>
</blockquote>
They are the same yes. What I was trying to say, is that when
there's no manifest type you seem to let 'null' in (because of the
lack of instanceof under the hood), so two similarly looking
patterns have different behavior w.r.t. nulls, which I'm not wild
about (but I have never noticed it either having used Scala :-))<br>
<blockquote type="cite"
cite="mid:356BE109-1EFD-4C93-BCED-D6BF758508B3@gmail.com">
<div style="font-family:sans-serif">
<div style="white-space:normal">
</div>
<div style="white-space:normal">
<blockquote style="border-left:2px solid #777; color:#777;
margin:0 0 5px; padding-left:5px">
<blockquote style="border-left:2px solid #777; color:#999;
margin:0 0 5px; padding-left:5px; border-left-color:#999">
<p dir="auto">In Scala, the runtime uses |instanceof| test
(Option 1 in your writeup),<br>
while the exhaustivity checkers uses type system and
assumes absence of null (Option 2).<br>
For generics, we issue a warning that type parameters
are unchecked.<br>
Have you considered this option?<br>
</p>
</blockquote>
<p dir="auto">So, you are saying that Scala does option 1 -
but it tones it a bit down by emitting a warning (rather
than an harsh error) when generic types are found.<br>
<br>
This seems a sensible option - the only thing I don't
understand from your description - what does Scala do for
nested patterns? Is it another instanceof? If that's the
case, does it means that I cannot match against a List
whose head is null with a normal nested type test pattern?</p>
</blockquote>
</div>
<div style="white-space:normal">
<p dir="auto">Scala behaves the same way for top level and
nested patters:</p>
</div>
</div>
</blockquote>
Yep - that's what I feared :-)<br>
<br>
I think that, basically, the differences we're seeing here is that
my claim that 'case var t' is just a shorthand for 'case T t' is not
as obvious as I thought it would have been.<br>
<br>
In Scala var patterns and test patterns are two different things,
and treated in quite different ways (which means different null
behavior).<br>
<br>
As I said in my earlier email, I have a feeling that keeping
'var'-ness out of the equation might result in better
compositionality (after all, patterns are not the only place where
we intend to use 'var').<br>
<br>
Maurizio<br>
<blockquote type="cite"
cite="mid:356BE109-1EFD-4C93-BCED-D6BF758508B3@gmail.com">
<div style="font-family:sans-serif">
<div style="white-space:normal">
<p dir="auto">Lets say that we have <code
style="background-color:#F7F7F7; border-radius:3px;
margin:0; padding:0 0.4em" bgcolor="#F7F7F7">case class
Cons(hd: Object, tl: Cons)</code></p>
<pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">x match {
case Cons(a, b) => 1 // will match only if `x instanceof Cons`. will match even if a is null and b is null
case Cons(a, b: Cons) => 2 // will not match if b is null, but a may be null
case a: Cons => 3 // will not match null, is equivalent to the first option
case a => 4 // always matches
}
</code></pre>
<p dir="auto">now, details about type parameters and type
inference:</p>
<pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">case class Cons[T](hd: T, tl: Cons)
x match {
case Cons(a, b) => 1 // a will be inferred to be Any, our top type
case Cons[Int](a, b) => 2 // warning will be emitted that Cons[Int] is unchecked.
}
</code></pre>
<p dir="auto">In practice, people rarely see this warning due
to important observation that compiler uses:</p>
<pre style="background-color:#F7F7F7; border-radius:5px 5px 5px 5px; margin-left:15px; margin-right:15px; max-width:90vw; overflow-x:auto; padding:5px" bgcolor="#F7F7F7"><code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0" bgcolor="#F7F7F7">case class Cons[T](hd: T, tl: Cons) extends Seq[T]
val x: Seq[Int] = ???
x match {
case Cons[Int](a, b) => 2 // a warning will not be emitted, as we know that T is the same as in Seq and we “trust†x.
}
</code></pre>
<p dir="auto">Best,<br>
Dmitry</p>
</div>
</div>
</blockquote>
<br>
</body>
</html>