It was pointed out at the core meeting yesterday that the SIP is already “accepted for shipping” (Process Specification | Scala Documentation) by the committee. So at this point it’s about testing for bugs, the design is done.
The SIP communication was lacking lately: meeting summaries were not published, pages (List of All SIPs | Scala Documentation) and PRs (https://github.com/scala/improvement-proposals/pull/72#event-15618867923) were not updated. So it was not possible for people outside the committee to know about the status. We need to improve this situation. This ties in to the upcoming “preview” stage for language features in the compiler (Introduce concept of Preview Features as a feature stabilization period · Issue #22044 · scala/scala3 · GitHub).
I guess in practice it doesn’t matter much whether a conversion is by subtyping or through an implicit conversion. The toTuple
implicit conversion is enabled by default anyway, so one can go back and forth between named and unnamed.
scala> val p = (x = 1, y = 2)
val p: (x : Int, y : Int) = (1,2)
scala> p.x
val res1: Int = 1
scala> ((p: (Int, Int)): (y: Int, x: Int)).x
val res2: Int = 2
IIUC, the argument for unnamed <: named
as implemented currently is the analogy to argument lists. If we had first class argument lists, we would certinaly allow val args = ("bob", 72); foo@args
, the names are inferred. This makes sense to me.
But it bothers me from a “types == sets of values” perspective. (String, Int)
is any String
/ Int
pair, or alternatively the set of unnamed String
/ Int
pairs. The type (name: String, age: Int)
is pairs with name
and age
fields.
There’s also some inconsisntency in pattern matching, a named tuple matches an unnamed pattern, not the other way around. But that won’t change, no matter if there’s subtyping or not.
scala> val p = (1, 2)
val p: (Int, Int) = (1,2)
scala> val n: (x: Int, y: Int) = p
val n: (x : Int, y : Int) = (1,2)
scala> p match { case (x = 1, y = 2) => true }
-- Error: ----------------------------------------------------------------------
1 |p match { case (x = 1, y = 2) => true }
| ^^^^^
| No element named `x` is defined in selector type (Int, Int)
-- Error: ----------------------------------------------------------------------
1 |p match { case (x = 1, y = 2) => true }
| ^^^^^
| No element named `y` is defined in selector type (Int, Int)
2 errors found
scala> n match { case (1, 2) => true }
val res0: Boolean = true