For those of us who don't think in terms compatible with Type Theory, the suggestion is essentially this: instead of going from general to specific, go from specific to general. E.g., for a given relationship ::A.does(::B) or ::A.isa(::B), include a way to start with ::B and then to define ::A in terms of it.
Some thoughts: Perl 6 currently defines four approaches to code reuse: inheritance from a class ("...is class") composition of a role ("...does role") delegation to an attribute ("attribute handles methods") subtypes ("...where condition") The first three approaches share the common approach of adding to what the object can do; the fourth approach adds restrictions on the values that the object may have. Reverse-engineering these would involve removing capabilities (in the first three cases) or removing restrictions (in the fourth case). In any case, one should never add anything while going from specific to general. -- Looking at the inheritance/composition/delegation triad for a moment: I suppose that a case could be made to that subtyping could be used to remove capabilities from an object (e.g., "... where !.can(&method)" to remove one method from it); but doing so is syntactically clumsy and semantically suspect (if "::B.can(&foo)" and "::B where !.can(&foo)" is equivalent to ".does(::B) and !.can(&foo)", then the latter ought always be false). I don't know how (or even if) I'd handle reverse-inheritance or reverse-delegation; but for reverse-composition (or decomposition, if you will), I'd handle it either by using set operations to define a subset of the role's methods to decompose into a more general role (as I've talked about earlier), or I'd define the more general role in terms of what methods it _doesn't_ have: role B { method foo() { ... } method bar() { ... } } my subset A of B except <foo> (where the except clause tells you which methods to remove when constructing A) would produce the same end result as: role A { method bar() { ... } } role B does A { method foo() { ... } } Personally, I feel that the set operations approach is the more flexible and user-friendly one, and it makes the one outlined here redundant. The one capability that both approaches miss is the ability to have the more general class redefine the behavior of existing methods. -- In terms of the subtypes, the reverse process would be to somehow remove restrictions from the object. This could (conceptually) be done in one of two ways: granting exemptions to the restrictions (in effect, adding conditions that, if met, permit the value despite existing restrictions), or specifying existing restrictions to be removed. I'm not sure how (or if) I'd implement the latter. In effect, an exemption clause would follow the rule of "if you pass this test, you're OK; if not, we'll pass you up the chain for further scrutiny" - as opposed to where clauses, which say "if you fail this test, you're out; if not, we'll pass you up the chain for further scrutiny". That is, "where" clauses should tack a new condition onto the start of the overall test by means of a short-circuiting "and"; exemptions would tack a new condition onto the start by means of a short-circuiting "or". Since the "default" test (prior to the first restriction or exemption) is "true", this would make "bare" exemptions useless. That said, I'm not sure what keyword would be the most user-friendly for defining exemptions. -- Jonathan "Dataweaver" Lang