[swift-evolution] Revisiting SE-0110
retired.hunter.djura at gmail.com
Fri Jun 23 10:15:40 CDT 2017
Hi, thanks for the answer.
>> …by showing code that’s marginally different from each other, like one more nesting of parentheses, or one less label for a parameter. It seems to me that distinctions like these are just important at the compiler level, but not particularly useful from an usability standpoint.
> It is your opinion that these distinctions are not “useful from a usability standpoint”. My opinion, for example, differs in that I think these distinctions in the structure of the types is very important, even if the types “information content” is the same. Structure also conveys information (and intent).
What I meant by "marginally different" is a distinction like ((A,B)) != (A,B) which seems to me completely meaningless from a user perspective.
I'm not sure how completely isomorphic structures (represented by tuples) could convey different information and intent. For example:
let x: (coordinates: (Double,Double), altitude: Double) == ((A,B),C)
let y: (latitude: Double, longitude: Double, altitude: Double) == (A,B,C)
In this case what conveys information are the arguments labels, not the structure by itself. And if I really need to be specific about the information that I want to represent, I should probably create a new actual type, for example a "Position" struct, such that the example becomes:
let z: Position == (A)
That's different. What I'm referring to are just tuples in general. A function that expects a "Position" should get a "Position", but if a function just expects 3 "Double" I don't see a reason why we shouldn't be able to call it with both "x" and "y": of course I could do something nonsensical in this context, like return a sum of the 3, but here the problem is "not using types that are specific enough", or simply "calling the wrong function" (like "square" instead of "squareRoot").
>> The point is that, the following type couples are completely isomorphic to each other (meaning that they are, for all means, equivalent) and a smart type system could in theory consider them as the same thing:
>> (A) == ((A))
>> (A) == (((A)))
>> (A) == (A,())
>> (A) == ((),A,())
>> (A,B) == ((A,B))
>> (A,B) == (((A,B)))
>> (A,B) == (A,B,())
>> (A,B) == ((),A,B,())
>> (A,B) == ((),(A,B),())
> To my mind, the examples should not compare equal (in fact, they shouldn’t even be comparable by default because for those distinct types involved that seems like a non-sensical question to me).
> I might agree that a type system *could* consider these the same, but I don’t think it should. For example, in the context of generic programming, the structure of types (especially in degenerate cases such as e.g. empty tuples) should strictly match what is expected; calling a function that expects two tuples is not the same as calling that function with one tuple and so on. The same goes for nesting tuples.
Could you please elaborate on this, providing some arguments for the statement "in the context of generic programming, the structure of types should strictly match what is expected"?
More information about the swift-evolution