Author: larry
Date: Sat Dec 23 12:50:23 2006
New Revision: 13501
Modified:
doc/trunk/design/syn/S02.pod
doc/trunk/design/syn/S06.pod
Log:
Housekeeping move of basic types section from S06 to S02, no other changes.
Modified: doc/trunk/design/syn/S02.pod
==============================================================================
--- doc/trunk/design/syn/S02.pod (original)
+++ doc/trunk/design/syn/S02.pod Sat Dec 23 12:50:23 2006
@@ -12,9 +12,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 10 Aug 2004
- Last Modified: 16 Dec 2006
+ Last Modified: 23 Dec 2006
Number: 2
- Version: 81
+ Version: 82
This document summarizes Apocalypse 2, which covers small-scale
lexical items and typological issues. (These Synopses also contain
@@ -656,6 +656,344 @@
=back
+=head2 Native types
+
+Values with these types autobox to their uppercase counterparts when
+you treat them as objects:
+
+ bit single native bit
+ int native signed integer
+ uint native unsigned integer (autoboxes to Int)
+ buf native buffer (finite seq of native ints or uints, no Unicode)
+ num native floating point
+ complex native complex number
+ bool native boolean
+
+=head2 Undefined types
+
+These can behave as values or objects of any class, except that
+C<defined> always returns false. One can create them with the
+built-in C<undef> and C<fail> functions. (See S02 for how failures
+are handled.)
+
+ Undef Undefined (can serve as a prototype object of any class)
+ Whatever Wildcard (like undef, but subject to do-what-I-mean via MMD)
+ Failure Failure (throws an exception if not handled properly)
+
+=head2 Immutable types
+
+Objects with these types behave like values, i.e. C<$x === $y> is true
+if and only if their types and contents are identical (that is, if
+C<$x.WHICH> eqv C<$y.WHICH>).
+
+ Bit Perl single bit (allows traits, aliasing, undef, etc.)
+ Int Perl integer (allows Inf/NaN, arbitrary precision, etc.)
+ Str Perl string (finite sequence of Unicode characters)
+ Num Perl number
+ Complex Perl complex number
+ Bool Perl boolean
+ Exception Perl exception
+ Code Base class for all executable objects
+ Block Executable objects that have lexical scopes
+ List Lazy Perl list (composed of Seq and Range parts)
+ Seq Completely evaluated (hence immutable) sequence
+ Range A pair of Ordered endpoints; gens lazy Seq in list context
+ Set Unordered Seq that allows no duplicates (does KeyHash, but ro)
+ Bag Unordered Seq that allows duplicates (does KeyHash, but ro)
+ Junction Sets with additional behaviours
+ Pair Seq of two elements that serves as a one-element Mapping
+ Mapping Pairs with no duplicate keys
+ Signature Function parameters (left-hand side of a binding)
+ Capture Function call arguments (right-hand side of a binding)
+ Blob An undifferentiated mass of bits
+
+=head2 Mutable types
+
+Objects with these types have distinct C<.WHICH> values that do not change
+even if the object's contents change.
+
+ Scalar Perl scalar
+ Array Perl array
+ Hash Perl hash
+ KeyHash Perl hash that autodeletes values matching default
+ KeySet KeyHash of Bool (does Set in list/array context)
+ KeyBag KeyHash of UInt (does Bag in list/array context)
+ Buf Perl buffer (a stringish array of memory locations)
+ IO Perl filehandle
+ Routine Base class for all wrappable executable objects
+ Sub Perl subroutine
+ Method Perl method
+ Submethod Perl subroutine acting like a method
+ Macro Perl compile-time subroutine
+ Regex Perl pattern
+ Match Perl match, usually produced by applying a pattern
+ Package Perl 5 compatible namespace
+ Module Perl 6 standard namespace
+ Class Perl 6 standard class namespace
+ Role Perl 6 standard generic interface/implementation
+ Object Perl 6 object
+ Grammar Perl 6 pattern matching namespace
+
+A C<KeyHash> differs from a normal C<Hash> in how it handles default
+values. If the value of a C<KeyHash> element is set to the default
+value for the C<KeyHash>, the element is deleted. If undeclared,
+the default default for a C<KeyHash> is 0 for numeric types, C<False>
+for boolean types, and the null string for string and buffer types.
+A C<KeyHash> of a C<Object> type defaults to the undefined prototype
+for that type. More generally, the default default is whatever defined
+value an C<undef> would convert to for that value type. A C<KeyHash>
+of C<Scalar> deletes elements that go to either 0 or the null string.
+A C<KeyHash> also autodeletes keys for normal undef values (that is,
+those undefined values that do not contain an unthrown exception).
+
+A C<KeySet> is a C<KeyHash> of booleans with a default of C<False>.
+If you use the C<Hash> interface and increment an element of a
+C<KeySet> its value becomes true (creating the element if it doesn't
+exist already). If you decrement the element it becomes false and
+is automatically deleted. When not used as a C<Hash> (that is,
+when used as an C<Array> or list or C<Set> object) a C<KeySet>
+behaves as a C<Set> of its keys. (Since the only possible value of
+a C<KeySet> is the C<True> value, it need not be represented in
+the actual implementation with any bits at all.)
+
+A C<KeyBag> is a C<KeyHash> of C<UInt> with default of 0. If you
+use the C<Hash> interface and increment an element of a C<KeyBag>
+its value is increased by one (creating the element if it doesn't exist
+already). If you decrement the element the value is decreased by one;
+if the value goes to 0 the element is automatically deleted. When not
+used as a C<Hash> (that is, when used as an C<Array> or list or C<Bag>
+object) a C<KeyBag> behaves as a C<Bag> of its keys, with each key
+replicated the number of times specified by its corresponding value.
+(Use C<.kv> or C<.pairs> to suppress this behavior in list context.)
+
+=head2 Value types
+
+Explicit types are optional. Perl variables have two associated types:
+their "value type" and their "implementation type". (More generally, any
+container has an implementation type, including subroutines and modules.)
+The value type is stored as its C<of> property, while the implementation
+type of the container is just the object type of the container itself.
+
+The value type specifies what kinds of values may be stored in the
+variable. A value type is given as a prefix or with the C<of> keyword:
+
+ my Dog $spot;
+ my $spot of Dog;
+
+In either case this sets the C<of> property of the container to C<Dog>.
+
+Subroutines have a variant of the C<of> property, C<returns>, that sets
+the C<returns> property instead. The C<returns> property specifies a
+constraint (or perhaps coercion) to be enforced on the return value (either
+by explicit call to C<return> or by implicit fall-off-the-end return).
+This constraint, unlike the C<of> property, is not advertised as the
+type of the routine. You can think of it as the implicit type signature of
+the (possibly implicit) return statement. It's therefore available for
+type inferencing within the routine but not outside it. If no inner type
+is declared, it is assumed to be the same as the C<of> type, if declared.
+
+ sub get_pet() of Animal {...} # of type, obviously
+ our Animal sub get_pet() {...} # of type
+ sub get_pet() returns Animal {...} # inner type
+
+A value type on an array or hash specifies the type stored by each element:
+
+ my Dog @pound; # each element of the array stores a Dog
+
+ my Rat %ship; # the value of each entry stores a Rat
+
+The key type of a hash may be specified as a shape trait--see S09.
+
+=head2 Implementation types
+
+The implementation type specifies how the variable itself is implemented. It is
+given as a trait of the variable:
+
+ my $spot is Scalar; # this is the default
+ my $spot is PersistentScalar;
+ my $spot is DataBase;
+
+Defining an implementation type is the Perl 6 equivalent to tying
+a variable in Perl 5. But Perl 6 variables are tied directly at
+declaration time, and for performance reasons may not be tied with a
+run-time C<tie> statement unless the variable is explicitly declared
+with an implementation type that does the C<Tieable> role.
+
+However, package variables are always considered C<Tieable> by default.
+As a consequence, all named packages are also C<Tieable> by default.
+Classes and modules may be viewed as differently tied packages.
+Looking at it from the other direction, classes and modules that
+wish to be bound to a global package name must be able to do the
+C<Package> role.
+
+=head2 Hierarchical types
+
+A non-scalar type may be qualified, in order to specify what type of
+value each of its elements stores:
+
+ my Egg $cup; # the value is an Egg
+ my Egg @carton; # each elem is an Egg
+ my Array of Egg @box; # each elem is an array of Eggs
+ my Array of Array of Egg @crate; # each elem is an array of arrays of
Eggs
+ my Hash of Array of Recipe %book; # each value is a hash of arrays of
Recipes
+
+Each successive C<of> makes the type on its right a parameter of the
+type on its left. Parametric types are named using square brackets, so:
+
+ my Hash of Array of Recipe %book;
+
+actually means:
+
+ my Hash[of => Array[of => Recipe]] %book;
+
+Because the actual variable can be hard to find when complex types are
+specified, there is a postfix form as well:
+
+ my Hash of Array of Recipe %book; # HoHoAoRecipe
+ my %book of Hash of Array of Recipe; # same thing
+
+The C<returns> form may be used in subroutines:
+
+ my sub get_book ($key) returns Hash of Array of Recipe {...}
+
+Alternately, the return type may be specified within the signature:
+
+ my sub get_book ($key --> Hash of Array of Recipe) {...}
+
+There is a slight difference, insofar as the type inferencer will
+ignore a C<returns> but pay attention to C<< --> >> or prefix type
+declarations, also known as the C<of> type. Only the inside of the
+subroutine pays attention to C<returns>.
+
+You may also specify the C<of> type as the C<of> trait:
+
+ my Hash of Array of Recipe sub get_book ($key) {...}
+ my sub get_book ($key) of Hash of Array of Recipe {...}
+
+=head2 Polymorphic types
+
+Anywhere you can use a single type you can use a set of types, for convenience
+specifiable as if it were an "or" junction:
+
+ my Int|Str $error = $val; # can assign if $val~~Int or
$val~~Str
+
+Fancier type constraints may be expressed through a subtype:
+
+ subset Shinola of Any where {.does(DessertWax) and .does(FloorTopping)};
+ if $shimmer ~~ Shinola {...} # $shimmer must do both interfaces
+
+Since the terms in a parameter could be viewed as a set of
+constraints that are implicitly "anded" together (the variable itself
+supplies type constraints, and C<where> clauses or tree matching just
+add more constraints), we relax this to allow juxtaposition of
+types to act like an "and" junction:
+
+ # Anything assigned to the variable $mitsy must conform
+ # to the type Fish and either the Cat or Dog type...
+ my Cat|Dog Fish $mitsy = new Fish but { int rand 2 ?? .does Cat
+ !! .does Dog };
+
+=head2 Parameter types
+
+Parameters may be given types, just like any other variable:
+
+ sub max (int @array is rw) {...}
+ sub max (@array of int is rw) {...}
+
+=head2 Generic types
+
+Within a declaration, a class variable (either by itself or
+following an existing type name) declares a new type name and takes
+its parametric value from the actual type of the parameter it is
+associated with. It declares the new type name in the same scope
+as the associated declaration.
+
+ sub max (Num ::X @array) {
+ push @array, X.new();
+ }
+
+The new type name is introduced immediately, so two such types in
+the same signature must unify compatibly if they have the same name:
+
+ sub compare (Any ::T $x, T $y) {
+ return $x eqv $y;
+ }
+
+=head2 Return types
+
+On a scoped subroutine, a return type can be specified before or after
+the name. We call all return types "return types", but distinguish
+two kinds of return types, the C<inner> type and the C<of> type,
+because the C<of> type is normally an "official" named type and
+declares the official interface to the routine, while the C<inner>
+type is merely a constraint on what may be returned by the routine
+from the routine's point of view.
+
+ our sub lay returns Egg {...} # inner type
+ our Egg sub lay {...} # of type
+ our sub lay of Egg {...} # of type
+ our sub lay (--> Egg) {...} # of type
+
+ my sub hat returns Rabbit {...} # inner type
+ my Rabbit sub hat {...} # of type
+ my sub hat of Rabbit {...} # of type
+ my sub hat (--> Rabbit) {...} # of type
+
+If a subroutine is not explicitly scoped, it belongs to the current
+namespace (module, class, grammar, or package), as if it's scoped with
+the C<our> scope modifier. Any return type must go after the name:
+
+ sub lay returns Egg {...} # inner type
+ sub lay of Egg {...} # of type
+ sub lay (--> Egg) {...} # of type
+
+On an anonymous subroutine, any return type can only go after the C<sub>
+keyword:
+
+ $lay = sub returns Egg {...}; # inner type
+ $lay = sub of Egg {...}; # of type
+ $lay = sub (--> Egg) {...}; # of type
+
+but you can use a scope modifier to introduce an C<of> prefix type:
+
+ $lay = my Egg sub {...}; # of type
+ $hat = my Rabbit sub {...}; # of type
+
+Because they are anonymous, you can change the C<my> modifier to C<our>
+without affecting the meaning.
+
+The return type may also be specified after a C<< --> >> token within
+the signature. This doesn't mean exactly the same thing as C<returns>.
+The C<of> type is the "official" return type, and may therefore be
+used to do type inferencing outside the sub. The C<inner> type only
+makes the return type available to the internals of the sub so that
+the C<return> statement can know its context, but outside the sub we
+don't know anything about the return value, as if no return type had
+been declared. The prefix form specifies the C<of> type rather than
+the C<inner> type, so the return type of
+
+ my Fish sub wanda ($x) { ... }
+
+is known to return an object of type Fish, as if you'd said:
+
+ my sub wanda ($x --> Fish) { ... }
+
+I<not> as if you'd said
+
+ my sub wanda ($x) returns Fish { ... }
+
+It is possible for the C<of> type to disagree with the C<inner> type:
+
+ my Squid sub wanda ($x) returns Fish { ... }
+
+or equivalently,
+
+ my sub wanda ($x --> Squid) returns Fish { ... }
+
+This is not lying to yourself--it's lying to the world. Having a
+different inner type is useful if you wish to hold your routine to
+a stricter standard than you let on to the outside world, for instance.
+
=head1 Names and Variables
=over 4
Modified: doc/trunk/design/syn/S06.pod
==============================================================================
--- doc/trunk/design/syn/S06.pod (original)
+++ doc/trunk/design/syn/S06.pod Sat Dec 23 12:50:23 2006
@@ -13,9 +13,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 21 Mar 2003
- Last Modified: 18 Dec 2006
+ Last Modified: 23 Dec 2006
Number: 6
- Version: 65
+ Version: 66
This document summarizes Apocalypse 6, which covers subroutines and the
@@ -1336,348 +1336,6 @@
Also, it is illegal to use placeholder variables in a block that already
has a signature, because the autogenerated signature would conflict with that.
-=head1 Built-in Types
-
-=head2 Native types
-
-[This stuff belongs in S02.]
-
-Values with these types autobox to their uppercase counterparts when
-you treat them as objects:
-
- bit single native bit
- int native signed integer
- uint native unsigned integer (autoboxes to Int)
- buf native buffer (finite seq of native ints or uints, no Unicode)
- num native floating point
- complex native complex number
- bool native boolean
-
-=head2 Undefined types
-
-These can behave as values or objects of any class, except that
-C<defined> always returns false. One can create them with the
-built-in C<undef> and C<fail> functions. (See S02 for how failures
-are handled.)
-
- Undef Undefined (can serve as a prototype object of any class)
- Whatever Wildcard (like undef, but subject to do-what-I-mean via MMD)
- Failure Failure (throws an exception if not handled properly)
-
-=head2 Immutable types
-
-Objects with these types behave like values, i.e. C<$x === $y> is true
-if and only if their types and contents are identical (that is, if
-C<$x.WHICH> eqv C<$y.WHICH>).
-
- Bit Perl single bit (allows traits, aliasing, undef, etc.)
- Int Perl integer (allows Inf/NaN, arbitrary precision, etc.)
- Str Perl string (finite sequence of Unicode characters)
- Num Perl number
- Complex Perl complex number
- Bool Perl boolean
- Exception Perl exception
- Code Base class for all executable objects
- Block Executable objects that have lexical scopes
- List Lazy Perl list (composed of Seq and Range parts)
- Seq Completely evaluated (hence immutable) sequence
- Range A pair of Ordered endpoints; gens lazy Seq in list context
- Set Unordered Seq that allows no duplicates (does KeyHash, but ro)
- Bag Unordered Seq that allows duplicates (does KeyHash, but ro)
- Junction Sets with additional behaviours
- Pair Seq of two elements that serves as a one-element Mapping
- Mapping Pairs with no duplicate keys
- Signature Function parameters (left-hand side of a binding)
- Capture Function call arguments (right-hand side of a binding)
- Blob An undifferentiated mass of bits
-
-=head2 Mutable types
-
-Objects with these types have distinct C<.WHICH> values that do not change
-even if the object's contents change.
-
- Scalar Perl scalar
- Array Perl array
- Hash Perl hash
- KeyHash Perl hash that autodeletes values matching default
- KeySet KeyHash of Bool (does Set in list/array context)
- KeyBag KeyHash of UInt (does Bag in list/array context)
- Buf Perl buffer (a stringish array of memory locations)
- IO Perl filehandle
- Routine Base class for all wrappable executable objects
- Sub Perl subroutine
- Method Perl method
- Submethod Perl subroutine acting like a method
- Macro Perl compile-time subroutine
- Regex Perl pattern
- Match Perl match, usually produced by applying a pattern
- Package Perl 5 compatible namespace
- Module Perl 6 standard namespace
- Class Perl 6 standard class namespace
- Role Perl 6 standard generic interface/implementation
- Object Perl 6 object
- Grammar Perl 6 pattern matching namespace
-
-A C<KeyHash> differs from a normal C<Hash> in how it handles default
-values. If the value of a C<KeyHash> element is set to the default
-value for the C<KeyHash>, the element is deleted. If undeclared,
-the default default for a C<KeyHash> is 0 for numeric types, C<False>
-for boolean types, and the null string for string and buffer types.
-A C<KeyHash> of a C<Object> type defaults to the undefined prototype
-for that type. More generally, the default default is whatever defined
-value an C<undef> would convert to for that value type. A C<KeyHash>
-of C<Scalar> deletes elements that go to either 0 or the null string.
-A C<KeyHash> also autodeletes keys for normal undef values (that is,
-those undefined values that do not contain an unthrown exception).
-
-A C<KeySet> is a C<KeyHash> of booleans with a default of C<False>.
-If you use the C<Hash> interface and increment an element of a
-C<KeySet> its value becomes true (creating the element if it doesn't
-exist already). If you decrement the element it becomes false and
-is automatically deleted. When not used as a C<Hash> (that is,
-when used as an C<Array> or list or C<Set> object) a C<KeySet>
-behaves as a C<Set> of its keys. (Since the only possible value of
-a C<KeySet> is the C<True> value, it need not be represented in
-the actual implementation with any bits at all.)
-
-A C<KeyBag> is a C<KeyHash> of C<UInt> with default of 0. If you
-use the C<Hash> interface and increment an element of a C<KeyBag>
-its value is increased by one (creating the element if it doesn't exist
-already). If you decrement the element the value is decreased by one;
-if the value goes to 0 the element is automatically deleted. When not
-used as a C<Hash> (that is, when used as an C<Array> or list or C<Bag>
-object) a C<KeyBag> behaves as a C<Bag> of its keys, with each key
-replicated the number of times specified by its corresponding value.
-(Use C<.kv> or C<.pairs> to suppress this behavior in list context.)
-
-=head2 Value types
-
-Explicit types are optional. Perl variables have two associated types:
-their "value type" and their "implementation type". (More generally, any
-container has an implementation type, including subroutines and modules.)
-The value type is stored as its C<of> property, while the implementation
-type of the container is just the object type of the container itself.
-
-The value type specifies what kinds of values may be stored in the
-variable. A value type is given as a prefix or with the C<of> keyword:
-
- my Dog $spot;
- my $spot of Dog;
-
-In either case this sets the C<of> property of the container to C<Dog>.
-
-Subroutines have a variant of the C<of> property, C<returns>, that sets
-the C<returns> property instead. The C<returns> property specifies a
-constraint (or perhaps coercion) to be enforced on the return value (either
-by explicit call to C<return> or by implicit fall-off-the-end return).
-This constraint, unlike the C<of> property, is not advertised as the
-type of the routine. You can think of it as the implicit type signature of
-the (possibly implicit) return statement. It's therefore available for
-type inferencing within the routine but not outside it. If no inner type
-is declared, it is assumed to be the same as the C<of> type, if declared.
-
- sub get_pet() of Animal {...} # of type, obviously
- our Animal sub get_pet() {...} # of type
- sub get_pet() returns Animal {...} # inner type
-
-A value type on an array or hash specifies the type stored by each element:
-
- my Dog @pound; # each element of the array stores a Dog
-
- my Rat %ship; # the value of each entry stores a Rat
-
-The key type of a hash may be specified as a shape trait--see S09.
-
-=head2 Implementation types
-
-The implementation type specifies how the variable itself is implemented. It is
-given as a trait of the variable:
-
- my $spot is Scalar; # this is the default
- my $spot is PersistentScalar;
- my $spot is DataBase;
-
-Defining an implementation type is the Perl 6 equivalent to tying
-a variable in Perl 5. But Perl 6 variables are tied directly at
-declaration time, and for performance reasons may not be tied with a
-run-time C<tie> statement unless the variable is explicitly declared
-with an implementation type that does the C<Tieable> role.
-
-However, package variables are always considered C<Tieable> by default.
-As a consequence, all named packages are also C<Tieable> by default.
-Classes and modules may be viewed as differently tied packages.
-Looking at it from the other direction, classes and modules that
-wish to be bound to a global package name must be able to do the
-C<Package> role.
-
-=head2 Hierarchical types
-
-A non-scalar type may be qualified, in order to specify what type of
-value each of its elements stores:
-
- my Egg $cup; # the value is an Egg
- my Egg @carton; # each elem is an Egg
- my Array of Egg @box; # each elem is an array of Eggs
- my Array of Array of Egg @crate; # each elem is an array of arrays of
Eggs
- my Hash of Array of Recipe %book; # each value is a hash of arrays of
Recipes
-
-Each successive C<of> makes the type on its right a parameter of the
-type on its left. Parametric types are named using square brackets, so:
-
- my Hash of Array of Recipe %book;
-
-actually means:
-
- my Hash[of => Array[of => Recipe]] %book;
-
-Because the actual variable can be hard to find when complex types are
-specified, there is a postfix form as well:
-
- my Hash of Array of Recipe %book; # HoHoAoRecipe
- my %book of Hash of Array of Recipe; # same thing
-
-The C<returns> form may be used in subroutines:
-
- my sub get_book ($key) returns Hash of Array of Recipe {...}
-
-Alternately, the return type may be specified within the signature:
-
- my sub get_book ($key --> Hash of Array of Recipe) {...}
-
-There is a slight difference, insofar as the type inferencer will
-ignore a C<returns> but pay attention to C<< --> >> or prefix type
-declarations, also known as the C<of> type. Only the inside of the
-subroutine pays attention to C<returns>.
-
-You may also specify the C<of> type as the C<of> trait:
-
- my Hash of Array of Recipe sub get_book ($key) {...}
- my sub get_book ($key) of Hash of Array of Recipe {...}
-
-=head2 Polymorphic types
-
-Anywhere you can use a single type you can use a set of types, for convenience
-specifiable as if it were an "or" junction:
-
- my Int|Str $error = $val; # can assign if $val~~Int or
$val~~Str
-
-Fancier type constraints may be expressed through a subtype:
-
- subset Shinola of Any where {.does(DessertWax) and .does(FloorTopping)};
- if $shimmer ~~ Shinola {...} # $shimmer must do both interfaces
-
-Since the terms in a parameter could be viewed as a set of
-constraints that are implicitly "anded" together (the variable itself
-supplies type constraints, and C<where> clauses or tree matching just
-add more constraints), we relax this to allow juxtaposition of
-types to act like an "and" junction:
-
- # Anything assigned to the variable $mitsy must conform
- # to the type Fish and either the Cat or Dog type...
- my Cat|Dog Fish $mitsy = new Fish but { int rand 2 ?? .does Cat
- !! .does Dog };
-
-=head2 Parameter types
-
-Parameters may be given types, just like any other variable:
-
- sub max (int @array is rw) {...}
- sub max (@array of int is rw) {...}
-
-=head2 Generic types
-
-Within a declaration, a class variable (either by itself or
-following an existing type name) declares a new type name and takes
-its parametric value from the actual type of the parameter it is
-associated with. It declares the new type name in the same scope
-as the associated declaration.
-
- sub max (Num ::X @array) {
- push @array, X.new();
- }
-
-The new type name is introduced immediately, so two such types in
-the same signature must unify compatibly if they have the same name:
-
- sub compare (Any ::T $x, T $y) {
- return $x eqv $y;
- }
-
-=head2 Return types
-
-On a scoped subroutine, a return type can be specified before or after
-the name. We call all return types "return types", but distinguish
-two kinds of return types, the C<inner> type and the C<of> type,
-because the C<of> type is normally an "official" named type and
-declares the official interface to the routine, while the C<inner>
-type is merely a constraint on what may be returned by the routine
-from the routine's point of view.
-
- our sub lay returns Egg {...} # inner type
- our Egg sub lay {...} # of type
- our sub lay of Egg {...} # of type
- our sub lay (--> Egg) {...} # of type
-
- my sub hat returns Rabbit {...} # inner type
- my Rabbit sub hat {...} # of type
- my sub hat of Rabbit {...} # of type
- my sub hat (--> Rabbit) {...} # of type
-
-If a subroutine is not explicitly scoped, it belongs to the current
-namespace (module, class, grammar, or package), as if it's scoped with
-the C<our> scope modifier. Any return type must go after the name:
-
- sub lay returns Egg {...} # inner type
- sub lay of Egg {...} # of type
- sub lay (--> Egg) {...} # of type
-
-On an anonymous subroutine, any return type can only go after the C<sub>
-keyword:
-
- $lay = sub returns Egg {...}; # inner type
- $lay = sub of Egg {...}; # of type
- $lay = sub (--> Egg) {...}; # of type
-
-but you can use a scope modifier to introduce an C<of> prefix type:
-
- $lay = my Egg sub {...}; # of type
- $hat = my Rabbit sub {...}; # of type
-
-Because they are anonymous, you can change the C<my> modifier to C<our>
-without affecting the meaning.
-
-The return type may also be specified after a C<< --> >> token within
-the signature. This doesn't mean exactly the same thing as C<returns>.
-The C<of> type is the "official" return type, and may therefore be
-used to do type inferencing outside the sub. The C<inner> type only
-makes the return type available to the internals of the sub so that
-the C<return> statement can know its context, but outside the sub we
-don't know anything about the return value, as if no return type had
-been declared. The prefix form specifies the C<of> type rather than
-the C<inner> type, so the return type of
-
- my Fish sub wanda ($x) { ... }
-
-is known to return an object of type Fish, as if you'd said:
-
- my sub wanda ($x --> Fish) { ... }
-
-I<not> as if you'd said
-
- my sub wanda ($x) returns Fish { ... }
-
-It is possible for the C<of> type to disagree with the C<inner> type:
-
- my Squid sub wanda ($x) returns Fish { ... }
-
-or equivalently,
-
- my sub wanda ($x --> Squid) returns Fish { ... }
-
-This is not lying to yourself--it's lying to the world. Having a
-different inner type is useful if you wish to hold your routine to
-a stricter standard than you let on to the outside world, for instance.
-
=head1 Properties and traits
Compile-time properties are called "traits". The