Author: szabgab Date: 2009-04-27 09:06:56 +0200 (Mon, 27 Apr 2009) New Revision: 26479
Modified: docs/Perl6/Spec/S14-roles-and-parametric-types.pod Log: dos2unix Modified: docs/Perl6/Spec/S14-roles-and-parametric-types.pod =================================================================== --- docs/Perl6/Spec/S14-roles-and-parametric-types.pod 2009-04-27 06:56:19 UTC (rev 26478) +++ docs/Perl6/Spec/S14-roles-and-parametric-types.pod 2009-04-27 07:06:56 UTC (rev 26479) @@ -17,7 +17,7 @@ =head1 Overview -This synopsis discusses roles and parametric types, which were +This synopsis discusses roles and parametric types, which were originally discussed in A12. =head1 Roles @@ -96,9 +96,9 @@ Within a role the C<has> declarator always indicates the declaration from the viewpoint of the class. Therefore a private attribute declared -using C<has> is private to the class, not to the role. You may wish to -declare an attribute that is hidden even from the class; a completely -private role attribute (that will exist per instance of the class) may +using C<has> is private to the class, not to the role. You may wish to +declare an attribute that is hidden even from the class; a completely +private role attribute (that will exist per instance of the class) may be declared like this: my $!spleen; @@ -364,30 +364,30 @@ appropriate C<trait_auxiliary:is()> routine yourself if you want it to do any extra shenanigans. The compiler won't call it for you at run time like it would at compile time. - + =head1 Parametric Roles -A role's main type is generic by default, but you can also parameterize -other types explicitly using type parameters: - - role Pet[::Petfood = TableScraps] { - method feed (Petfood $food) {...} - } - -(Note that in this case you must not use ::Petfood in the inner declaration, -or it would rebind the type to type of the actual food parameter.) - -If you want to parameterize the initial value of a role attribute, -be sure to put a double semicolon if you don't want the parameter to -be considered part of the long name: - - role Pet[::ID;; $tag] { - has ID $.collar .= new($tag); - } +A role's main type is generic by default, but you can also parameterize +other types explicitly using type parameters: -You don't just have to parameterize on types; any value is fine. Imagine -we wanted to factor out a "greet" method into a role, which takes + role Pet[::Petfood = TableScraps] { + method feed (Petfood $food) {...} + } + +(Note that in this case you must not use ::Petfood in the inner declaration, +or it would rebind the type to type of the actual food parameter.) + +If you want to parameterize the initial value of a role attribute, +be sure to put a double semicolon if you don't want the parameter to +be considered part of the long name: + + role Pet[::ID;; $tag] { + has ID $.collar .= new($tag); + } + +You don't just have to parameterize on types; any value is fine. Imagine +we wanted to factor out a "greet" method into a role, which takes somebody's name and greets them. We can parameterize it on the greeting. role Greet[Str $greeting] { @@ -412,12 +412,12 @@ Slovak.new.request("borovicka"); Lolcat.new.request("CHEEZEBURGER"); -Sadly, the Slovak output sucks here. Borovicka is the nominative form -of the word, and we need to decline it into the accusative case. But -some languages don't care about that, and we don't want to have to make -them all supply a transform. Thankfully, you can write many roles with -the same short name, and a different signature, and multi-dispatch will -pick the right one for you (it is the exact same dispatch algorithm used +Sadly, the Slovak output sucks here. Borovicka is the nominative form +of the word, and we need to decline it into the accusative case. But +some languages don't care about that, and we don't want to have to make +them all supply a transform. Thankfully, you can write many roles with +the same short name, and a different signature, and multi-dispatch will +pick the right one for you (it is the exact same dispatch algorithm used by multi-subs). So we can write: role Request[Str $statement] { @@ -442,76 +442,76 @@ Slovak.new.request("borovicka"); Lolcat.new.request("CHEEZEBURGER"); -Which means we can now properly order our borovicka in Slovakia, which -is awesome. Until you do it in a loop and find the Headache['very bad'] +Which means we can now properly order our borovicka in Slovakia, which +is awesome. Until you do it in a loop and find the Headache['very bad'] role got mixed into yourself overnight, anyway... -=head2 Relationship Between of And Types - -The of keyword is just syntactic sugar for providing a single -parameter to a parametric type. Thus: - - my Array of Recipe %book; - -Actually means: - - my Array[Recipe] %book; - -This can be nested, so: - - my Hash of Array of Recipe @library; - -Is just: - - my Hash[Array[Recipe]] @library; - -Therefore: - - my Array @array; - -Means an Array of Array (actually, a Positional of Array). - -=head2 Parametric Subtyping - -If you have two types in a subtyping relationship such that T1 is -narrower than T2, then also the roles: - - role R[::T] { } - role R[::T1, ::T2] { } - -Will act such that R[T1] is narrower than R[T2]. This extends to multiple -parameters, however they must all be narrower or the same (this is unlike -in multiple dispatch where you can have one narrower and the rest narrower -or tied). That is, assuming we have some unrelated type T3, then R[T2, T1] -is narrower than R[T1,T1] but R[T2,T1] is not narrower than R[T1,T3]. - -Nesting follows naturally from this definition, so a role R[R[T2]] is -narrower than a role R[R[T1]]. - -This all means that, for example, if you have a sub: - - sub f(Num @arr) { ... } - -Then you can also call it with an array of Int. - - my Int @a = 1,2,3; - f(@a); - -=head2 Interaction of typed and untyped data structures - -Certainly so far as Perl 6.0.0 goes, only types that have been declared -on a container count in the type check. That is, if we have a sub: - - sub f(Int @arr) { ... } - -And call it with any of: - - f([1,2,3]); - my @a = 1,2,3; - f(@a); - -Then neither of these calls will work. The type check is based on the -declared type of the array, and the content is unknown to the type -checker. +=head2 Relationship Between of And Types +The of keyword is just syntactic sugar for providing a single +parameter to a parametric type. Thus: + + my Array of Recipe %book; + +Actually means: + + my Array[Recipe] %book; + +This can be nested, so: + + my Hash of Array of Recipe @library; + +Is just: + + my Hash[Array[Recipe]] @library; + +Therefore: + + my Array @array; + +Means an Array of Array (actually, a Positional of Array). + +=head2 Parametric Subtyping + +If you have two types in a subtyping relationship such that T1 is +narrower than T2, then also the roles: + + role R[::T] { } + role R[::T1, ::T2] { } + +Will act such that R[T1] is narrower than R[T2]. This extends to multiple +parameters, however they must all be narrower or the same (this is unlike +in multiple dispatch where you can have one narrower and the rest narrower +or tied). That is, assuming we have some unrelated type T3, then R[T2, T1] +is narrower than R[T1,T1] but R[T2,T1] is not narrower than R[T1,T3]. + +Nesting follows naturally from this definition, so a role R[R[T2]] is +narrower than a role R[R[T1]]. + +This all means that, for example, if you have a sub: + + sub f(Num @arr) { ... } + +Then you can also call it with an array of Int. + + my Int @a = 1,2,3; + f(@a); + +=head2 Interaction of typed and untyped data structures + +Certainly so far as Perl 6.0.0 goes, only types that have been declared +on a container count in the type check. That is, if we have a sub: + + sub f(Int @arr) { ... } + +And call it with any of: + + f([1,2,3]); + my @a = 1,2,3; + f(@a); + +Then neither of these calls will work. The type check is based on the +declared type of the array, and the content is unknown to the type +checker. + =for vim:set expandtab sw=4: