Author: larry
Date: Wed Apr  5 15:37:22 2006
New Revision: 8562

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

Log:
Got rid of identity and trivial properties in favor of MMD definitions.


Modified: doc/trunk/design/syn/S03.pod
==============================================================================
--- doc/trunk/design/syn/S03.pod        (original)
+++ doc/trunk/design/syn/S03.pod        Wed Apr  5 15:37:22 2006
@@ -14,7 +14,7 @@
   Date: 8 Mar 2004
   Last Modified: 5 Apr 2006
   Number: 3
-  Version: 15
+  Version: 16
 
 =head1 Operator renaming
 
@@ -198,9 +198,10 @@
 
 =head1 Reduction operators
 
-The other metaoperator in Perl 6 is the reduction operator.  Any infix
-operator can be surrounded by square brackets in term position to create
-a list operator that reduces using that operation:
+The other metaoperator in Perl 6 is the reduction operator.  Any
+infix operator (except for non-associating operators and assignment
+operators) can be surrounded by square brackets in term position to
+create a list operator that reduces using that operation:
 
     [+] 1, 2, 3;      # 1 + 2 + 3 = 6
     my @a = (5,6);
@@ -216,30 +217,84 @@
 
     [<] 1, 3, 5;      # 1 < 3 < 5
 
-If no arguments are given, and if the infix operator defines
-an "identity" value property, that identity value is returned.
-(For instance, C<[*] @list> must return C<1> when C<@list> is empty.)
-In the absence of an identity value, the reduce metaoperator calls
-C<fail> (either returning C<undef>, or throwing an exception if C<use
-fatal> is in effect).
-
-If exactly one argument is given, it is returned by default.  However,
-this default doesn't make sense for an operator like C<< < >> that
-doesn't return the same type as it takes, so these kinds of operators
-overload the single-argument case to return something more meaningful.
-All the comparison operators return truth in this case.  This behavior
-is triggered by storage of the "trivial" value property on the infix
-operator.  (The trivial property is also returned for 0 arguments.)
-
-The identity and trivial properties are stored on the most general
-default variant of the infix operator, if there is more than
-one variant.  (Perhaps they can be returned simply by calling C<< infix:<op>() 
>> and C<< infix:<op>($x) >>, respectively, letting the defaults handle it.)
+If fewer than two arguments are given, one MMD attempt is made to
+dispatch to the operator anyway with whatever arguments are given.
+If this MMD dispatch succeeds, the result becomes the result of the
+of the reduce.
+
+Otherwise, if the MMD dispatch fails, then if there is one argument,
+that argument is returned.  However, this default doesn't make sense
+for an operator like C<< < >> that doesn't return the same type as it
+takes, so these kinds of operators overload the single-argument case
+to return something more meaningful.  All the comparison operators
+return a boolean for either 1 or 0 arguments.  Negated operators,
+return Bool::False, and all the rest return Bool::True.
+
+If no arguments were given, and the dispatch to the 0-ary form fails,
+the reduce as a whole fails.  Operators that wish to specify an identity
+value should do so by overloading the 0-ary variant.  Among the builtin
+operators, infix:<+>() returns 0 and infix:<*>() returns 1.  Note that,
+while the single argument form can MMD dispatch based on the type of
+the single argument, the 0-argument form cannot.
 
 This metaoperator can also be used on the semicolon second-dimension
 separator:
 
     [[;] 1,2,3]   # equivalent to [1;2;3]
 
