Hi,
TSa (Thomas Sandlaß) wrote:
There is no formally defined subtype relation or rules for subsumption.
A type is called narrower without details what that means.
A is a subtype of B if A ~~ B, where ~~ is the smart-match
operator..It's up to the type object on the RHS how it responds to this.
Type objects of classes take that to mean that the thing on the LHS
should inherit from it, roles take it to mean that the thing on the LHS
does the role, etc.
And the odering in dispatch is not a type lattice as in Cecil but a topological ordering. Again I've no clue what that means.
Take all of the candidates. Build a DAG where there's an arrow from a
narrower to a wider candidate. Do a topological sort on the DAG, and
you've got the ordering. Note that narrowness is a stronger condition
than subtype; if A ~~ B and B ~~ A then you have two types that are
tied. S12 describes how this extends from individual parameter types to
give a way to determine if two signatures are tied or if one is narrower
than the other.
It is possible for one role to do another as in
role A does B {...}
and all objects that do A are also B doers. So one could infer that we
have A <: B. But note that this subtype relation is not enforced in the
body of the role or in the class it is composed into.
Can you clarify what you mean by "not enforced"? I think I'm missing
something, since if you have:
role B {
method m() { ... }
}
role A does B { }
class C does A { }
Then you get a composition time error (or should, by spec) because C
does not implement a method "m". (Current Rakudo gets this wrong, but
it's a fault of the implementation, not the spec).
The spec says nothing about class inheritance and type narrowness.
Despite both terms showing up multiple times in S12?
Parametric roles are covariant on their type parameter irrespective of its use.
E.g. you can declare a read/write attribute of that type.
While parametric roles do fill the niche of parametric types, you can
also parametrize them with values - STD (the standard grammar) takes
advantage of this. In many ways, a parametric role definition works like
a kind of role factory; an implementation falls quite naturally out of
multiple dispatch and closure semantics. Seeing parametric roles as
being solely for parametric polymorphism is casting their role in Perl 6
a little too narrowly though.
I agree that the information that is available on the Perl 6 type system
is scattered across the synopses, and in some places probably needs a
look at the spectests, and probably has untested edge-cases too. Maybe
it'd be good to try and collect it together more at some point, so
there's a single source to point people at.
Hope this helps,
Jonathan