Named Tuples don't have a built-in Ordering?

It seems as if Named- Tuples, unlike regular tuples, don’t have a built-in Ordering? :worried:

val ordTuple = summon[Ordering[(String, Int)]]

//wont compile
val ordNamed = summon[Ordering[(name: String, num: Int)]]

scastie

The built-in tuple ordering of the std library doesn’t seem to work once names are added to the fields of a tuple.

I’m guessing this may be related to the perplexing decision to make named tuples a superclass of their unnamed version…

3 Likes

Thanks chatgpt :smiley:

//> using scala 3.7

import scala.NamedTuple.NamedTuple

given orderingForNamedTuple[N <: Tuple, V <: Tuple](using ord: Ordering[V]): Ordering[NamedTuple[N, V]] with
 def compare(x: NamedTuple[N, V], y: NamedTuple[N, V]): Int =
   ord.compare(x.toTuple, y.toTuple)

type Person = (name: String, age: Int)

val so = summon[Ordering[Person]]

//seeing is believing
val people: List[Person] = List(
  (name = "Charlie", age = 35),
  (name = "Alice", age = 30),
  (name = "Alice", age = 29),
  (name = "Bob", age = 25),
)
val sortedPeople = people.sorted
@main def main = println(s"$sortedPeople")
1 Like

Haha :joy:, chatGPT is outsmarting our community. Although this is not super complex, i think it is still pretty amazing chatGTP produced this code. Can you share the prompt and version you used with us?

IMO Named Tuples should not have been promoted from experimental to stable without this being added to the standard library.

The fact I’m reporting this now suggests to me that they haven’t seen much practical uptake yet, since the need for tuple Orderings comes up pretty quickly in practical applications.

Why do favoured features get rushed to stable, while others (eg Generic Number Literals) languish in purgatory for years? I admit, a rhetorical question; I’ve already formed a view on why..

I find AIs handle focused problems like this very well. IME, long-running work in big codebases is where they fall down.

Prompt to chatgpt 4.1 with Web Search option enabled:
"Scala 3.7 introduced a new feature Named Tuples.

Named Tuples do not have a default Ordering provided by the standard library, unlike regular tuples, presumed due to them being treated as supertypes of the equivalent unnamed tuple.

Investigate whether it is possible to define a generic given definition that would enable lexigraphic ordering for any/all Named Tuples of a given arity."

Its answer needed a teeny bit of fixup because it thought the opaque type was defined at scala.NamedTuple, not scala.NamedTuple.NamedTuple.

3 Likes

It’s just that usually they just need a person to drive it through SIP and if there is no interest it’s unlikely there will a person like that. If you feel that this is a feature that should get into the language, we can discuss it more on the next Scala Core meeting to see if we can push it forward and what is blocking it.

For named tuples there was plenty of interested parties and a lot of discussions about it. It might still contain some issues, but in reality to get any real usage feedback you will need to have it as stable.

IMO Named Tuples should not have been promoted from experimental to stable without this being added to the standard library.

Sure, but if no one reported it and it was missed by the implementer this in reality is just a bug.

See Add an Ordering given instance for named tuples by odersky · Pull Request #23379 · scala/scala3 · GitHub for the pull request to add this feature. It was an oversight that it was missing. Ideally this would have been detected and fixed when named tuples were still experimental. But the fact of the matter is that hardly anyone does serious work with a an experimental feature, so it’s easy for these things to be overlooked initially. Furtunatly, in this case, it’s equally easy to fix.

4 Likes

Thanks for moving quickly to address this need in the standard library, it’s certainly preferable to users hand-rolling their own Orderings. :folded_hands:

When I saw the original question, I was not aware that @benhutchison was asking for implementation help (I thought this was just about the absence from the standard library).

Otherwise, my answer would have been the following which imho outsmarts the ChatGP solution:

given orderingForNamedTuple[N <: Tuple, V <: Tuple: Ordering]: Ordering[NamedTuple[N, V]] =
  Ordering.by(_.toTuple)
4 Likes