Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Case classes should inherit from ProductN #1799

Open
scabug opened this issue Mar 16, 2009 · 15 comments
Open

Case classes should inherit from ProductN #1799

scabug opened this issue Mar 16, 2009 · 15 comments

Comments

@scabug
Copy link

scabug commented Mar 16, 2009

Currently, only TupleN classes inherit from ProductN.

Case classes should also inherit from ProductN, where N is the value of the productArity of the case class.

@scabug
Copy link
Author

scabug commented Mar 16, 2009

Imported From: https://issues.scala-lang.org/browse/SI-1799?orig=1
Reporter: Rafael de F. Ferreira (rafaeldff)

@scabug
Copy link
Author

scabug commented Mar 16, 2009

@paulp said:
I don't know the reasoning, but they used to and were changed not to about two years ago (see r9542.) So barring some invalidation of the original rationale, you can probably figure on this being wontfix.

@scabug
Copy link
Author

scabug commented Mar 16, 2009

@DRMacIver said:
Basically, it's inconsistent with case class inheritance. Suppose I have

  case class Foo(foo : String, bar : Int);
  case class Baz(baz : Int, bloop : String) extends Foo(bloop, baz);

This would have to extend both Product2[String, Int] and Product2[Int, String], which isn't allowed.

@scabug
Copy link
Author

scabug commented Mar 16, 2009

Rafael de F. Ferreira (rafaeldff) said:
Ok, I understand the rationale. Case class inheritance really seems to be a minefield (I'm sorry I asked for it back on the pre-trac days :).

Anyway, for my use case I just wanted to have the arity of the case class encoded in the type system. I don't need to know the actual types of the arguments. I was hoping to do something like:

abstract class Arity
abstract class N1 extends Arity
abstract class N2 extends Arity
abstract class N3 extends Arity
//...

class FiniteProduct[A <% Arity](val p:Product)

implicit def productArity1(p:Product1[_]) = new FiniteProduct[N1](p)
implicit def productArity2(p:Product2[_,_]) = new FiniteProduct[N2](p)
implicit def productArity3(p:Product3[_,_,_]) = new FiniteProduct[N3](p)
//...
//Note that the implicit defs above forget the argument types

def table[P <% FiniteProduct[_]](rows:List[P]) = Do something knowing that all products in rows have the same arity

Should I take this to the mailing lists or open another ticket (or forget about this kind of guarantee and sulk)?

@scabug
Copy link
Author

scabug commented Mar 16, 2009

@DRMacIver said:
Yes, it is a minefield. I'm sorry you asked for it too. ;-)

One thing I've found useful for dealing with case classes with specific sizes is to parameterise by their unapply methods: The companion object has a generated unapply method which returns an Option[ProductN[T1, ..., TN]].

@scabug
Copy link
Author

scabug commented Jul 21, 2011

@SethTisue said:
at http://groups.google.com/group/scala-debate/msg/3571378837734785 Martin says "we should do it" now that case/case inheritance is gone

@scabug
Copy link
Author

scabug commented Jul 21, 2011

Commit Message Bot (anonymous) said:
(extempore in r25336) As per discussion documented in #1799, brought back the ProductN
traits and synthesized them into case classes. It's -Xexperimental for
now because there may be minor implications for existing code which
should be discussed. And also because I snuck in another "improvement"
but it's probably too dangerous to be touching productIterator directly
and it should go into something else.

scala> case class Bippy(x: Int, y: Int)
defined class Bippy

scala> Bippy(5, 10).productIterator
res0: Iterator[Int] = non-empty iterator
^^^----- as opposed to Iterator[Any]

There is an even better idea available than lubbing the case class field
types: it starts with "H" and ends with "List"...

Review by oderksy.

@scabug
Copy link
Author

scabug commented Sep 26, 2011

Commit Message Bot (anonymous) said:
(extempore in r25725) ProductN, and method synthesis toolbox.

  • Finished giving case classes a ProductN parent, and flipped it on.
    The "finish" part involved not breaking existing code where case classes
    manually extend the appropriate ProductN. (Like, Tuple 1-22.)

  • Generalized most of SyntheticMethods to ease method creation
    and class manipulation in general.

  • Fixed bugs related to the above, like the fact that this used to
    be a compile error:

    scala> case class Foo() extends Serializable
    :28: error: trait Serializable is inherited twice
    case class Foo() extends Serializable
    ^
    It feels like there's a better way to eliminate the duplicate parents,
    but after spending a lot of time chasing my tail in that peril-fraught
    zone between namer and typer, I don't see an easy path to improve on
    it. Closes Case classes should inherit from ProductN #1799. For that modification to Typers, review by odersky.

@scabug
Copy link
Author

scabug commented Jun 23, 2012

@paulp said:
Reverted half a year ago in b7395e9f50 but failed to reopen the ticket.

@scabug
Copy link
Author

scabug commented Jun 25, 2012

@adriaanm said:
Unassigned strictly because we don't have the manpower right now. Labelled grand-challenge so ambitious contributors know where to look.

@scabug
Copy link
Author

scabug commented Sep 21, 2012

@ijuma said:
Hi, what is the status of this. Too late for Scala 2.10, I guess?

@scabug
Copy link
Author

scabug commented Sep 21, 2012

@gkossakowski said:
Definitively too late, sorry. These kind of changes can land in master, though.

@scabug
Copy link
Author

scabug commented Apr 22, 2013

@Blaisorblade said:
Wow, b7395e9f50 is really informative on the problems. But I guess that figuring out the problem will be easy compared to the actual fix, so it's OK.

Reverted ProductN parent for case classes.

Looks like we will need blood, toil, tears, and sweat. No review.

@scabug
Copy link
Author

scabug commented Apr 22, 2013

@paulp said:
The good news is that nobody has figured out the problem. But some of the relevant tickets are #5119, #5082, #5084. Sorry about the uninformative message. The issue is cycles between classes and their companions; there is already a lot of tension there, and ProductN pushed it over the limit between the companion object apply method, the type parameters to the ProductN parent, the synthesized copy method, the fact that the class often refers to aliases which reside in the companion object, and whatever else there is.

@scabug
Copy link
Author

scabug commented Apr 22, 2013

@retronym said:
I'm hopeful that #5082 untied the knot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants