Author: larry
Date: Tue Apr 24 22:06:33 2007
New Revision: 14382


Clarifications suggested by TheDamian++
Killed "next METHOD", now just use nextsame etc.
Defined "lastcall" to allow return from final candidate.
Set up WHENCE mechanism for undefined prototype objects to autovivify lazily.

Modified: doc/trunk/design/syn/S06.pod
--- doc/trunk/design/syn/S06.pod        (original)
+++ doc/trunk/design/syn/S06.pod        Tue Apr 24 22:06:33 2007
@@ -2100,7 +2100,15 @@
 C<callsame> and C<callwith>, but a tail call is explicitly enforced;
 any code following the call will be unreached, as if a return had
 been executed there before calling into the destination routine.
-Within a method C<nextsame> is equivalent to C<next METHOD>.
+Within an ordinary method dispatch these functions treat the rest
+of the dispatcher's candidate list as the wrapped function, which
+generally works out to calling the same method in one of our parent
+(or older sibling) classes.  Likewise within a multiple dispatch the
+current routine may defer to candidates further down the candidate
+list.  Although not necessarily related by a class hierarchy, such
+later candidates are considered more generic and hence likelier
+to be able to handle various unforeseen conditions (perhaps).
 =head2 The C<&?ROUTINE> object

Modified: doc/trunk/design/syn/S12.pod
--- doc/trunk/design/syn/S12.pod        (original)
+++ doc/trunk/design/syn/S12.pod        Tue Apr 24 22:06:33 2007
@@ -12,9 +12,9 @@
   Maintainer: Larry Wall <[EMAIL PROTECTED]>
   Date: 27 Oct 2004
-  Last Modified: 13 Apr 2007
+  Last Modified: 24 Apr 2007
   Number: 12
-  Version: 46
+  Version: 47
 =head1 Overview
@@ -199,14 +199,14 @@
 Indirect object notation now requires a colon after the invocant,
 even if there are no arguments after the colon:
-    $handle.close
-    close $handle:
+    $handle.close;
+    close $handle:;
 To reject method call and only consider subs, simply omit the colon
 from the invocation line:
-    close($handle)
-    close $handle
+    close($handle);
+    close $handle;
 However, here the built-in B<IO> class defines C<method close is export ()>,
 which puts a C<multi sub close (IO)> in scope by default.  Thus if the
@@ -233,7 +233,7 @@
     .'+'               # same as +$_
 And in fact, if there is a choice between a unary prefix and a postfix
-operator, the indirect forms will choose the prefix operator.  See S03.
+operator, the quoted forms will choose the prefix operator.  See S03.
 Likewise, presuming that C<$op> does not name an ordinary method on
 C<$left>, this calls any arbitrary infix operator:
@@ -392,8 +392,10 @@
 visible to derived classes via inheritance.  A submethod is called
 only when a method call is dispatched directly to the current class.
-[Conjecture: there is some relationship between "submethod BUILD" and
-"method ^BUILD" that possibly rises to the level of a unifiable identity...]
+Conjecture: in order to catch spelling errors it is a compile-time
+warning to define a submethod in any class that does not inherit the
+corresponding method name from some base class.  (But note that the
+standard C<Object> class supplies a default C<BUILD> and C<new>.)
 =head1 Attributes
@@ -564,7 +566,7 @@
 The default C<BUILD> and C<BUILDALL> are inherited from C<Object>, so
 you need to write initialization routines only if you wish to modify
 the default behavior.  If the name of a named argument begins with a
-C<::> and corresponds to a class or role being built, the list value
+C<::> and corresponds to a (super)class or role being built, the list value
 of that argument is passed as a list of named arguments to that class
 or role's C<BUILD>.  (If the value of that argument is a closure
 instead of a list, that closure will be called to return a list.
@@ -572,6 +574,9 @@
 being initialized.)  In the absence of a class-labeled pair, all
 the arguments to C<bless> are passed to the C<BUILD>.
+    class Dog is Animal {...}
+    my $pet = :name<Fido>, Animal => [:blood<warm> :legs(4)] );
 You can clone an object, changing some of the attributes:
     $newdog = $olddog.clone(:trick<RollOver>);
@@ -661,9 +666,7 @@
-Any method can defer to the next candidate method in the list by
-saying C<next METHOD>.  Any method can stop the progression by saying
-C<last METHOD>.  The order and selection of the candidates may be
+The order and selection of the candidates may be
 specified by arguments to a pseudo-class known as C<WALK>:
@@ -681,10 +684,15 @@
     :omit(Selector)     # only classes that don't match selector
     :include(Selector)  # only classes that match selector
