In short, the problem is that constructs like the following compile
without even a warning, and then fail with a MatchError at runtime:
val (a,b) = 1: Any
val (a,b) = Person("f", "l"): Product // with Person defined as
`case class Person(first: String, last: String)`
val Person(f, l) = ("f", "l"): Product
The real danger, of course, is that the right-hand side need not be
typed explicitly. The type may be inferred locally, or it may be the
return type of a method, etc. A refactoring could easily lead to
runtime failures.
I finally took the time to file an issue [2] and propose a
viable(-sounding) solution (admittedly, I don't know the compiler
internals). If you have any interest, please consider voting for
and/or watching the issue. Also, I would greatly appreciate any
feedback you might have on the proposal.
Thanks,
~Aaron
[1] http://www.scala-lang.org/node/8344 -- Is MatchError becoming
Scala's NullPointerException?
[2] https://issues.scala-lang.org/browse/SI-4670 -- Type safety
violations in value/variable definitions with patterns
Yes, that's exactly the issue, and the "clean slate" design you
suggested is basically what I proposed (except I like the `case`
keyword after `val`). Even if it's "baked in", I think the language
can move forward over time as follows:
1. Starting immediately, on `val (a,b) = x: Any`, the compiler should
warn that the construct is unsafe (which it can infer from the fact
that Tuple2's unapply method does not take an Any).
2. Introduce new syntax (suggestions I've seen so far include `val
case (a, b) = x: Any`, `case val (a, b) = x: Any`, and Martin's
preference `val ((a,b)) = x: Any`) to distinguish pattern matching
definitions. Now, the compiler should warn that the unsafe versions
are not only unsafe, but also deprecated.
3. The unsafe versions fail to compile without the new syntax.
At stages 1 and 2, a compiler option could be made available to make
the unsafe versions fail to compile.
Since type safety is at stake, and the existing syntax gives no reason
for developers to expect that there may be a runtime exception, I
think this issue is too serious for a documentation-only approach.
That said, gotchas like this *are* documented on stackoverflow [1]
(although it would be nice to have a more official location). You'll
notice that this essential issue (transparent pattern matching) is at
the root of two of the common mistakes listed on that page.
~Aaron
[1] http://stackoverflow.com/questions/1332574/common-programming-mistakes-for-scala-developers-to-avoid