Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread Raphael Descamps
Am Freitag, den 10.07.2009, 17:06 -0700 schrieb Jon Lang:
 How about this: in role composition, mandate causes methods to take
 precedence over other methods with which they would normally conflict,
 and to conflict with methods that would normally take precedence over
 them.

I really dislike this because it is contrary to the original idea of the
stateless traits as defined in the original paper from Nathanael
Schärli.
The main reason why traits have been introduced was to solve the
problems inherent to mixins. In mixins the main problem is that the
class using the mixin is not able to control the composition (which is
simply done sequencially) and that lend to fragile hierarchies.

The brilliant idea with traits is that it bring back the control to
the class consuming the trait and conflicts have to be solved
explicitly. The traits paper propose 3 different operators to solve such
conflicts: overriding, excluding or aliasing.

I definitively think that perl 6 roles should also have an excluding
operator because I think that *every* composition conflicts arrising
should be solvable by the class comsuming the role.

What you propose here is a step behind: you reintroduce the problem
existing with mixins by bringing back precedence rules in the way
composition is made.

So far, I have only seen reference to the original paper decribing the
stateless traits. As roles are an implementation of stateful traits,
maybe we should start to point to the paper formalising it:
http://scg.unibe.ch/archive/papers/Berg07eStatefulTraits.pdf

   So:
 
 role R1 { mandate method foo { ... } }
 role R2 { method foo { ... } }
 class C does R1 does R2 { ... }
 
 Normally, the compiler would complain of a conflict between R1 and R2;
 but because R1::foo is mandated, it wins out.
 
 role R { mandate method foo { ... } }
 class C does R { method foo { ... } }
 
 Normally, C::foo would take precedence over R::foo; but because R::foo
 is mandated, the compiler complains of a conflict between C and R.
 
 When two methods have the mandate keyword, they are compared to each
 other as if neither had the keyword.
 
 role R { mandate method foo { ... } }
 class C does R { mandate method foo { ... } }
 
 Since both R::foo and C::foo are mandated, C::foo supersedes R::foo.
 
 Applying the mandate keyword to a role is shorthand for applying it
 to all of its methods.
 
 mandate role R {
 method foo { ... }
 method bar { ... }
 method baz { ... }
 }
 
 is the same as:
 
 role R {
 mandate method foo { ... }
 mandate method bar { ... }
 mandate method baz { ... }
 }
 
 This behavior can be overridden by the suggest keyword:
 
 mandate role R {
 suggest method foo { ... }
 method bar { ... }
 method baz { ... }
 }
 
 is the same as:
 
 role R {
 method foo { ... }
 mandate method bar { ... }
 mandate method baz { ... }
 }
 
 That is, every method is either mandated or suggested, and suggested
 by default.  Mandating a role changes the default for its methods, or
 you could explicitly suggest the role.  The latter possibility would
 allow for a pragma that changes the role's default importance from
 suggested to mandated.
 
 Ovid's distinction between interface and unit of behavior could be
 managed by this distinction: suggest role R is primarily intended as
 an interface, with behavior being a suggestion only and implicitly
 overriden by the class; mandate role R is primarily intended as a
 unit of behavior, and overriding its behavior requires that you
 explicitly supersede it.  In Ovid's programs, he might start by saying
 use mandate, so that roles operate as units of behavior by default,
 and can be declared as interfaces by saying suggest role instead of
 role.  Or maybe the pragma declares interface as a synonym for
 suggest role.  (I'd be more comfortable with this if I could think
 of a comparable synonym for mandate role; at that point, you could
 do away with the pragma - use role, suggest role, or interface
 to mean interface, and use mandate role or ??? to mean unit of
 behavior.)
 
 At this point, you can strengthen the importance of a method (raising
 it from a suggestion to a mandate); but you cannot weaken it.  Thus,
 interfaces can be composed into units of behavior; but not vice versa:
 attempting to do so would result in a unit of behavior.  I think that
 the converse _should_ be possible; but I'm not quite sure how it might
 be done.
 



Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread Jon Lang
Raphael Descamps wrote:
 Am Freitag, den 10.07.2009, 17:06 -0700 schrieb Jon Lang:
 How about this: in role composition, mandate causes methods to take
 precedence over other methods with which they would normally conflict,
 and to conflict with methods that would normally take precedence over
 them.

 I really dislike this because it is contrary to the original idea of the
 stateless traits as defined in the original paper from Nathanael
 Schärli.

