Hi,
I have overlooked that "Issue 19146: Specify List::reject and other iterations." introduces two specializations for List operations:
excludesAll
List(T)::excludesAll(c2 : Collection(T)) : Boolean
List(T)::excludesAll(c2 : List(T)) : Boolean
includesAll
List(T)::includesAll(c2 : Collection(T)) : Boolean
List(T)::includesAll(c2 : List(T)) : Boolean
removeAll
List(T)::removeAll(elements : Collection(T)) : Void
List(T)::removeAll(elements : List(T)) : Void
Little incoherence is that at the same time some other operations don't have such additions
product
List(T)::product(c2: Collection(T2)) : Set(Tuple(first: T, second: T2))
union
List(T)::union (s : List(T)) : List(T)
And the main question is why specializations for every operation which works with collection were introduced.
User will always be forced to define two counterparts in every simple case. For example:
helper Collection(Real)::meanValue() : Real { ... }
helper List(Real)::meanValue() : Real { ... }
or
helper meanValue(in c: Collection(Real)) : Real { ... }
helper meanValue(in c : List(Real)) : Real { ... }
Besides, let's imagine that QVT 1.x will introduce, say, mutable queue or bidirectional map or something similar. Follows List type experience this new type also won't inherit Collection type. Then the new operation which accepts a certain type will appear in the existing types, like:
List(T)::excludesAll(c2 : Queue(T)) : Boolean
Of course dedicated root like MutableCollection (which all other mutable collections will inherit) might be introduced but that is also problematic design.
Yet another point is that operations 'excludesAll()/includesAll()/product()' in Collection-rooted types don't accept List instance without explicit conversion. That is also awkward.
Last point is that this issue introduces 'asList' operation for Collection type which implicitly refers that List might inherit Collection type:
Collection(T)::asList(T) : List(T)
Regards,
Sergey.