I agree that Nothing
, overloading, and implicits are existing cases of “compile-time” LSP violation. But I argue that they indeed fit the bill for “endless stream of edge cases”! We were just discussing two different edge cases around Nothing
inference a few days ago, and I think most would agree that the existence of overloading makes everything more complicated, with tons of features that don’t work well together with it (default values, target typing, …). I don’t think adding more such compile-time LSP violations is desirable if there are easy alternatives available.
I think there is enough confusion in this thread to suggest that despite the technical validity of unnamed <: named
, it’s pretty counterintuitive to a majority of users. There is certainly a mental model where unnamed <: named
makes sense, but it seems that it is simply not the model that everyone already has in their heads
Given unnamed <: named
seems empirically confusing, assuming we don’t want to go with python-ish named <: unnamed
, I like @soronpo’s idea of just having all tuples be named, with unnamed tuples just being named tuples with the names "_1"
, "_2"
, etc.:
-
That would both keep things simple since there’s only one real implementation of named tuples with a thin desugaring for unnamed tuples, but also keep the two types distinct so
named =!= unnamed
. -
We can add conversions in either direction, between
named -> unnamed
,unnamed -> named
, and even between differentnamed -> named
tuples. Given that they are all the same runtime values, these conversions would be zero runtime cost, and IMO having people explicitly opt-in to convert between them is a very good idea for reasons @Ichoran and others have already brought up. -
It opens up the possibility of mixed named/unnamed tuples for free, since in the end they’re all just named tuples with some of the names being
"_n"
, there’s no additional complexity to worry about: you can append them, mix them in any order, and it should “just work”