Re: class interface of roles
Larry Wall schreef: > I suspect ordered composition is going to be rare enough that we can > simply dehuffmanize it to > > $x does A; > $x does B; > $x does C; Maybe use a list-like notation? $x does (A, B, C,) ; $x does (A ; B ; C) ; $x does [A, B, C,] ; $x does [A ; B ; C] ; -- Groet, Ruud
Re: class interface of roles
HaloO, Larry Wall wrote: You've got it inside out. Unordered is just "does A | B | C" or some such, the | there really being coerced to a set construction, not a junction. In fact, & would work just as well. I only used | because it's more readable. Autocoercion of junctions to sets is, of course, conjectural. You really have does set(A,B,C) I would like "does A & B & C" mean the intersection type of A, B and C. That is a supertype of all three roles. In addition we might need negation to get what Jonathan Lang envisoned for the Complex type that does Num & !Comparable. IOW, I'm opting for a role combination syntax by means of logical operators that operate on the intension set of the involved roles. Could we get that? BTW, the synopsis reserve Foo[Bar] and Foo{Bar} for type theoretical operations. The former is used for parametric types. How is the latter used? Regards, TSa. --
Re: class interface of roles
HaloO TSa wrote: I would like "does A & B & C" mean the intersection type of A, B and C. That is a supertype of all three roles. In addition we might need negation to get what Jonathan Lang envisoned for the Complex type that does Num & !Comparable. IOW, I'm opting for a role combination syntax by means of logical operators that operate on the intension set of the involved roles. Could we get that? And while we're at it, could we also introduce the subtype operator <: and perhaps >: as the supertype operator? This would come in handy for expressing type constraints in does clauses. --
Re: class interface of roles
Ruud H.G. van Tol wrote: Larry Wall schreef: > I suspect ordered composition is going to be rare enough that we can > simply dehuffmanize it to > > $x does A; > $x does B; > $x does C; Maybe use a list-like notation? What happens when you try to mix ordered and unordered composition? Under the current syntax, to compose roles A and B together, and then C once A and B are done, one could say: $x does A | B does C; Under my original suggestion, this would be: $x does A does B & does C; Under Larry's suggestion, this would be: $x does A does B; $x does C; How would you handle it? If ordered composition is something that can be done in a single statement, then unordered composition syntax needs to be nestable inside ordered composition syntax - and since the goal here is to have "does A does B" always represent unordered composition, that's what would need to nest. -- Despite having suggested a possible syntax for ordered composition, I think that Larry is right in claiming that a sequence of separate composition statements is more than sufficient in both syntax and clarity to handle those cases where ordered composition is needed. -- Jonathan "Dataweaver" Lang
Re: class interface of roles
TSa wrote: And while we're at it, could we also introduce the subtype operator <: and perhaps >: as the supertype operator? This would come in handy for expressing type constraints in does clauses. Isn't one of those called ".does()"? -- Jonathan "Dataweaver" Lang
Re: class interface of roles
HaloO, Hmm, no one seems to read the article! There actually is another class GenLocSquare that combines GenSquare and GenPointMixin. With that we get a modified version of my code as follows: role GenEqual { method equal( : GenEqual $ --> Bool ) {...} } role GenPointMixin { has Int $.x; has Int $.y; method equal( ::?CLASS GenEqual $self: ::?CLASS $p --> Bool ) This additional GenEqual type bound on the self type is all that is needed to get the superclass interface as described in the article. { return super.equal(p) and # <-- handwave return call($p) and # normal superclass call, but I still # think that super.equal reads better. self.x == $p.x and self.y == $p.y; } } class GenSquare does GenEqual does GenPointMixin class GenSquare does GenEqual { has Int $.side; method equal ( : ::?CLASS $p --> Bool ) { return self.side == $p.side; } } And finally the combined class class GenLocSquare is GenSquare does GenPointMixin {} I initially dropped it because I thought that roles can see the pre-composed class somehow. But as Jonathan explained they don't---at least not in compile-time class composition. And for runtime composition you get the empty class for free! Regards, TSa. --
Re: class interface of roles
"Jonathan Lang" schreef: > role R does A does B does C { ... } # unordered composition > $x does A does B does C; # ordered composition > $y does A | B | C; # unordered composition > > I'd like to see it done something like: > > role R does A does B does C { ... } # unordered composition > $x does A & does B & does C; # ordered composition > $y does A does B does C; # unordered composition And I was on the line of: role R does A | B | C { ... } # unordered composition $x does ( A, B, C ) ; # ordered composition $y does A | B | C ; # unordered composition but I would like early and late binding to be explicit. Maybe the coder will use () around the run-time ones. -- Affijn, Ruud "Gewoon is een tijger."
Re: class interface of roles
Larry Wall wrote: Though actually, now that I think about it, the cascaded notation in S12 is illegal according to S03, since "does" is classified as non-chaining, which implies non-associative. Wait a minute. Isn't "chaining" specifically referring to the idea that "A op B op C" implicitly becomes something like "A op B && B op C"? That would seem to be unrelated to the concept of associativity, other than the fact that you can't have chaining without associativity. Why would "does" have to be chaining in order to be associative? -- Jonathan "Dataweaver" Lang
set operations for roles
In "class interface of roles", Dr.Ruud wrote: And I was on the line of: role R does A | B | C { ... } # unordered composition $x does ( A, B, C ) ; # ordered composition $y does A | B | C ; # unordered composition but I would like early and late binding to be explicit. Maybe the coder will use () around the run-time ones. Note that compile-time "is" and "does" declarations can be applied before the curly braces or inside them; if applied inside, each one is treated as a separate statement: class Foo is A is B does R { ... } class Foo { is A; is B; does R; ... } Unless you put a restriction that the body can have no more than one "does" statement, I would expect the symmetry between these two cases to be maintained: role R { does A; does B; ... } role R does A does B { ... } And since one of the basic principles of multiple role composition is that ordered composition should not be encouraged, this syntax should represent unordered composition if it remains at all (and I think it should). And if unordered composition can be done this way at compile-time, it ought to be doable in an analogous way at runtime as well. That said, TIMTOWTDI. I could see "does A | B | C" being used as a valid alternative to "does A does B does C" on the theory that '|' is being used like a union operator and 'A', 'B', and 'C' can be viewed as sets of methods. One thing which should be considered when deciding whether or not to permit this sort of syntax is that the availability of a union-ish operator implies the availability of other set-like operators, such as "does A & B" or "does A - B". The problem with these latter definitions is that, conceptually, the new role is not a superset of either of the old ones: role R1 does A { ... } R1.does(A) # true: R1 can do everything that A can. A.does(R1) # false: A can't neccessarily do everything that R1 can. role R2 does A | B { ... } R2.does(A) # true: R2 can do everything that A can. A.does(R2) # false: A can't neccessarily do everything that R2 can. role R3 does A & B { ... } R3.does(A) # false: R3 can't neccessarily do everything that A can. A.does(R3) # false: A can't neccessarily do everything that R3 can. This dissonance comes from the fact that "does" is being used in two different ways here: as an instruction to help define a class or role based off of another role or roles, and as a test of whether something is a semantic superset of a role. As long as the former only adds to or changes the roles that it composes, the two concepts are in synch; but once you allow subsets of roles to be composed, the symmetry breaks. And because you have the ability to add methods to R3 that aren't in A or B, you can't make use of the fact that A & B is a subset of A for type-checking purposes. -- Hmm... how about allowing something analogous to binding as the basis for set-like role composition: role Foo ::= A; # Foo.does(A) and A.does(Foo) role Foo ::= A | B; # Foo.does(A) and Foo.does(B) role Foo ::= A & B; # A.does(Foo) and B.does(Foo) role Foo ::= A - B; # A.does(Foo) The first case would merely make Foo synonymous with A; nothing special here. The second case would be equivalent to "role Foo does A does B { }". The third case would create a new role that includes only those methods that both A and B have; in addition, it would modify the definitions of both A and B so that they compose Foo. The fourth case would include those methods that are in A but not in B, and would modify the definition of A so that it composes Foo. These modifications to A and B won't change their existing behavior; they'll merely add to the range of types that A and B will match. In all of these cases, you don't get to add functionality to the new role. If A and B have methods that conflict, both A | B and A & B will include an undefined method instead. If you want to add functionality, compose Foo into something else and add the functionality there. One could try to extend this notion: "A | B" creates an anonymous role that composes A and B; "A & B" creates an anonymous role that both A and B compose (for type-checking purposes only); "A - B" creates an anonymous role that A composes (again, for type-checking purposes only). These expressions can be used in "does", or they can be bound to a name using '::=' (or ':=' at runtime). If parentheses get used, you could have something akin to ordered composition, with the innermost set operators being evaluated first: so "(A | B) | C" would compose an anonymous role that merges A and B, and would then compose C into the result - meaning that if A and B have conflicts, C can resolve them. So strictly ordered composition could be done as: role Foo does (((A) | B) | C) { ... } making it visually explicit as to what gets done when. This would require that '&' and '|' (and possibly '-') be
Interrogative statements
Let's say that I want $expression?; to mean the same thing as the statement $_ = $expression; That is, any statement that ends with a '?;' instead of a ';' evaluates in scalar context instead of void context and stores the result as the topic '$_'. (I was going to suggest '?' intead of '?;', but a quick review of the specs pointed out that this would be ambiguous wrt the ? prefix operator.) Is perl 6 powerful enough to enable this sort of thing with its existing tools, or would the parser need to be altered? -- Jonathan "Dataweaver" Lang