-In addition to C<next METHOD>, the special functions C<callsame>,
-C<callwith>, C<nextsame>, and C<nextwith> dispatch to the next
-candidate, possibly with a new argument list, and if the "next"
-variant is used, without returning:
+Any method can defer to the next candidate method in the list by
+the special functions C<callsame>, C<callwith>, C<nextsame>, and
+C<nextwith>.  The "same" variants reuse the original argument list
+passed to the current method, whereas the "with" variants allow a
+new argument list to be substituted for the rest of the candidates.
+The "call" variants dispatch to the rest of the candidates and return
+their values to the current method for subsequent processing, whereas
+while the "next" variants don't return, but merely defer to the rest
+of the candidate list:
     callsame;           # call with the original arguments (return here)
     callwith();         # call with no arguments (return here)
@@ -693,6 +701,21 @@
     nextwith();         # redispatch with no arguments (no return)
     nextwith(1,2,3);    # redispatch with a new set of arguments (no return)
+For dispatches using C<.> and C<.?>, the return value is the
+C<Capture> returned by the first method completed without deferring.
+(Such a return value may in fact be failure, but it still counts as a
+successful call from the standpoint of the dispatcher.)  Likewise the
+return value of C<.*> and C<.+> is a list of C<Captures> returned by
+those methods that ran to completion without deferring to next method.
+It is also possible to trim the candidate list so that the current
+call is considered the final candidate.  (This is implicitly the case
+already for the dispatch variants that want a single successful call.)
+For the multiple call variants, C<lastcall> will cause the dispatcher
+to throw away the rest of the candidate list, and the subsequent
+return from the current method will produce the final C<Capture>
+in the returned list.
 =head1 Parallel dispatch
 Any of the method call forms may be turned into a hyperoperator by
@@ -705,6 +728,10 @@
     @object».=meth(@args)  # calls mutator method on each
     @object»!meth(@args)   # calls private method on each
+The return value is a list with exactly the same number of elements
+as C<@object>.  Each such return value is a Capture or List of Captures
+as specified above for the non-hyper "dot" variants.
 Hyperoperators treat a junction as a scalar value, so saying:
@@ -756,10 +783,14 @@
 in a grammar by declaring a C<proto> C<token> or C<proto> C<rule>.  (Perl 6's
 grammar does this, for instance.)
-You can have multiple C<multi> variables in the same scope, and they
-all share the same storage location and type.  Usually these are
-declared by one C<proto> declaration at the top, and leaving the
-C<multi> implicit on the rest of the declarations.
+You can have multiple C<multi> variables of the same name in the
+same scope, and they all share the same storage location and type.
+Usually these are declared by one C<proto> declaration at the top,
+and leaving the C<multi> implicit on the rest of the declarations.
+You might do this when you suspect you'll have multiple declarations
+of the same variable name (such code might be produced by a macro
+or by a code generator, for instance) and you wish to suppress any
+possible warnings about redefinition.
 In contrast, C<multi> routines can have only one instance of the long
 name in any namespace, and that instance hides any outer (or less-derived)
@@ -896,9 +927,9 @@
 only on positional parameters.  Note that most builtins will map known
 named parameters to positional via a C<proto> declaration.
-Within a multiple dispatch, C<next METHOD> means to try the next best
+Within a multiple dispatch, C<nextsame> means to try the next best
 match, or next best default in case of tie, or the proto sub if there
-is one.  The C<nextsame> function has the same effect.
+is one.
 Attributes are tied to a particular class definition, so a multi method
 can only directly access the attributes of a class it's defined within
