John M. Dlugosz wrote:
> TSa wrote:
> > Jon Lang wrote:
> > > I'm having some difficulty understanding the business with £. I
> > > _think_ that you're saying that £ sort of acts as a prefix operator
> > > that changes the meaning of the type with which it is associated; and
> > > the only time that a change in meaning occurs is if the type in
> > > question makes use of ::?CLASS or a generic parameter.
> >
> > The difference seems to be the two definitions of bendit
> >
> > sub bendit (IBend ::T $p -->T)
> > {
> > IBend $q = get_something;
> > my T $result= $p.merge($q);
> > return $result;
> > }
> >
> > sub bendit (£ IBend ::T $p -->T)
> > {
> > T $q = get_something;
> > my T $result= $p.merge($q);
> > return $result;
> > }
> >
> > The interesting thing that is actually left out is the return type
> > of get_something. I think in both cases it does the IBend role but
> > in the second definition it is checked against the actual type T
> > which is Thingie if called with a Thingie for $p. So the advantage
> > of this code is that the compiler can statically complain about the
> > return type of get_something. But I fail to see why we need £ in
> > the signature to get that.
>
> In the top example, merge has to be declared with invariant parameter
> types, so the actual type passed "isa" IBend. That means merge's parameter
> is IBend. If get_something returned the proper type, it would be lost.
>
> In the lower example, the merge parameter is allowed to be covariant. The
> actual type is not a subtype of IBend. The parameter to merge is checked to
> make sure it is also T. The £ means "use the higher-order £ike-this" rather
> than "isa" substitutability.
>
> The issue is how to give covariant parameter types =and= minimal type
> bounds for T at the same time.
Perhaps it would be clearer if you could illustrate the difference between
sub bendit (£ IBend ::T $p -->T)
{
T $q = get_something;
my T $result= $p.merge($q);
return $result;
}
and
sub bendit (IBend ::T $p -->T)
{
T $q = get_something;
my T $result= $p.merge($q);
return $result;
}
Or perhaps it would be clearer if I actually understood what
"covariant" means.
> > The use of £ in
> >
> > sub foo (£ pointlike ::PointType $p1, PointType $p2 --> PointType)
> >
> > is that of *structural* subtyping. Here FoxPoint is found to be
> > pointlike. In that I would propose again to take the 'like' operator
> > from JavaScript 2. Doing that the role should be better named Point
> > and foo reads:
> >
> > sub foo (like Point ::PointType $p1, PointType $p2 --> PointType)
> >
> > This is very useful to interface between typed and untyped code.
> > With rthe 'like' the role Point has to be *nominally* available
> > in the argument. There's no problem with 'like'-types beeing more
> > expensive than a nominal check.
>
> Yes, with Point would work for matching as well as pointlike. When the
> covariant parameter type destroys the "isa" relationship between Point and
> Point3D, "£ Point" will still indicate conformance to the "like" rules.
>
> I like "like" as the ASCII synonym to £, but didn't want to get into that
> in the whitepaper. I wanted to concentrate on the need for a higher-order
> type check, not worry about how to modify the grammar.
OK; how does "higher-order type checks" vs. "isa relationships" differ
from "duck typing" vs. "nominal typing"?
--
Jonathan "Dataweaver" Lang