- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
sealed case classes and tableswitch
Thu, 2011-04-28, 03:39
Hi list,
Is there a way to get a match over a variant (i.e. a group of case
classes extending a sealed trait) to be compiled to a tableswitch? I
was surprised to see that it becomes a bucket brigade of instanceof
tests. I tried sealing the individual case classes as well. Thanks,
Jake
Thu, 2011-04-28, 05:17
#2
Re: sealed case classes and tableswitch
On Wed, Apr 27, 2011 at 8:33 PM, Paul Phillips wrote:
> On 4/27/11 7:39 PM, Jake Donham wrote:
>> Is there a way to get a match over a variant (i.e. a group of case
>> classes extending a sealed trait) to be compiled to a tableswitch?
>
> No. There should be.
Thanks for the quick reply. I see that it is possible to do it
manually with reasonable concision, e.g. for
sealed trait T
case class Foo(val s: String) extends T
case class Bar(val i: Int) extends T
object Test {
def foo(t: T) {
t match {
case Foo(s) => {
...
}
case Bar(i) => {
...
}
}
}
}
write instead:
sealed trait T { val c: Int }
case class Foo(val s: String) extends T { val c = 0 }
case class Bar(val i: Int) extends T { val c = 1 }
object Test {
def foo(t: T) {
(t.c : @annotation.switch) match {
case 0 => { val Foo(s) = t.asInstanceOf[Foo]
...
}
case 1 => { val Bar(i) = t.asInstanceOf[Bar]
...
}
}
}
}
Jake
Thu, 2011-04-28, 05:57
#3
Re: sealed case classes and tableswitch
On 4/27/11 9:08 PM, Jake Donham wrote:
> object Test {
> def foo(t: T) {
> (t.c : @annotation.switch) match {
> case 0 => { val Foo(s) = t.asInstanceOf[Foo]
> ...
> }
> case 1 => { val Bar(i) = t.asInstanceOf[Bar]
> ...
> }
Notes of historical interest:
http://lampsvn.epfl.ch/trac/scala/changeset/1370
08/28/03 14:39:52 (8 years ago)
"Added support for case class tags"
http://lampsvn.epfl.ch/trac/scala/changeset/12232
07/07/07 22:44:54 (4 years ago)
optimizing case class matches via tags (experimental)
http://lampsvn.epfl.ch/trac/scala/changeset/16488
11/04/08 15:56:08 (2 years ago)
Stripping out casetags.
http://lampsvn.epfl.ch/trac/scala/changeset/17201
02/25/09 00:26:25 (2 years ago)
Removed $tag method from ScalaObject? and rebuilt starr.
Why did this happen? Empirically, in modern hotspot a class-based
instance tests is so fast it's hard to improve upon, and there was no
evidence the $tags were offering such improvement. I read a paper
somewhere which did some measurements, and for smallish matches you were
better off not getting fancy. I find more interest in some of the other
ideas mentioned in #3375 like memoized hashcodes and reference equality.
Fri, 2011-04-29, 20:47
#4
Re: sealed case classes and tableswitch
On Wed, Apr 27, 2011 at 9:55 PM, Paul Phillips wrote:
> Why did this happen? Empirically, in modern hotspot a class-based
> instance tests is so fast it's hard to improve upon, and there was no
> evidence the $tags were offering such improvement. I read a paper
> somewhere which did some measurements, and for smallish matches you were
> better off not getting fancy.
Thanks, I found some discussion of the issue in Emir, Odersky,
Williams, "Matching Objects with Patterns":
http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.5295
It sounds like instanceof bucket brigades are specially recognized
(and compiled to dispatch tables?) by Hotspot.
Jake
On 4/27/11 7:39 PM, Jake Donham wrote:
> Is there a way to get a match over a variant (i.e. a group of case
> classes extending a sealed trait) to be compiled to a tableswitch? I
> was surprised to see that it becomes a bucket brigade of instanceof
> tests. I tried sealing the individual case classes as well. Thanks,
No. There should be. It's definitely something I would like to do, but
if you continue looking at the generated code you will soon agree there
are more pressing matters in the pattern matcher world.
This ticket is probably the one to watch:
https://lampsvn.epfl.ch/trac/scala/ticket/3375
(not in a "holding breath" sort of way though.)