@@ -943,7 +974,7 @@
         method feed ($food) {
-            self.some_other_method;
+  $food);
@@ -999,7 +1030,7 @@
 Roles may have attributes:
     role Pet {
-        has $.collar = { };
+        has $.collar =;
         method id () { return $.collar.tag }
         method lose_collar () { undefine $.collar }
@@ -1113,6 +1144,12 @@
     proto method shake {...}
+(This declaration need not preceed the C<does> clause textually, since
+roles are not actually composed until the end of the class definition,
+at which point we know how which roles are to be composed together
+in a single logical operation, as well as how the class intends to
+override the roles.)
 The proto method will be called if the multi fails:
     proto method shake { warn "They couldn't decide" }
@@ -1135,13 +1172,16 @@
     $dog.bark();        # picks Dog role's bark method
     $tree.bark();       # picks Tree role's bark method
+If there is such a mechanism, it may only be used as a tie-breaker.
+Otherwise we break the normal polymorphism expectations.
 Run-time mixins are done with C<does> and C<but>.  The C<does> binary
 operator is a mutator that derives a new anonymous class (if necessary)
 and binds the object to it:
     $fido does Sentry
-The C<does> operator is non-associative, so this is a syntax error:
+The C<does> infix operator is non-associative, so this is a syntax error:
     $fido does Sentry does Tricks does TailChasing does Scratch;
@@ -1152,6 +1192,10 @@
     $fido does TailChasing;
     $fido does Scratch;
+And since it returns the left side, you can also say:
+    ((($fido does Sentry) does Tricks) does TailChasing) does Scratch;
 Unlike the compile-time role composition, each of these layers on a new
 mixin with a new level of inheritance, creating a new anonymous class
 for dear old Fido, so that a C<.chase> method from C<TailChasing> hides a
@@ -1161,12 +1205,14 @@
     $fido does (Sentry, Tricks, TailChasing, Scratch);
-This will level the playing field for collisions among the new set of roles,
-and guarantees the creation of no more than one more anonymous class.
-A role still can't conflict with itself, but it can hide its previous
-methods in the parent class, and the calculation of what conflicts
-is done again for the set of roles being mixed in.
+This will level the playing field for collisions among the new
+set of roles, and guarantees the creation of no more than one more
+anonymous class.  Such a role still can't conflict with itself, but it
+can hide its previous methods in the parent class, and the calculation
+of what conflicts is done again for the set of roles being mixed in.
+If you can't do compile-time composition, we strongly recommend this
+approach for run-time mixins since it approximates a compile-time
+composition at least for the new roles involved.
 A role applied with C<does> may be parameterized with an initializer
 in parentheses, but only if the role supplies exactly one attribute
@@ -1175,6 +1221,13 @@
     $fido does Wag($tail);
     $line does taint($istainted);
+The supplied initializer will be coerced to type of the attribute.
+Note that this initializer is in addition to any parametric type
+supplied in square brackets, which is considered part of the actual
+type name:
+    $myobj does Array[:of(Int)](@initial)
 The C<but> operator creates a copy and works on that.  It also knows
 how to generalize a particular enumerated value to its role.  So
@@ -1306,13 +1359,13 @@
 You can specify multiple method names:
-    has $.legs handles <walk run lope shake pee>;
+    has $.legs handles <walk run lope shake lift>;
 It's illegal to call the outer method unless the attribute
 has been initialized to an object of a type supporting the method,
 such as by:
-    has Tail $.tail handles 'wag' = { .new(|%_) };
+    has Tail $.tail handles 'wag' .= new(|%_);
 Note that putting a C<Tail> type on the attribute does not necessarily
 mean that the method is always delegated to the C<Tail> class.
@@ -1383,9 +1436,8 @@
                  StBernard => $woof,
                          * => $ruff,
-    method prefix:<~>( return "$.breed" )
-If the current object matches no Selector, a "C<next METHOD>" is
+If the current object matches no Selector, a "C<nextsame>" is
 automatically performed.
 =head1 Types and Subtypes
@@ -1658,11 +1710,11 @@
 By default, all methods and submethods that do not declare an explicit
 C<*%> parameter will get an implicit C<*%_> parameter declared for
 them whether they like it or not.  In other words, all methods allow
-unexpected named arguments, so that C<next METHOD> semantics work
+unexpected named arguments, so that C<nextsame> semantics work
 If you mark a class "C<is hidden>", it hides the current class
-from "C<next METHOD>" semantics, and incidentally suppresses the
+from "C<nextsame>" semantics, and incidentally suppresses the
 autogeneration of C<*%_> parameters.  Hidden classes may be visited
 as C<SUPER::>, but not via "C<next>".
@@ -1680,6 +1732,7 @@
     HOW         the metaclass object: "Higher Order Workings"
     WHEN        (reserved for events?)
     WHY         (reserved for documentation?)
+    WHENCE      autovivification closure
 These may be used either as methods or as unary operators:
@@ -1738,7 +1791,7 @@
 Class traits may include:
-    identifier    Dog-1.2.1-
+    identifier  { :name<Dog> :ver<1.2.1> :auth<> } 
         name      Dog
         version   1.2.1
@@ -1833,4 +1886,16 @@
 a method of a particular name if it's required and hasn't been supplied
 by the class or one of its roles.
+Conjecture: The C<WHENCE> property of an object is its autovivifying
+closure.  Any undefined prototype object may carry such a closure that
+can lazily create an object of the appropriate type.  For instance,
+a C<CANDO> routine, instead of creating a C<Dog> object directly,
+could instead return something like:
+    Dog but WHENCE({ .new(:name<Fido>) })
+which runs the closure if the object ever needs to be autovivified.
+The closure can capture whatever initializers were available in the
+original lexical scope.
 =for vim:set expandtab sw=4:

Reply via email to