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