I read these discussions, and I now have a concern about it.
In theory, we can think about what happens if reverse generics was applied in argument type considering the next example.
// Reverse generics in result
func callee<opaque T: FixedWidthInteger>() -> T { /* ... */ }
// Reverse generics in argument
// The actual type of `T` is `Int64`, but from the caller it seems to be opaque
func callee<opaque T: FixedWidthInteger = Int64>(_ value: T) { /* ... */ }
<opaque T: FixedWidthInteger = Int64>
is my instant syntax, which says the actual type of T
is Int64
, but tells user only that the T
conforms to FixedWidthInteger
.
It is easy to reject using this, but this has possibility to be used.
Just for example, FixedWidthInteger
has constraint to have static let max: Self
. Then we can use this function by using this.
// Call the function with leading dot syntax
callee(.max)
Although caller cannot know the actual type of the argument, constraint ensures that the type has static value max
. Therefore, caller can use .max
.
But caller cannot use this with explicitly written type, because caller doesn't know this is correct.
// Error, because caller cannot know the actual type of argument is Int64 or not.
callee(Int64.max)
By considering it, we can have clear explanation of generics and reverse generics.
Who decide actual type \ position | Argument Type | Result Type |
---|---|---|
Caller | Generic Argument | Generic Result |
Callee | Reverse Generic Argument | Reverse Generic Result |
Without it, the cell of "Argument Type/Callee" got empty.
I don't argue reverse generic argument is highly useful, but in some cases it would be useful, for example, the situation you don't want to make it visible what the actual argument type is. If you are using module private types for the argument, you can use reverse generic argument so that you don't have to make the type public.
Again, I don't think such situations are common and I don't feel it important to implement this feature, but we have to admit that such feature can be considered.
However, at least, the next syntax should be reconsidered, because potentially it excludes the opportunity to use reverse generic argument with some
keyword. This is quote from here
// But it also could be this:
func makeCollection<^T: Numeric = Int64, ^C: Collection>(with number: T) -> C {
return [number]
}
How do you think about these things? I couldn't find any previous refers in the forum about this. I'm sorry if this discussion has been already held. Thank you!