More thoughts on roles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Colomon recently pointed out that the "claim" directive does not do all | |
that much to help the problem which overriding methods from crony roles | |
presents, and we still need a concept of "most-derived" in roles to | |
resolve these conflicts. | |
(https://justrakudoit.wordpress.com/2015/03/07/role-inheritance/) | |
If I understand Ovid's characterization of this problem, it was from the | |
standpoint of developers not expecting role ordering to matter, because | |
roles are primarily there to separate concerns as a flat set. IIRC Ovid | |
would have preferred the resolution to these matters be up on the same | |
LOC where the roles were included, and "claim" does not do that, either, | |
since it can be buried deep in the body of the role. | |
While I have come to agree with colomon's point that there is indeed an | |
"inheritance" relationship among roles, as currently specced, I am concerned | |
that this relationship should continue to be viewed as an ancillary | |
attachment to roles, and that roles should primarily be viewed as a flat | |
set of functionality. | |
Not all hammers have nail pullers and we don't call hammers | |
"nail pullers" we just put a nail puller on the back of some of | |
them because it is useful. IMO I think it is important to view | |
"role A does role B" as "role A will not show up to the BBQ | |
without role B" even in the face of that feature. | |
Another issue in all this is what to do about BUILD, which is a | |
pain point for those trying to use roles as roles and not as lenient | |
classes: when you have complex logic for attribute initialization in | |
a role, you need it to run, even if another role with complex | |
initialization logic is mixed in, and you just cannot do that with | |
submethod BUILD. That separation of concerns is part of the | |
whole reason for using roles in the first place. | |
A final issue is the fact that, though the spec goes to some lengths | |
to make it clear that a crony role cannot conflict with itself (unless | |
it is brought in via multiple classes in a class inheritance), it | |
does in the implementation, and it's been hard to get affirmation | |
that this is a bug, not a feature. Personally I have found cronies | |
conflicting with themselves to be a hindrance to some use cases, | |
e.g. you want C to show up at the BBQ when you invite either or | |
both of A and B, because A and B both bring the blandest potato | |
salad you have ever tasted and C is the only one who brings the | |
salt and pepper. | |
I'm far from competent on the language design front, but has it | |
been considered that one problem is we only have one verb for | |
role composition? Should we have more than "does"? | |
role A does B { } # flat set, order does not matter, die on conflicts | |
role A wraps B { } # A is mildly class-like, order matters, A wins on conflicts. | |
...and perhaps some others to control behavior of .WALK (nextsame etc) | |
within the role "inheritance" hierarchy. The BUILD problem will | |
need some additional work outside of that. Roles may need their | |
own work-alike set of methods in addition to BUILD for role-local | |
initialization. | |
Sure this does not get us per-method granularity, but it makes it | |
obvious that when you use "wraps" (or whatever) order does matter. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment