Author: larry
Date: Thu May 25 11:21:16 2006
New Revision: 9307

Modified:
   doc/trunk/design/syn/S06.pod

Log:
Clarifying the distinction between the "of" and "where" return types.


Modified: doc/trunk/design/syn/S06.pod
==============================================================================
--- doc/trunk/design/syn/S06.pod        (original)
+++ doc/trunk/design/syn/S06.pod        Thu May 25 11:21:16 2006
@@ -13,9 +13,9 @@
 
   Maintainer: Larry Wall <[EMAIL PROTECTED]>
   Date: 21 Mar 2003
-  Last Modified: 14 May 2006
+  Last Modified: 24 May 2006
   Number: 6
-  Version: 35
+  Version: 36
 
 
 This document summarizes Apocalypse 6, which covers subroutines and the
@@ -288,7 +288,7 @@
 including Unicode characters. For example:
 
     sub infix:<(c)> ($text, $owner) { return $text but Copyright($owner) }
-    method prefix:<±> (Num $x) returns Num { return +$x | -$x }
+    method prefix:<±> (Num $x --> Num) { return +$x | -$x }
     multi sub postfix:<!> (Int $n) { $n < 2 ?? 1 !! $n*($n-1)! }
     macro circumfix:«<!-- -->» ($text) is parsed / .*? / { "" }
 
@@ -1238,7 +1238,7 @@
 
 Note that unlike a sub declaration, a regex-embedded signature has no
 associated "returns" syntactic slot, so you have to use C<< --> >>
-within the signature to specify the type of the signature, or match as
+within the signature to specify the C<of> type of the signature, or match as
 an arglist:
 
     :(Num, Num --> Coord)
@@ -1395,15 +1395,21 @@
 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<returns> or
-C<of> keywords:
+variable. A value type is given as a prefix or with the C<of> keyword:
 
     my Dog $spot;
-    my $spot returns Dog;
     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 to be checked upon calling C<return> that, unlike the C<of>
+property, is not advertized as the type of the routine:
+
     our Animal sub get_pet() {...}
     sub get_pet() returns Animal {...}
     sub get_pet() of Animal {...}
@@ -1431,6 +1437,13 @@
 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
@@ -1449,19 +1462,16 @@
 
 actually means:
 
-    my Hash[returns => Array[returns => Recipe]] %book; 
+    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
-    my %book returns Hash of Array of Recipe;   # same thing
 
-The C<returns> form is more commonly seen in subroutines:
+The C<returns> form may be used in subroutines:
 
-    my Hash of Array of Recipe sub get_book ($key) {...}
-    my sub get_book ($key) of Hash of Array of Recipe {...}
     my sub get_book ($key) returns Hash of Array of Recipe {...}
 
 Alternately, the return type may be specified within the signature:
@@ -1469,8 +1479,14 @@
     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.
-Only the inside of the subroutine pays attention to C<returns>.
+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
 
@@ -1524,42 +1540,53 @@
 =head2 Return types
 
 On a scoped subroutine, a return type can be specified before or
-after the name:
-
-    our Egg sub lay {...}
-    our sub lay returns Egg {...}
-
-    my Rabbit sub hat {...}
-    my sub hat returns Rabbit {...}
+after the name.  We call all return types "return types", but distinguish
+two kinds of return type, the C<where> type from the C<of> type, because
+the C<of> type must be an "official" named type, while the C<where> type
+is merely applied as a constraint to what may be returned by the routine.
+
+    our Egg sub lay {...}              # of type
+    our sub lay returns Egg {...}      # where type
+    our sub lay of Egg {...}           # of type
+    our sub lay (--> Egg) {...}                # of type
+
+    my Rabbit sub hat {...}            # of type
+    my sub hat returns Rabbit {...}    # where 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 {...}
+    sub lay returns Egg {...}          # where 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 {...};
+    $lay = sub returns Egg {...};      # where type
+    $lay = sub of Egg {...};           # of type
+    $lay = sub (--> Egg) {...};                # of type
 
-but you can use a scope modifier to introduce a return type:
+but you can use a scope modifier to introduce an C<of> prefix type:
 
-    $lay = my Egg sub {...};
-    $hat = my Rabbit sub {...};
+    $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
-arrow form is an "official" return type, and may be used to do type
-inferencing outside the sub.  The C<returns> form 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 actually corresponds to the C<< --> >> semantics rather than the
-C<returns> semantics, so the return type of
+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<where> 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<where> type, so the return type of
 
     my Fish sub wanda ($x) { ... }
 
@@ -1571,7 +1598,7 @@
 
     my sub wanda ($x) returns Fish { ... }
 
-It is possible for the outer type to disagree with the inner type:
+It is possible for the C<of> type to disagree with the C<where> type:
 
     my Squid sub wanda ($x) returns Fish { ... }
 
@@ -1623,7 +1650,11 @@
 
 =item C<returns>/C<is returns>
 
-The type returned by a subroutine.
+The C<where> type constraint that a routine imposes in its return value.
+
+=item C<of>/C<is of>
+
+The C<of> type that is the official return type of the routine.
 
 =item C<will do>
 

Reply via email to