+Builtin infix operators specify the following identity operations:
+
+    multi sub infix:<**> ()     { 1 }   # arguably nonsensical
+    multi sub infix:<*> ()      { 1 }
+    multi sub infix:</> ()      { ??? } # reduce is nonsensical
+    multi sub infix:<%> ()      { ??? } # reduce is nonsensical
+    multi sub infix:<x> ()      { ??? } # reduce is nonsensical
+    multi sub infix:<xx> ()     { ??? } # reduce is nonsensical
+    multi sub infix:<+&> ()     { +^0 } # -1 on 2's complement machine
+    multi sub infix:{'+<'} ()   { ??? } # reduce is nonsensical
+    multi sub infix:{'+>'} ()   { ??? } # reduce is nonsensical
+    multi sub infix:<~&> ()     { ??? } # sensical but 1's length indeterminate
+    multi sub infix:{'~<'} ()   { ??? } # reduce is nonsensical
+    multi sub infix:{'~>'} ()   { ??? } # reduce is nonsensical
+    multi sub infix:<+> ()      { 0 }
+    multi sub infix:<-> ()      { 0 }
+    multi sub infix:<~> ()      { '' }
+    multi sub infix:<+|> ()     { 0 }
+    multi sub infix:<+^> ()     { 0 }
+    multi sub infix:<~|> ()     { '' } # length indeterminate but 0's default
+    multi sub infix:<~^> ()     { '' } # length indeterminate but 0's default
+    multi sub infix:<&> ()      { all() }
+    multi sub infix:<|> ()      { any() }
+    multi sub infix:<^> ()      { one() }
+    multi sub infix:<!=> ($x?)  { Bool::False }
+    multi sub infix:<==> ($x?)  { Bool::True }
+    multi sub infix:{'<'} ($x?) { Bool::True }
+    multi sub infix:{'<='} ($x?) { Bool::True }
+    multi sub infix:{'>'} ($x?) { Bool::True }
+    multi sub infix:{'>='} ($x?) { Bool::True }
+    multi sub infix:<~~> ($x?)  { Bool::True }
+    multi sub infix:<!~> ($x?)  { Bool::False }
+    multi sub infix:<eq> ($x?)  { Bool::True }
+    multi sub infix:<ne> ($x?)  { Bool::False }
+    multi sub infix:<lt> ($x?)  { Bool::True }
+    multi sub infix:<le> ($x?)  { Bool::True }
+    multi sub infix:<gt> ($x?)  { Bool::True }
+    multi sub infix:<ge> ($x?)  { Bool::True }
+    multi sub infix:<=:=> ($x?) { Bool::True }
+    multi sub infix:<===> ($x?) { Bool::True }
+    multi sub infix:<&&> ()     { Bool::True }
+    multi sub infix:<||> ()     { Bool::False }
+    multi sub infix:<^^> ()     { Bool::False }
+    multi sub infix:<//> ()     { undef }
+    multi sub infix:<,> ()      { () }
+    multi sub infix:<¥> ()      { [] }
+
+Any builtin operator not mentioned here does not have an identity
+value.  User-defined operators may of course define their own
+identity values.  Math packages wishing to find the identity value
+for an operation can call C<infix:{$opname}()> to discover it.
+(There is no explicit identity property.)
+
 =head1 Junctive operators
 
 C<|>, C<&>, and C<^> are no longer bitwise operators (see L</Operator
@@ -328,7 +383,7 @@
 
 as is this:
 
-    my $args = \(@foo, @bar);   # construct List object
+    my $args = \(@foo, @bar);    # construct List object
     push *$args;
 
 In list context, a scalar reference to an array does not flatten.  Hence
@@ -461,26 +516,26 @@
 
 Perl 6 has 22 precedence levels (which is fewer than Perl 5):
 
-    terms              42 "eek" $x /abc/ (1+2) a(1) :by(2) .meth listop
-    method postfix     . .+ .? .* .() .[] .{} .«» .=
-    autoincrement      ++ --
-    exponentiation     **
-    symbolic unary     ! + - ~ ? * ** +^ ~^ ?^ \ ^
-    multiplicative     * / % x xx +& +< +> ~& ~< ~>
-    additive           + - ~ +| +^ ~| ~^
-    junctive and (all) &
-    junctive or (any)  | ^
-    named unary                rand sleep abs etc.
-    nonchaining binary but does cmp <=> .. ^.. ..^ ^..^ ff ^ff ff^ ^ff^ fff 
^fff etc.
-    chaining binary    != == < <= > >= ~~ !~ eq ne lt le gt ge =:= ===
-    tight and          &&
-    tight or           || ^^ //
-    ternary            ?? !!
-    assignment         = := ::= += -= **= xx= etc. (and also =>)
-    list item separator        , ¥
-    list op (rightward)        <== print push any all true not etc.
-    pipe forward       ==>
-    loose and          and
-    loose or           or xor err
-    expr terminator    ; {} as control block, statement modifiers
+    terms               42 "eek" $x /abc/ (1+2) a(1) :by(2) .meth listop
+    method postfix      . .+ .? .* .() .[] .{} .«» .=
+    autoincrement       ++ --
+    exponentiation      **
+    symbolic unary      ! + - ~ ? * ** +^ ~^ ?^ \ ^
+    multiplicative      * / % x xx +& +< +> ~& ~< ~>
+    additive            + - ~ +| +^ ~| ~^
+    junctive and (all)  &
+    junctive or (any)   | ^
+    named unary         rand sleep abs etc.
+    nonchaining binary  but does cmp <=> .. ^.. ..^ ^..^ ff ^ff ff^ ^ff^ fff 
^fff etc.
+    chaining binary     != == < <= > >= ~~ !~ eq ne lt le gt ge =:= ===
+    tight and           &&
+    tight or            || ^^ //
+    ternary             ?? !!
+    assignment          = := ::= += -= **= xx= etc. (and also =>)
+    list item separator , ¥
+    list op (rightward) <== print push any all true not etc.
+    pipe forward        ==>
+    loose and           and
+    loose or            or xor err
+    expr terminator     ; {} as control block, statement modifiers
 

Reply via email to