Type safety violations in value/variable definitions

14 views
Skip to first unread message

Aaron Novstrup

unread,
Jun 6, 2011, 5:37:35 PM6/6/11
to scala-user
I've posted about this before [1] and I know it's come up other times
on this list, but I thought it was worth raising again since the
previous thread got side-tracked (someone was apparently more
disturbed by a confusing compile error than by surprising runtime
failures *sigh*).

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

Matthew Pocock

unread,
Jun 6, 2011, 6:31:58 PM6/6/11
to Aaron Novstrup, scala-user
I'm not entirely sure, but I think that things like val(a,b)=1:Any are compiling because the (a,b) is treated as a non-exhaustive pattern match - like a single example of something directly after the case keyword. Hence, because it is possible that an Any is in fact a pair, (a,b) may sometimes match.

It seems a little counter-intuitive to me that this is the choice of semantics here. If I where designing this from a clean slate, I'd have done it like this:

val (a, b) = 1: Any // compiler complains because not every Any is an (a, b)
case val (a, b) = 1: Any // you've agreed by using the case keyword that a possibly non-exhaustive match is taking place

However, this may be one of those things that is baked into the language now, and needs to be documented with appropriate 'here be dragons' in the documentation. Is there a process for publicly documenting these kinds of things? We really need a whole set of pages dealing with each language construct.

Matthew
--
Matthew Pocock
(0191) 2566550

Aaron Novstrup

unread,
Jun 6, 2011, 7:04:24 PM6/6/11
to Matthew Pocock, scala-user
Matthew,

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

Reply all
Reply to author
Forward
0 new messages