From aecd526985b770a920db783b162326cb46442353 Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Thu, 30 Apr 2020 07:11:51 -0300 Subject: [PATCH 1/5] Document Metamodel::TypePretense and Metamodel::MethodDelegation --- doc/Type/Metamodel/MethodDelegation.pod6 | 67 +++++++++++++++++++++ doc/Type/Metamodel/TypePretense.pod6 | 75 ++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 doc/Type/Metamodel/MethodDelegation.pod6 create mode 100644 doc/Type/Metamodel/TypePretense.pod6 diff --git a/doc/Type/Metamodel/MethodDelegation.pod6 b/doc/Type/Metamodel/MethodDelegation.pod6 new file mode 100644 index 000000000..9ec041400 --- /dev/null +++ b/doc/Type/Metamodel/MethodDelegation.pod6 @@ -0,0 +1,67 @@ +=begin pod :kind :subkind :category + +=TITLE role Metamodel::MethodDelegation + +=SUBTITLE Metarole for delegating method dispatch + + role Metamodel::MethodDelegation { } + +I: this role is part of the Rakudo implementation, and is not +a part of the language specification. + +Methods of C and C can be invoked on roles, despite them not +actually having these types as parents: + +=begin code +role Role { } + +say Role.raku; # OUTPUT: «Role␤» +say Role.^pun.^parents(:all).map(*.^name); # OUTPUT: «()␤» +=end code + +C is the metarole responsible for this +behavior. Using the metamethods this provides, metaobjects can delegate +method dispatch to another type object. This can be useful when +implementing types that shouldn't store methods of their own through +L|/type/Metamodel::MethodContainer>, but +should still support method dispatch somehow. + +All this metarole does is provide an interface for storing a type object +to delegate methods to and provide a default C method for +delegating method lookups to that type object if no other method lookup +behavior for it exists; any other behavior related to methods is left up +to the metaclasses that do this metarole to implement themselves. + +Because method delegation is a property of the metaclass for a HOW, not +HOWs themselves, the C and +C metamethods this metarole provides must be +invoked directly through a metaclass or HOW, not with C<.^> syntax: + +=for code :preamble +say Role.HOW.delegating_methods_to.^name; # OUTPUT: «Any␤» + +This metarole is commonly used in combination with +L|/type/Metamodel::TypePretense>. + +=head1 Methods + +=head2 method delegate_methods_to + + method delegate_methods_to($type) + +Delegates methods to a type object. + +=head2 method delegating_methods_to + + method delegating_methods_to() + +Returns the type object a metaobject is delegating methods to. + +=head2 method find_method + + method find_method($obj, $name) + +Looks up a method on the type object this metaobject is delegating +method dispatch to. + +=end pod diff --git a/doc/Type/Metamodel/TypePretense.pod6 b/doc/Type/Metamodel/TypePretense.pod6 new file mode 100644 index 000000000..9651a994e --- /dev/null +++ b/doc/Type/Metamodel/TypePretense.pod6 @@ -0,0 +1,75 @@ +=begin pod :kind :subkind :category + +=TITLE role Metamodel::TypePretense + +=SUBTITLE Metarole for type pretenses + + role Metamodel::TypePretense { } + +I: this role is part of the Rakudo implementation, and is not +a part of the language specification. + +Roles can type-check as C, C, and C, but don't actually +have these classes as parents: + +=begin code +class Class { } +role Role { } + +say Role ~~ Mu; # OUTPUT: «True␤» +say Role ~~ Any; # OUTPUT: «True␤» +say Role ~~ Cool; # OUTPUT: «True␤» + +say Class.^parents(:all).map(*.^name); # OUTPUT: «(Any Mu)␤» +say Role.^pun.^parents(:all).map(*.^name); # OUTPUT: «()␤» +=end code + +C is the metarole that's responsible for this +behavior. Using the metamethods this provides, types can C other types, i.e. types can type-check as other types. This can be +useful when implementing types that should not store parent types +through +L|/type/Metamodel::MultipleInheritance>, +but should still type-check like other types somehow. + +All this metarole does is provide an interface for storing type objects +in a HOW and provide a default C method that allows types to +type-check as the types they're pretending to be if no other +type-checking behavior for it exists; any other behavior related to type +pretenses are left up to the metaclasses that do this metarole to +implement themselves. + +Because type pretenses are a property of the metaclass for a HOW, not +HOWs themselves, the C and C +metamethods this metarole provides must be invoked directly through a +metaclass or HOW, not with C<.^> syntax: + +=for code :preamble +say Role.HOW.pretending_to_be.map(*.^name); # OUTPUT: «(Cool Any Mu)» + +This metarole is commonly used in combination with +L|/type/Metamodel::MethodDelegation>. + +=head1 Methods + +=head2 method pretend_to_be + + method pretend_to_be(@types) + +Makes all types for a type of HOW pretend to be any of the type objects +in C<@types>. + +=head2 method pretending_to_be + + method pretending_to_be() + +Returns the type objects this type of HOW is pretending to be. + +=head2 method type_check + + method type_check($obj, $checkee) + +If C<$checkee> is the same object as C<$obj> or is of any of the types +C<$obj> is pretending to be, returns C<1>, otherwise returns C<0>. + +=end pod From b1716d431c5ddfbcf1c433d7727ef12015021c66 Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Thu, 30 Apr 2020 12:58:38 -0300 Subject: [PATCH 2/5] Document role type pretense and method delegation behaviour --- doc/Type/Metamodel/CurriedRoleHOW.pod6 | 4 ++++ doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 | 4 ++++ doc/Type/Metamodel/ParametricRoleHOW.pod6 | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/doc/Type/Metamodel/CurriedRoleHOW.pod6 b/doc/Type/Metamodel/CurriedRoleHOW.pod6 index 6419535d7..7ecbb505c 100644 --- a/doc/Type/Metamodel/CurriedRoleHOW.pod6 +++ b/doc/Type/Metamodel/CurriedRoleHOW.pod6 @@ -61,6 +61,10 @@ a single parameter an instantiated role will also be of the same type: role Zape[::T] {}; say Zape[Int].HOW; #: «Perl6::Metamodel::CurriedRoleHOW.new␤» +Curried roles L of types +C, C, and C, and +L methods to C. + I: As most of the C classes, this class is here mainly for illustration purposes and it's not intended for the final user to instantiate. diff --git a/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 b/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 index 9ba35ec9d..03cc83a3a 100644 --- a/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 +++ b/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 @@ -28,6 +28,10 @@ my \zape := Metamodel::ParametricRoleGroupHOW.new_type( name => "zape"); my \zipi := Metamodel::ParametricRoleHOW.new_type( name => "zipi", group => zape); say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» +Role groups L of types +C, C, and C, and +L methods to C. + I: As most of the C classes, this class is here mainly for illustration purposes and it's not intended for the final user to instantiate. diff --git a/doc/Type/Metamodel/ParametricRoleHOW.pod6 b/doc/Type/Metamodel/ParametricRoleHOW.pod6 index b4ac7f736..c02e4ef6f 100644 --- a/doc/Type/Metamodel/ParametricRoleHOW.pod6 +++ b/doc/Type/Metamodel/ParametricRoleHOW.pod6 @@ -38,6 +38,10 @@ say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» The extra C argument will need to be used to integrate it in a parametric role group, which will need to be defined in advance. +Roles L of types C, +C, and C, and L +methods to C. + I: As most of the C classes, this one is here mainly for illustration purposes and it's not intended for the final user to instantiate, unless their intention is really to create a parametric role group. From d660828f25c2299428c6ca84d8ec984a8b6d9636 Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Thu, 30 Apr 2020 14:11:56 -0300 Subject: [PATCH 3/5] Correct Metamodel::TypePretense and Metamodel::MethodDelegation subkinds --- doc/Type/Metamodel/MethodDelegation.pod6 | 2 +- doc/Type/Metamodel/TypePretense.pod6 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Type/Metamodel/MethodDelegation.pod6 b/doc/Type/Metamodel/MethodDelegation.pod6 index 9ec041400..bc0cc8ffc 100644 --- a/doc/Type/Metamodel/MethodDelegation.pod6 +++ b/doc/Type/Metamodel/MethodDelegation.pod6 @@ -1,4 +1,4 @@ -=begin pod :kind :subkind :category +=begin pod :kind :subkind :category =TITLE role Metamodel::MethodDelegation diff --git a/doc/Type/Metamodel/TypePretense.pod6 b/doc/Type/Metamodel/TypePretense.pod6 index 9651a994e..4c295b836 100644 --- a/doc/Type/Metamodel/TypePretense.pod6 +++ b/doc/Type/Metamodel/TypePretense.pod6 @@ -1,4 +1,4 @@ -=begin pod :kind :subkind :category +=begin pod :kind :subkind :category =TITLE role Metamodel::TypePretense From 7caaa3078eb63831095242adb670117aa8fb2084 Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Thu, 30 Apr 2020 14:18:53 -0300 Subject: [PATCH 4/5] Clarify Metamodel::MethodDelegation.delegate_methods_to's documentation --- doc/Type/Metamodel/MethodDelegation.pod6 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/Type/Metamodel/MethodDelegation.pod6 b/doc/Type/Metamodel/MethodDelegation.pod6 index bc0cc8ffc..30f6023a9 100644 --- a/doc/Type/Metamodel/MethodDelegation.pod6 +++ b/doc/Type/Metamodel/MethodDelegation.pod6 @@ -49,7 +49,8 @@ L|/type/Metamodel::TypePretense>. method delegate_methods_to($type) -Delegates methods to a type object. +Delegates methods to C<$type>. This should be a type object, but may be +any object with a C metamethod technically. =head2 method delegating_methods_to From 7f6f2c7246c0916b2290c8ddb73c8ae4a784155f Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Thu, 30 Apr 2020 14:24:48 -0300 Subject: [PATCH 5/5] Clarify how roles typecheck in Metamodel::TypePretense --- doc/Type/Metamodel/TypePretense.pod6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Type/Metamodel/TypePretense.pod6 b/doc/Type/Metamodel/TypePretense.pod6 index 4c295b836..4695927ac 100644 --- a/doc/Type/Metamodel/TypePretense.pod6 +++ b/doc/Type/Metamodel/TypePretense.pod6 @@ -9,8 +9,8 @@ I: this role is part of the Rakudo implementation, and is not a part of the language specification. -Roles can type-check as C, C, and C, but don't actually -have these classes as parents: +Any role will type-check as C, C, and C, but don't +actually have these classes as parents: =begin code class Class { }