- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Do you use case class inheritance?
Fri, 2009-04-03, 15:28
There has been some discussion recently about deprecating case class
inheritance (i.e. the ability to have case class Foo(...) and case
class Bar(...) extends Foo(...)). Nothing so far as a formal proposal
has been made, but I'd like to give it some thought (and certain
others are enthusiastically crying for it. Hi paul :-) ). This isn't
an sort of announcement, I'm just taking an opinion poll.
Reasons that have been given for deprecation:
- It doesn't appear to be that useful
- The current implementation is significantly buggy
- It has very strange interaction with equality
So it would be very appreciated if you could tell us if you use it and
could give us some specific examples of how and why.
Thanks,
David
Fri, 2009-04-03, 18:07
#2
Re: Do you use case class inheritance?
On Fri, Apr 3, 2009 at 10:27 AM, David MacIver <> wrote:
>
> It has very strange interaction with equality
>
> So it would be very appreciated if you could tell us if you use it and
> could give us some specific examples of how and why.
>
I use it for inheritance in my AST.
sealed abstract class CSValue extends Positional
sealed case class CSTuple(elements:List[Expression]) extends CSValue
sealed case class StringValue(value:String) extends CSValue
sealed case class LiteralStringValue(myValue:String) extends StringValue(myValue)
sealed case class RichStringValue(pattern:String) extends StringValue(myValue)
~~ Robert Fischer.
Grails Training http://GroovyMag.com/training
Smokejumper Consulting http://SmokejumperIT.com
Enfranchised Mind Blog http://EnfranchisedMind.com/blog
Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html
Fri, 2009-04-03, 18:47
#3
Re: Do you use case class inheritance?
You only need to seal once. "sealed" means "can't extend hierarchy outside of this compilation unit." The question is, can StringValue be an ordinary abstract class or even a trait?
sealed abstract class CSValue extends Positional
case class CSTuple(elements:List[Expression]) extends CSValue
trait StringValue extends CSValue { def value : String }
case class LiteralStringValue(value:String) extends StringValue
case class RichStringValue(value:String) extends StringValue
On Fri, Apr 3, 2009 at 9:52 AM, Robert Fischer <robert.fischer@smokejumperit.com> wrote:
sealed abstract class CSValue extends Positional
case class CSTuple(elements:List[Expression]) extends CSValue
trait StringValue extends CSValue { def value : String }
case class LiteralStringValue(value:String) extends StringValue
case class RichStringValue(value:String) extends StringValue
On Fri, Apr 3, 2009 at 9:52 AM, Robert Fischer <robert.fischer@smokejumperit.com> wrote:
On Fri, Apr 3, 2009 at 10:27 AM, David MacIver <<mailto:david.maciver@gmail.com>> wrote:
It has very strange interaction with equality
So it would be very appreciated if you could tell us if you use it and
could give us some specific examples of how and why.
I use it for inheritance in my AST.
sealed abstract class CSValue extends Positional
sealed case class CSTuple(elements:List[Expression]) extends CSValue
sealed case class StringValue(value:String) extends CSValue
sealed case class LiteralStringValue(myValue:String) extends StringValue(myValue)
sealed case class RichStringValue(pattern:String) extends StringValue(myValue)
~~ Robert Fischer.
Grails Training http://GroovyMag.com/training
Smokejumper Consulting http://SmokejumperIT.com
Enfranchised Mind Blog http://EnfranchisedMind.com/blog
Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html
Fri, 2009-04-03, 18:57
#4
Re: Do you use case class inheritance?
2009/4/3 James Iry :
> You only need to seal once. "sealed" means "can't extend hierarchy outside
> of this compilation unit." The question is, can StringValue be an ordinary
> abstract class or even a trait?
I can definitely see the desire to be able to do "case
StringValue(someString) => " here. It does seem like a valid use case.
Fri, 2009-04-03, 19:17
#5
Re: Do you use case class inheritance?
Justin du coeur wrote:
> do I correctly understand that standard best practice is to
> have an abstract conventional super-class, with case classes used only
> as the leaves of the inheritance tree?
Yes, although I'd go further and try to use sealed traits as
superclasses for my case classes. But makes no real difference.
It is more a stylistic issue, I just try to use traits instead of
abstract classes where ever possible.
> I do find myself curious about the equality interaction, though.
It is about the symmetry of equality:
scala> case class Foo(s: String)
defined class Foo
scala> case class Bar(override val s: String) extends Foo(s)
defined class Bar
scala> Bar("x") == Foo("x")
res0: Boolean = false
scala> Foo("x") == Bar("x")
res1: Boolean = true
- Florian.
Fri, 2009-04-03, 19:27
#6
Re: Do you use case class inheritance?
>> do I correctly understand that standard best practice is to have an
>> abstract conventional super-class, with case classes used only as the leaves
>> of the inheritance tree?
out of curiosity, what is the current wisdom about this vs. Scott
Meyer's old C++ note?
http://www.informit.com/content/images/020163371x/items/item33.html
thanks.
Fri, 2009-04-03, 19:37
#7
Re: Do you use case class inheritance?
From Section 5.2 of the spec:
A sealed class may not be directly inherited, except if the inheriting
template is defined in the same source file as the inherited class. However,
subclasses of a sealed class can be inherited anywhere.
-Mark
On Friday 03 April 2009 13:42, James Iry wrote:
> You only need to seal once. "sealed" means "can't extend hierarchy outside
> of this compilation unit." The question is, can StringValue be an ordinary
> abstract class or even a trait?
>
> sealed abstract class CSValue extends Positional
> case class CSTuple(elements:List[Expression]) extends CSValue
> trait StringValue extends CSValue { def value : String }
> case class LiteralStringValue(value:String) extends StringValue
> case class RichStringValue(value:String) extends StringValue
>
>
> On Fri, Apr 3, 2009 at 9:52 AM, Robert Fischer <
> robert.fischer@smokejumperit.com> wrote:
>
> > On Fri, Apr 3, 2009 at 10:27 AM, David MacIver < > david.maciver@gmail.com>> wrote:
> >
> >>
> >> It has very strange interaction with equality
> >>
> >> So it would be very appreciated if you could tell us if you use it and
> >> could give us some specific examples of how and why.
> >>
> >>
> > I use it for inheritance in my AST.
> >
> > sealed abstract class CSValue extends Positional
> > sealed case class CSTuple(elements:List[Expression]) extends CSValue
> > sealed case class StringValue(value:String) extends CSValue
> > sealed case class LiteralStringValue(myValue:String) extends
> > StringValue(myValue)
> > sealed case class RichStringValue(pattern:String) extends
> > StringValue(myValue)
> >
> > ~~ Robert Fischer.
> > Grails Training http://GroovyMag.com/training
> > Smokejumper Consulting http://SmokejumperIT.com
> > Enfranchised Mind Blog http://EnfranchisedMind.com/blog
> >
> > Check out my book, "Grails Persistence with GORM and GSQL"!
> > http://www.smokejumperit.com/redirect.html
> >
>
Fri, 2009-04-03, 20:07
#8
Re: Do you use case class inheritance?
Ouch! My bad! I don't know why I've had that stuck in my head for so long.
Hmmm, flexible but verbose.
On Fri, Apr 3, 2009 at 11:32 AM, Mark Harrah <harrah@bu.edu> wrote:
Hmmm, flexible but verbose.
On Fri, Apr 3, 2009 at 11:32 AM, Mark Harrah <harrah@bu.edu> wrote:
From Section 5.2 of the spec:
A sealed class may not be directly inherited, except if the inheriting
template is defined in the same source file as the inherited class. However,
subclasses of a sealed class can be inherited anywhere.
-Mark
On Friday 03 April 2009 13:42, James Iry wrote:
> You only need to seal once. "sealed" means "can't extend hierarchy outside
> of this compilation unit." The question is, can StringValue be an ordinary
> abstract class or even a trait?
>
> sealed abstract class CSValue extends Positional
> case class CSTuple(elements:List[Expression]) extends CSValue
> trait StringValue extends CSValue { def value : String }
> case class LiteralStringValue(value:String) extends StringValue
> case class RichStringValue(value:String) extends StringValue
>
>
> On Fri, Apr 3, 2009 at 9:52 AM, Robert Fischer <
> robert.fischer@smokejumperit.com> wrote:
>
> > On Fri, Apr 3, 2009 at 10:27 AM, David MacIver <<mailto:
> > david.maciver@gmail.com>> wrote:
> >
> >>
> >> It has very strange interaction with equality
> >>
> >> So it would be very appreciated if you could tell us if you use it and
> >> could give us some specific examples of how and why.
> >>
> >>
> > I use it for inheritance in my AST.
> >
> > sealed abstract class CSValue extends Positional
> > sealed case class CSTuple(elements:List[Expression]) extends CSValue
> > sealed case class StringValue(value:String) extends CSValue
> > sealed case class LiteralStringValue(myValue:String) extends
> > StringValue(myValue)
> > sealed case class RichStringValue(pattern:String) extends
> > StringValue(myValue)
> >
> > ~~ Robert Fischer.
> > Grails Training http://GroovyMag.com/training
> > Smokejumper Consulting http://SmokejumperIT.com
> > Enfranchised Mind Blog http://EnfranchisedMind.com/blog
> >
> > Check out my book, "Grails Persistence with GORM and GSQL"!
> > http://www.smokejumperit.com/redirect.html
> >
>
Fri, 2009-04-03, 20:17
#9
Re: Do you use case class inheritance?
to be clear, case classes would still be able to inherit from classes and
traits?
Fri, 2009-04-03, 20:27
#10
Re: Do you use case class inheritance?
2009/4/3 Channing Walton :
>
> to be clear, case classes would still be able to inherit from classes and
> traits?
Yes. And classes and traits would still be able to inherit from case
classes. The only thing that would be forbidden was the case where Foo
<: Bar and both Foo and Bar are case classes.
Fri, 2009-04-03, 20:47
#11
Re: Do you use case class inheritance?
I've used them in a situation similar to what's already been mentioned:
sealed trait JsValue
...
abstract case class JsBoolean(b: Boolean) extends JsValue
case object JsTrue extends JsBoolean(true)
case object JsFalse extends JsBoolean(false)
Though to be honest in this case I'd want to write my own JsBoolean.apply method, so writing my own unapply wouldn't be too much more hassle.
--j
On Fri, Apr 3, 2009 at 7:27 AM, David MacIver <david.maciver@gmail.com> wrote:
sealed trait JsValue
...
abstract case class JsBoolean(b: Boolean) extends JsValue
case object JsTrue extends JsBoolean(true)
case object JsFalse extends JsBoolean(false)
Though to be honest in this case I'd want to write my own JsBoolean.apply method, so writing my own unapply wouldn't be too much more hassle.
--j
On Fri, Apr 3, 2009 at 7:27 AM, David MacIver <david.maciver@gmail.com> wrote:
There has been some discussion recently about deprecating case class
inheritance (i.e. the ability to have case class Foo(...) and case
class Bar(...) extends Foo(...)). Nothing so far as a formal proposal
has been made, but I'd like to give it some thought (and certain
others are enthusiastically crying for it. Hi paul :-) ). This isn't
an sort of announcement, I'm just taking an opinion poll.
Reasons that have been given for deprecation:
- It doesn't appear to be that useful
- The current implementation is significantly buggy
- It has very strange interaction with equality
So it would be very appreciated if you could tell us if you use it and
could give us some specific examples of how and why.
Thanks,
David
Sat, 2009-04-04, 05:17
#12
Re: Do you use case class inheritance?
I don't think this use case has been mentioned before. If case classesinherit from an abstract class then you lose their "productness". Beingable to treat case classes as generic products is important for someapplications I am doing including rewriting.
To more explicit, in the following example, the numchildren (t) call is illegal since Top is not a subclass of Product.
abstract class Topcase class One (i : Int) extends Topcase class Two (s : String) extends Top
object Main { def main (args : Array[String]) = { println (topchildren (One (42))) println (topchildren (Two ("hello"))) } def topchildren (t : Top) = numchildren (t) def numchildren (p : Product) = p.productArity }
This can be fixed by changing the Top definition to either of these:
abstract class Top extends Productabstract case class Top ()
The second seems cleaner and would be lost if case class inheritancewere not allowed.
regards,Tony
On 04/04/2009, at 6:32 AM, Jorge Ortiz wrote:
To more explicit, in the following example, the numchildren (t) call is illegal since Top is not a subclass of Product.
abstract class Topcase class One (i : Int) extends Topcase class Two (s : String) extends Top
object Main { def main (args : Array[String]) = { println (topchildren (One (42))) println (topchildren (Two ("hello"))) } def topchildren (t : Top) = numchildren (t) def numchildren (p : Product) = p.productArity }
This can be fixed by changing the Top definition to either of these:
abstract class Top extends Productabstract case class Top ()
The second seems cleaner and would be lost if case class inheritancewere not allowed.
regards,Tony
On 04/04/2009, at 6:32 AM, Jorge Ortiz wrote:
I've used them in a situation similar to what's already been mentioned:
sealed trait JsValue
...
abstract case class JsBoolean(b: Boolean) extends JsValue
case object JsTrue extends JsBoolean(true)
case object JsFalse extends JsBoolean(false)
Though to be honest in this case I'd want to write my own JsBoolean.apply method, so writing my own unapply wouldn't be too much more hassle.
--j
On Fri, Apr 3, 2009 at 7:27 AM, David MacIver <david.maciver@gmail.com> wrote:There has been some discussion recently about deprecating case class
inheritance (i.e. the ability to have case class Foo(...) and case
class Bar(...) extends Foo(...)). Nothing so far as a formal proposal
has been made, but I'd like to give it some thought (and certain
others are enthusiastically crying for it. Hi paul :-) ). This isn't
an sort of announcement, I'm just taking an opinion poll.
Reasons that have been given for deprecation:
- It doesn't appear to be that useful
- The current implementation is significantly buggy
- It has very strange interaction with equality
So it would be very appreciated if you could tell us if you use it and
could give us some specific examples of how and why.
Thanks,
David
Sat, 2009-04-04, 11:37
#13
Re: Do you use case class inheritance?
2009/4/4 Tony Sloane :
> I don't think this use case has been mentioned before. If case classes
> inherit from an abstract class then you lose their "productness". Being
> able to treat case classes as generic products is important for some
> applications I am doing including rewriting.
> To more explicit, in the following example, the numchildren (t) call is
> illegal since Top is not a subclass of Product.
> abstract class Top
> case class One (i : Int) extends Top
> case class Two (s : String) extends Top
> object Main {
>
> def main (args : Array[String]) = {
> println (topchildren (One (42)))
> println (topchildren (Two ("hello")))
> }
>
> def topchildren (t : Top) =
> numchildren (t)
>
> def numchildren (p : Product) =
> p.productArity
>
> }
> This can be fixed by changing the Top definition to either of these:
> abstract class Top extends Product
> abstract case class Top ()
> The second seems cleaner and would be lost if case class inheritance
> were not allowed.
To be honest, I don't agree that the second seems cleaner. If case
class inheritance is deprecated I'm not going to lose any sleep over
this use case. :-)
Sat, 2009-04-04, 21:47
#14
Re: Do you use case class inheritance?
On 04/04/2009, at 9:31 PM, David MacIver wrote:
> 2009/4/4 Tony Sloane :
>> I don't think this use case has been mentioned before. If case
>> classes
>> inherit from an abstract class then you lose their "productness".
>> Being
>> able to treat case classes as generic products is important for some
>> applications I am doing including rewriting.
>> To more explicit, in the following example, the numchildren (t)
>> call is
>> illegal since Top is not a subclass of Product.
>> abstract class Top
>> case class One (i : Int) extends Top
>> case class Two (s : String) extends Top
>> object Main {
>>
>> def main (args : Array[String]) = {
>> println (topchildren (One (42)))
>> println (topchildren (Two ("hello")))
>> }
>>
>> def topchildren (t : Top) =
>> numchildren (t)
>>
>> def numchildren (p : Product) =
>> p.productArity
>>
>> }
>> This can be fixed by changing the Top definition to either of these:
>> abstract class Top extends Product
>> abstract case class Top ()
>> The second seems cleaner and would be lost if case class inheritance
>> were not allowed.
>
> To be honest, I don't agree that the second seems cleaner. If case
> class inheritance is deprecated I'm not going to lose any sleep over
> this use case. :-)
I guess we disagree then :-)
Tony
Sun, 2009-04-05, 00:47
#15
Re: Do you use case class inheritance?
Another point in favor of deprecating case class inheritance is that
it hampers the specificity of their Product types.
Before case class inheritance, a case class such as
case class Foo(a:Int, b:String)
would inherit from Product2[Int,String]. but now it only extends
Product, as explained in ticket 1799. Having at least the arity of the
product encoded somehow in the type can be very useful at times.
I recall asking for case class inheritance when it was first being
discussed, but am now convinced that it wasn't such a bright idea.
--
Rafael de F. Ferreira.
http://www.rafaelferreira.net/
On Sat, Apr 4, 2009 at 5:44 PM, Tony Sloane wrote:
> On 04/04/2009, at 9:31 PM, David MacIver wrote:
>
>> 2009/4/4 Tony Sloane :
>>>
>>> I don't think this use case has been mentioned before. If case classes
>>> inherit from an abstract class then you lose their "productness". Being
>>> able to treat case classes as generic products is important for some
>>> applications I am doing including rewriting.
>>> To more explicit, in the following example, the numchildren (t) call is
>>> illegal since Top is not a subclass of Product.
>>> abstract class Top
>>> case class One (i : Int) extends Top
>>> case class Two (s : String) extends Top
>>> object Main {
>>>
>>> def main (args : Array[String]) = {
>>> println (topchildren (One (42)))
>>> println (topchildren (Two ("hello")))
>>> }
>>>
>>> def topchildren (t : Top) =
>>> numchildren (t)
>>>
>>> def numchildren (p : Product) =
>>> p.productArity
>>>
>>> }
>>> This can be fixed by changing the Top definition to either of these:
>>> abstract class Top extends Product
>>> abstract case class Top ()
>>> The second seems cleaner and would be lost if case class inheritance
>>> were not allowed.
>>
>> To be honest, I don't agree that the second seems cleaner. If case
>> class inheritance is deprecated I'm not going to lose any sleep over
>> this use case. :-)
>
> I guess we disagree then :-)
>
> Tony
>
>
>
Sun, 2009-04-05, 08:47
#16
Re: Do you use case class inheritance?
Justin du coeur wrote:
> Okay, here's a question from a newbie, trying to understand the
> implications. Having read the comment that Seth quoted, and digested it
> a little, do I correctly understand that standard best practice is to
> have an abstract conventional super-class, with case classes used only
> as the leaves of the inheritance tree? (If so, Martin's comment is
> right: that's not obvious to newbies, and probably ought to be called
> out a bit more loudly in the book.) And what you're proposing is to
> make that more mandatory -- that case classes cannot be inner nodes of
> the tree, only leaves?
We have a use case where we have non-leaf case traits.
We use Ice for our RPC implementation, which generates Java classes. We extend
the Java classes with our own methods that implement the RPC calls in Scala. A
few of the classes have a form of a sealed trait with case classes.
So
abstract class JavaAbstractTime
abstract class JavaNowTime extends JavaAbstractTime
abstract class JavaFixedTime extends JavaAbstractTime
And then in Scala
sealed trait RichAbstractTime
trait RichNowTime
trait RichFixedTime
Finally, the classes that implement the RPC
class NowTimeImpl extends JavaNowTime with RichNowTime
class FixedTimeImpl extends JavaFixedTime with RichFixedTime
The Scala traits provide implementation methods to the implementation classes.
Regards,
Blair
Sun, 2009-04-05, 11:27
#17
Re: Do you use case class inheritance?
2009/4/5 Blair Zajac :
> Justin du coeur wrote:
>>
>> Okay, here's a question from a newbie, trying to understand the
>> implications. Having read the comment that Seth quoted, and digested it a
>> little, do I correctly understand that standard best practice is to have an
>> abstract conventional super-class, with case classes used only as the leaves
>> of the inheritance tree? (If so, Martin's comment is right: that's not
>> obvious to newbies, and probably ought to be called out a bit more loudly in
>> the book.) And what you're proposing is to make that more mandatory -- that
>> case classes cannot be inner nodes of the tree, only leaves?
>
> We have a use case where we have non-leaf case traits.
>
> We use Ice for our RPC implementation, which generates Java classes. We
> extend the Java classes with our own methods that implement the RPC calls in
> Scala. A few of the classes have a form of a sealed trait with case
> classes.
>
> So
>
> abstract class JavaAbstractTime
> abstract class JavaNowTime extends JavaAbstractTime
> abstract class JavaFixedTime extends JavaAbstractTime
>
> And then in Scala
>
> sealed trait RichAbstractTime
> trait RichNowTime
> trait RichFixedTime
>
> Finally, the classes that implement the RPC
>
> class NowTimeImpl extends JavaNowTime with RichNowTime
> class FixedTimeImpl extends JavaFixedTime with RichFixedTime
>
> The Scala traits provide implementation methods to the implementation
> classes.
Sorry, I think one of us is missing a point somewhere. This example
doesn't appear to involve case class inheritance?
To be clear: The only thing that anyone is proposing prohibiting is
things that look like the following:
case class Foo(stuff : Stuff);
case class Bar(stuff : Stuff, otherStuff : OtherStuff) extends Foo(stuff);
The following would still be allowed:
a) Case classes extending normal classes
b) Case classes extending traits
c) Normal classes extending case classes
d) Traits extending case classes (though I have to admit I've never
seen anyone do this, but there's no reason it should be prohibited)
(side note: Things where there are other classes between Foo and Bar
would also be forbidden. i.e. case class Foo; class Baz extends Foo;
case class Bar extends Baz; is also out).
Sun, 2009-04-05, 19:47
#18
Re: Do you use case class inheritance?
On Apr 5, 2009, at 3:24 AM, David MacIver wrote:
> 2009/4/5 Blair Zajac :
>> Justin du coeur wrote:
>>>
>>> Okay, here's a question from a newbie, trying to understand the
>>> implications. Having read the comment that Seth quoted, and
>>> digested it a
>>> little, do I correctly understand that standard best practice is
>>> to have an
>>> abstract conventional super-class, with case classes used only as
>>> the leaves
>>> of the inheritance tree? (If so, Martin's comment is right:
>>> that's not
>>> obvious to newbies, and probably ought to be called out a bit more
>>> loudly in
>>> the book.) And what you're proposing is to make that more
>>> mandatory -- that
>>> case classes cannot be inner nodes of the tree, only leaves?
>>
>> We have a use case where we have non-leaf case traits.
>>
>> We use Ice for our RPC implementation, which generates Java
>> classes. We
>> extend the Java classes with our own methods that implement the RPC
>> calls in
>> Scala. A few of the classes have a form of a sealed trait with case
>> classes.
>>
>> So
>>
>> abstract class JavaAbstractTime
>> abstract class JavaNowTime extends JavaAbstractTime
>> abstract class JavaFixedTime extends JavaAbstractTime
>>
>> And then in Scala
>>
>> sealed trait RichAbstractTime
>> trait RichNowTime
>> trait RichFixedTime
>>
>> Finally, the classes that implement the RPC
>>
>> class NowTimeImpl extends JavaNowTime with RichNowTime
>> class FixedTimeImpl extends JavaFixedTime with RichFixedTime
>>
>> The Scala traits provide implementation methods to the implementation
>> classes.
>
> Sorry, I think one of us is missing a point somewhere. This example
> doesn't appear to involve case class inheritance?
Oh yes, you're right. Don't reply to email too late at night :)
Regards,
Blair
Mon, 2009-04-06, 14:57
#19
Re: Do you use case class inheritance?
Tony Sloane schrieb:
> If case classes
> inherit from an abstract class then you lose their "productness".
Don't use abstract classes, then.
scala> trait Top
defined trait Top
scala> case class Foo(i: Int) extends Top
defined class Foo
scala> Foo(0).productArity
res0: Int = 1
- Florian.
Mon, 2009-04-06, 15:37
#20
Re: Do you use case class inheritance?
2009/4/6 Florian Hars :
> Tony Sloane schrieb:
>> If case classes
>> inherit from an abstract class then you lose their "productness".
>
> Don't use abstract classes, then.
>
> scala> trait Top
> defined trait Top
>
> scala> case class Foo(i: Int) extends Top
> defined class Foo
>
> scala> Foo(0).productArity
> res0: Int = 1
I think you've missed the point. That works fine with abstract classes
too. The problem is that Top doesn't extend Product, even though all
its subclasses do.
Mon, 2009-04-06, 15:47
#21
Re: Do you use case class inheritance?
Another possible work-around without case class inheritance:
trait Topcase class One (i : Int) extends Top case class Two (s : String) extends Top
object Main { def main (args : Array[String]) = { println (topchildren (One (42))) println (topchildren (Two ("hello"))) }
def topchildren (t : Top with Product) = t.productArity
}
- Colin
trait Topcase class One (i : Int) extends Top case class Two (s : String) extends Top
object Main { def main (args : Array[String]) = { println (topchildren (One (42))) println (topchildren (Two ("hello"))) }
def topchildren (t : Top with Product) = t.productArity
}
- Colin
Mon, 2009-04-06, 20:27
#22
Re: Do you use case class inheritance?
I use it to describe rules in a popular card game which has extremely
complex rules (I won't name it because I'm not sure where this project
will go or if it will go anywhere at all). But I have found them useful.
I do use case classes MOSTLY in Leaves, but for convenience I sometimes
use deeper hierarchies, sometimes case objects that extend case classes.
The best reason I can give is that it's easier to construct
expressions/sentences if I use more specific case classes/objects, but
when executing the expressions (with pattern matching), I don't care
about some of the leaf classes (leafs are for convenience when
constructing the expressions).
Is there something really complex about case class inheritance regarding
to equality etc. that they are difficult to implement? I know they are
currently buggy, I've filed one or two tickets about it.
Erkki
David MacIver wrote:
> There has been some discussion recently about deprecating case class
> inheritance (i.e. the ability to have case class Foo(...) and case
> class Bar(...) extends Foo(...)). Nothing so far as a formal proposal
> has been made, but I'd like to give it some thought (and certain
> others are enthusiastically crying for it. Hi paul :-) ). This isn't
> an sort of announcement, I'm just taking an opinion poll.
>
> Reasons that have been given for deprecation:
>
> - It doesn't appear to be that useful
> - The current implementation is significantly buggy
> - It has very strange interaction with equality
>
> So it would be very appreciated if you could tell us if you use it and
> could give us some specific examples of how and why.
>
> Thanks,
> David
>
>
Tue, 2009-04-07, 01:57
#23
Re: Do you use case class inheritance?
On 07/04/2009, at 12:33 AM, Colin Bullock wrote:
This one is nice if you don't have access to the Top trait. I presume that if you have many methods taking a Top parameter you can shorten the type using a type synonym such as
type TopP = Top with Product
but I haven't tried it.
If you do have access to the Top trait, it's easier to just inherit Product there. Doesn't make me like it though... :-)
Tony
Another possible work-around without case class inheritance:
trait Topcase class One (i : Int) extends Top case class Two (s : String) extends Top
object Main { def main (args : Array[String]) = { println (topchildren (One (42))) println (topchildren (Two ("hello"))) }
def topchildren (t : Top with Product) = t.productArity
}
This one is nice if you don't have access to the Top trait. I presume that if you have many methods taking a Top parameter you can shorten the type using a type synonym such as
type TopP = Top with Product
but I haven't tried it.
If you do have access to the Top trait, it's easier to just inherit Product there. Doesn't make me like it though... :-)
Tony
Tue, 2009-04-07, 04:07
#24
Re: Do you use case class inheritance?
I do not use case class inheritance.
2009/4/7 Tony Sloane <inkytonik@gmail.com>
2009/4/7 Tony Sloane <inkytonik@gmail.com>
On 07/04/2009, at 12:33 AM, Colin Bullock wrote:Another possible work-around without case class inheritance:
trait Topcase class One (i : Int) extends Top case class Two (s : String) extends Top
object Main { def main (args : Array[String]) = { println (topchildren (One (42))) println (topchildren (Two ("hello"))) }
def topchildren (t : Top with Product) = t.productArity
}
This one is nice if you don't have access to the Top trait. I presume that if you have many methods taking a Top parameter you can shorten the type using a type synonym such as
type TopP = Top with Product
but I haven't tried it.
If you do have access to the Top trait, it's easier to just inherit Product there. Doesn't make me like it though... :-)
Tony
Tue, 2009-04-07, 21:17
#25
RE: Do you use case class inheritance?
Doesn't the actor library use case classes/objects to represent message types. How do I define a message type that is a specialization of another message type without case class inheritance?
//Odd Möller
-----Original Message-----
From: David MacIver [mailto:david.maciver@gmail.com]
Sent: den 3 april 2009 16:27
To: scala
Subject: [scala] Do you use case class inheritance?
There has been some discussion recently about deprecating case class
inheritance (i.e. the ability to have case class Foo(...) and case
class Bar(...) extends Foo(...)). Nothing so far as a formal proposal
has been made, but I'd like to give it some thought (and certain
others are enthusiastically crying for it. Hi paul :-) ). This isn't
an sort of announcement, I'm just taking an opinion poll.
Reasons that have been given for deprecation:
- It doesn't appear to be that useful
- The current implementation is significantly buggy
- It has very strange interaction with equality
So it would be very appreciated if you could tell us if you use it and
could give us some specific examples of how and why.
Thanks,
David
Tue, 2009-04-07, 21:57
#26
Re: Do you use case class inheritance?
On Tue, Apr 7, 2009 at 10:14 PM, <odd.moller@traveas.com> wrote:
Doesn't the actor library use case classes/objects to represent message types. How do I define a message type that is a specialization of another message type without case class inheritance?
You can roll your own extractors.
//Odd Möller
-----Original Message-----
From: David MacIver [mailto:david.maciver@gmail.com]
Sent: den 3 april 2009 16:27
To: scala
Subject: [scala] Do you use case class inheritance?
There has been some discussion recently about deprecating case class
inheritance (i.e. the ability to have case class Foo(...) and case
class Bar(...) extends Foo(...)). Nothing so far as a formal proposal
has been made, but I'd like to give it some thought (and certain
others are enthusiastically crying for it. Hi paul :-) ). This isn't
an sort of announcement, I'm just taking an opinion poll.
Reasons that have been given for deprecation:
- It doesn't appear to be that useful
- The current implementation is significantly buggy
- It has very strange interaction with equality
So it would be very appreciated if you could tell us if you use it and
could give us some specific examples of how and why.
Thanks,
David
--
Viktor Klang
Senior Systems Analyst
Sat, 2009-05-30, 06:47
#27
Re: Do you use case class inheritance?
David MacIver wrote:
> So it would be very appreciated if you could tell us if you use it and
> could give us some specific examples of how and why.
Sorry for raking up an old thread. I hope there is still some time for reconsideration.
When this was first brought up, I had immediately checked up all my code to see if I was using case class
inheritance. Turned out I wasn't and I went with the flow...
Until today. I wanted to model arithmetic expressions for a new (hobby) project. Something like:
abstract class Expression
case class PosInt(value:BigInt, size:Int) extends Expression
case class PosInt32(override value:BigInt) extends PosInt(value,32)
case class PosInt64(override value:BigInt) extends PosInt(value,64)
There could be many such variations involving other attributes like signed/unsigned, or other types like Float,
Rationals, etc.
I have not studied in detail all the alternatives to case class inheritance posted in this thread, but from a cursory
glance they all seem to involve much boilerplate.
How should I write my code to keep it as elegant as possible and still be forward-compatible?
Sat, 2009-05-30, 15:57
#28
Re: Re: Do you use case class inheritance?
This is pretty much the exact same stunt I was pulling (except my types were Strings, not Ints).
The standing recommendation is to make PosInt a trait or abstract class and have PosInt32 and
PosInt64 extend that. The alternative is to make PosInt a case class that holds an instance of the
other class.
Neither are particularly pretty.
~~ Robert.
Harshad wrote:
> David MacIver wrote:
>
>> So it would be very appreciated if you could tell us if you use it and
>> could give us some specific examples of how and why.
>
> Sorry for raking up an old thread. I hope there is still some time for reconsideration.
>
> When this was first brought up, I had immediately checked up all my code to see if I was using case class
> inheritance. Turned out I wasn't and I went with the flow...
>
> Until today. I wanted to model arithmetic expressions for a new (hobby) project. Something like:
>
> abstract class Expression
>
> case class PosInt(value:BigInt, size:Int) extends Expression
>
> case class PosInt32(override value:BigInt) extends PosInt(value,32)
> case class PosInt64(override value:BigInt) extends PosInt(value,64)
>
>
> There could be many such variations involving other attributes like signed/unsigned, or other types like Float,
> Rationals, etc.
>
> I have not studied in detail all the alternatives to case class inheritance posted in this thread, but from a cursory
> glance they all seem to involve much boilerplate.
>
> How should I write my code to keep it as elegant as possible and still be forward-compatible?
>
>
>
If so, I can't say that I have any specific immediate objections to it: my expected uses for case classes do all seem to be at the leaves. But I do find it a little unintuitive, coming from the viewpoint of more ordinary OO languages. It roughly says that case classes are automatically sealed, and I don't generally think of sealed as being quite so common. I worry a little about the implications for being able to add little tweaks to things down the line, but it's a pretty hypothetical concern: if practice has shown that people really aren't doing this, then it probably indicates that that's okay.
I do find myself curious about the equality interaction, though. Is the problem something to do with the automatic definitions of equals stepping on each other?
On Fri, Apr 3, 2009 at 10:27 AM, David MacIver <david.maciver@gmail.com> wrote: