Author: lwall
Date: 2010-03-15 18:39:10 +0100 (Mon, 15 Mar 2010)
New Revision: 30092
Modified:
docs/Perl6/Spec/S03-operators.pod
Log:
[S03] add Z to go with X metaop
note that X and Z desugar to higher-order methods, crosswith and zipwith
speculate about how to zip/cross dwimmily with non-identical ops
possibly creating a real use case for surreal precedence :)
Modified: docs/Perl6/Spec/S03-operators.pod
===
--- docs/Perl6/Spec/S03-operators.pod 2010-03-15 17:02:04 UTC (rev 30091)
+++ docs/Perl6/Spec/S03-operators.pod 2010-03-15 17:39:10 UTC (rev 30092)
@@ -15,8 +15,8 @@
Created: 8 Mar 2004
-Last Modified: 2 Mar 2010
-Version: 196
+Last Modified: 15 Mar 2010
+Version: 197
=head1 Overview
@@ -1732,6 +1732,9 @@
1,2 Z 3,4 # (1,3),(2,4)
+The C operator is actually a degenerate case of the C zipwith
+metaoperator (see L below).
+
=item *
C<< infix: >>, the minmax operator
@@ -3841,14 +3844,16 @@
operators yourself. Similarly, the carets that exclude the endpoints
on ranges are there by convention only.
-In contrast to that, Perl 6 has seven standard metaoperators for
+In contrast to that, Perl 6 has eight standard metaoperators for
turning a given existing operator into a related operator that is
more powerful (or at least differently powerful). These differ from a
mere naming convention in that Perl automatically generates these new
operators from user-defined operators as well as from builtins.
In fact, you're not generally supposed to define the individual
metaoperations--their semantics are supposed to be self-evident by
-the transformation of the base operator.
+the transformation of the base operator. In other words, these
+metaoperators are really just shorthand for higher-order functions
+(functions that take other functions as arguments).
Constructs containing metaoperators are considered "metatokens",
by which we mean that they are not subject to ordinary longest-token
@@ -4396,19 +4401,33 @@
=head2 Cross operators
The cross metaoperator, C, may be followed by any infix operator.
-It applies the
-modified operator across all groupings of its list arguments as returned
-by the ordinary C<< infix: >> operator. All
-generated cross operators are of list infix precedence, and are list
associative.
+It applies the modified operator across all groupings of its list
+arguments as returned by the ordinary C<< infix: >> operator.
+All generated cross operators are of list infix precedence, and are
+list associative.
The string concatenating form is:
- X~ <1 2> # 'a1', 'a2', 'b1', 'b2'
+ X~ 1,2 # 'a1', 'a2', 'b1', 'b2'
-The C operator desugars to something like:
+The C operator desugars to:
-[~]«( X, <1 2> ) # 'a1', 'a2', 'b1', 'b2'
+(; 1,2).crosswith(&[~])
+which in turn means
+
+(; 1,2).cross.slice.map { .reduce(&[~]) }
+
+And
+
+ X~ 1,2 X+ 3,4
+
+might mean
+
+(; 1,2; 3,4).cross.slice.map { .reduce(&[~],&[+]) }
+
+(But see below.)
+
The list concatenating form, C, when used like this:
X, 1,2 X,
@@ -4424,7 +4443,8 @@
('b', 2, 'x'),
('b', 2, 'y')
-The list form is common enough to have a shortcut, the ordinary infix
+The C operator is perhaps more clearly written as C. However,
+this list form is common enough to have a shortcut, the ordinary infix
C operator described earlier.
For the general form, any existing, non-mutating infix operator
@@ -4447,8 +4467,85 @@
Note that only the first term of an C operator may reasonably be
an infinite list.
-Multidimensional lists should be handled properly.
+All lists are assumed to be flat; multidimensional lists are
+handled by treating the first dimension as the only dimension.
+=head2 Zip operators
+
+The zip metaoperator, C, may be followed by any infix operator.
+It applies the modified operator across all groupings of its list
+arguments as returned by the ordinary C<< infix: >> operator.
+All generated zip operators are of list infix precedence, and are
+list associative.
+
+The string concatenating form is:
+
+ Z~ 1,2 # 'a1', 'b2'
+
+The C operator desugars to:
+
+(; 1,2).zipwith(&[~])
+
+which in turn means
+
+(; 1,2).zip.slice.map { .reduce(&[~]) }
+
+And
+
+ Z~ 1,2 Z+ 3,4 # 'a4', 'b6'
+
+would mean
+
+(; 1,2; 3,4).zip.slice.map { .reduce(&[~],&[+]) }
+
+implying that multi-function reduce knows how to compare the precedence
+of its operator arguments somehow. That seems unreasonable. The clean
+way to solve this might involve giving C and C metaoperators a
+subprecedence within listop precedence corresponding to the original
+operator's precedence, so that C and C actually have different
+precedences within listop precedence. Then the above would parse as if
+you'd said C<< Z~ ( 1,2 Z+ 3,4> ) >>, but the lists would still
+parse at list infix precedence, with comma tighter than t