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