Agreed.  OTOH, Roles are already contrary in this respect, because
they can provide attributes as well as methods.  Note also that this
was my first proposal; I have since abandoned it in favor of (I hope)
a more intuitive approach.

 The main reason why traits have been introduced was to solve the
 problems inherent to mixins. In mixins the main problem is that the
 class using the mixin is not able to control the composition (which is
 simply done sequencially) and that lend to fragile hierarchies.

 The brilliant idea with traits is that it bring back the control to
 the class consuming the trait and conflicts have to be solved
 explicitly. The traits paper propose 3 different operators to solve such
 conflicts: overriding, excluding or aliasing.

 I definitively think that perl 6 roles should also have an excluding
 operator because I think that *every* composition conflicts arising
 should be solvable by the class comsuming the role.

 What you propose here is a step behind: you reintroduce the problem
 existing with mixins by bringing back precedence rules in the way
 composition is made.

Well, yes and no.  The class still has the final say on how a given
method is to be implemented; the only thing being debated here is
whether or not the class should have to explicitly pull rank to
redefine a method being provided by a role, or if it does so silently.
 The latter approach is how things currently stand, and is being
criticized as a source of bugs as authors of classes inadvertently
override method definitions that they didn't intend to override.

 So far, I have only seen reference to the original paper decribing the
 stateless traits. As roles are an implementation of stateful traits,
 maybe we should start to point to the paper formalising it:
 http://scg.unibe.ch/archive/papers/Berg07eStatefulTraits.pdf

Thanks for the link.

-- 
Jonathan Dataweaver Lang


Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread TSa

HaloO,

Jon Lang wrote:

I'd still like to get a synonym for mandate role, though - a word
that captures the meaning of unit of behavior.


A bit burdened with conflicting meaning but I think mixin is what
you are looking for.


Regards, TSa.
--
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread TSa

HaloO,

Jon Lang wrote:

Well, yes and no.  The class still has the final say on how a given
method is to be implemented; the only thing being debated here is
whether or not the class should have to explicitly pull rank to
redefine a method being provided by a role, or if it does so silently.
 The latter approach is how things currently stand, and is being
criticized as a source of bugs as authors of classes inadvertently
override method definitions that they didn't intend to override.


I think the distinction can be made implicitly. Methods in a role
with no implementation are silently overridden. Ones with an
implementation produce a warning if the composing class overrides
it without some extra syntax. This bites only the case where the
role provides a default implementation intended for overriding.

Regards, TSa.
--
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: YAPC::EU and Perl 6 Roles

2009-07-15 Thread Jon Lang
TSa wrote:
 HaloO,

 Jon Lang wrote:

 Well, yes and no.  The class still has the final say on how a given
 method is to be implemented; the only thing being debated here is
 whether or not the class should have to explicitly pull rank to
 redefine a method being provided by a role, or if it does so silently.
  The latter approach is how things currently stand, and is being
 criticized as a source of bugs as authors of classes inadvertently
 override method definitions that they didn't intend to override.

 I think the distinction can be made implicitly. Methods in a role
 with no implementation are silently overridden. Ones with an
 implementation produce a warning if the composing class overrides
 it without some extra syntax. This bites only the case where the
 role provides a default implementation intended for overriding.

Perhaps.  FWIW, applying the supersede keyword to the class method
would work as the extra syntax to which you refer.  Your last
sentence is pointing to the distinction that I was trying to make with
the mandate/suggest pairing.

For clarity, let me propose the following terminology: an interface
is a role with methods that suggest their implementations by default;
a mixin is a role with methods that mandate their implementations by
default.  I could see adopting one of these terms as a variation on
role and treating role itself as the other one; if we do this,
which would be preferable: interfaces and roles, or roles and mixins?
That is: when you think role, do you think of the interface
semantics or the mixin semantics most readily?

-- 
Jonathan Dataweaver Lang