--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
That said, I think once you get above a few things, you might as well create a case class anyways, since tuples become incomprehensible.
Hopefully the change to unshackle case classes solves most of the
problems, but I'm sypathetic to the cause of raising the this limit,
too.
I will finish it when I have the chance (realistically not until at least tomorrow night).
scala> import tuple._import tuple._scala> val t1 = Tuple(1,2,"a", "b")t1: tuple.Tuple[tuple.~[tuple.~[tuple.~[Int(1),Int(2)],String("a")],String("b")]] = tuple.Tuple@69b95c3ascala> t1._1res0: Int = 1scala> t1._2res1: Int = 2scala> t1._3res2: String = ascala> t1._4res3: String = bscala> val t2 = Tuple(List(1,2,3), "a", 2.3, false)t2: tuple.Tuple[tuple.~[tuple.~[tuple.~[List[Int],String("a")],Double(2.3)],Boolean(false)]] = tuple.Tuple@3b59a690scala> t2._1res4: List[Int] = List(1, 2, 3)scala> t2._2res5: String = ascala> t2._4res6: Boolean = falsescala> t2._0error: exception during macro expansion:java.lang.IllegalArgumentExceptionat tuple.TupleMacros$.get(Tuple.scala:115)scala> t2._100error: exception during macro expansion:java.lang.IllegalArgumentExceptionat tuple.TupleMacros$.get(Tuple.scala:114)scala> val letters = Tuple('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')letters: tuple.Tuple[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[Char('a'),Char('b')],Char('c')],Char('d')],Char('e')],Char('f')],Char('g')],Char('h')],Char('i')],Char('j')],Char('k')],Char('l')],Char('m')],Char('n')],Char('o')],Char('p')],Char('q')],Char('r')],Char('s')],Char('t')],Char('u')],Char('v')],Char('w')],Char('x')],Char('y')],Char('z')]] = tuple.Tuple@4303418scala> letters._1res9: Char = ascala> letters._5res10: Char = escala> letters._26res11: Char = zscala> 1 to 100 toList<console>:11: warning: postfix operator toList should be enabledby making the implicit value language.postfixOps visible.This can be achieved by adding the import clause 'import scala.language.postfixOps'or by setting the compiler option -language:postfixOps.See the Scala docs for value scala.language.postfixOps for a discussionwhy the feature should be explicitly enabled.1 to 100 toList^res12: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100)scala> val numbers = Tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100)numbers: tuple.Tuple[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[tuple.~[...,...],...(53)],Int(54)],Int(55)],Int(56)],Int(57)],Int(58)],Int(59)],Int(60)],Int(61)],Int(62)],Int(63)],Int(64)],Int(65)],Int(66)],Int(67)],Int(68)],Int(69)],Int(70)],Int(71)],Int(72)],Int(73)],Int(74)],Int(75)],Int(76)],Int(77)],Int(78)],Int(79)],Int(80)],Int(81)],Int(82)],Int(83)],Int(84)],Int(85)],Int(86)],Int(87)],Int(88)],Int(89)],Int(90)],Int(91)],Int(92)],Int(93)],Int(94...scala> numbers._100res13: Int = 100
A few implementation notes:
- If you call c.abort rather than throwing an exception from the macro, you can have a regular error message instead of "error: exception during macro expansion:"
- Array[Unit] can be represented with an Int (at worst.)
- Declaring everything as vals up front means you have a high minimum memory consumption. There should be an abstract version which declares defs, which makes it possible to have lower memory consumption; in fact it would make possible moving everything into the code segment if one didn't mind a new anonymous class for every different tuple...- Another way to pay for something in the ballpark of what you use would be a single field which holds an Array[Object], with that Array holding 1-9 arrays which in turn hold the actual values of the tuple.
scala> Array(1,2,3).asInstanceOf[Array[AnyRef]]
java.lang.ClassCastException: [I cannot be cast to [Ljava.lang.Object;
You and Paul are right. It doesn't need to be an Array[AnyRef] just an AnyRef. I'm silly. It's still small time vs small space though, right? Am I overacting to be worried about the time of an extra Array deindexing being between the user and their tupled data? It seems like some JVM magic would improve repeated access to the same array...
Actually, didn't my experiment prove that youcould not lift an Array[Int] into the singleArray[AnyRef] field (hey, it was good forsomething!).
I understand arguments that you shouldn't design your classes to have that many fields, but this is the real world and the real world needs a general purpose language. Sometimes we are dealing with data transfer objects to legacy code that we don't control. And sometimes those data transfer objects have more than 22 fields. Sure this allows people to create classes with too many fields, but it also allows people to express classes with too many fields in the simplest possible way. My impression of Scala's design goals is that it was more important to be a powerful language than an nanny language.
Since the Tuple classes are static, we have to set the limit somewhere. 22 is simply too low. 100 is a nice round number that should solve the vast majority of the problems.
> What is the use case where you need 60 items, but not 100, and you can't nest tuples, and you can't use case classes?
Sounds like you are describing something different, as that is not the use case I described. Like the tuple limitation, the case class limitation is also 22 as of Scala 10.0.1, so my original use case applies. Are you suggesting we should have a different limitation for case classes than we do for tuples? That might make functions like .tupled behave in surprising ways, for example if you did something like: (MyCaseClass.apply _).tupled
> What is the use case where you need 60 items, but not 100, and you can't nest tuples, and you can't use case classes?
Sounds like you are describing something different, as that is not the use case I described. Like the tuple limitation, the case class limitation is also 22 as of Scala 10.0.1, so my original use case applies. Are you suggesting we should have a different limitation for case classes than we do for tuples? That might make functions like .tupled behave in surprising ways, for example if you did something like: (MyCaseClass.apply _).tupled
I was hoping for an implementation that would shield the programmer from limitations not related to their application's need.
No matter what the actual limit is, someone can always argue why not one more or why not one less (raould, I concede that 128 is more of a round number than 100 in base 2).
From the conversation between Chris Hodapp and Paul Phillips, it looks like there may a way to not have a limitation at all, so I am hopeful that a solution along these lines will prove practical.
Regarding 22 being too high, I am not convinced it is a good idea for a general purpose programming language to make that decision on the behalf of every possible application that might ever be written in that language. I would rather leave the domain modelling decisions to the individual application developers, and have the programming language take a hands off approach, focusing on being useful while staying out of the way.