Author: larry Date: Sat Jul 15 00:15:51 2006 New Revision: 10217 Modified: doc/trunk/design/syn/S03.pod
Log: More clarifications, many suggested by dduncan++. Modified: doc/trunk/design/syn/S03.pod ============================================================================== --- doc/trunk/design/syn/S03.pod (original) +++ doc/trunk/design/syn/S03.pod Sat Jul 15 00:15:51 2006 @@ -12,9 +12,9 @@ Maintainer: Larry Wall <[EMAIL PROTECTED]> Date: 8 Mar 2004 - Last Modified: 14 Jul 2006 + Last Modified: 15 Jul 2006 Number: 3 - Version: 47 + Version: 48 =head1 Changes to existing operators @@ -29,7 +29,8 @@ =item * C<< -> >> becomes C<.>, like the rest of the world uses. =item * The string concatenation C<.> becomes C<~>. Think of it as -"stitching" the two ends of its arguments together. +"stitching" the two ends of its arguments together. String append +is likewise C<~=>. =item * All postfix operators that do not start with a dot also have an alternate form that does. (The converse does not hold--just because @@ -50,17 +51,31 @@ so you need C<$($foo[bar])> to mean the other way. =item * Bitwise operators get a data type prefix: C<+>, C<~>, or C<?>. -For example, C<|> becomes either C<+|> or C<~|> or C<?|>, depending on -whether the operands are to be treated as numbers, strings, or boolean -values. Left shift C< << > becomes C< +< >, and correspondingly with -right shift. Unary C<~> becomes either C<+^> or C<~^> or C<?^>, since a -bitwise NOT is like an exclusive-or against solid ones. Note that C<?^> -is functionally identical to C<!>. C<?|> differs from C<||> in that -C<?|> always returns a standard boolean value (either 1 or 0), whereas -C<||> return the actual value of the first of its arguments that is -true. Bitwise string operators may only be applied to C<Buf> types or -similar compact integer arrays, and treat the entire chunk of memory -as a single huge integer. +For example, Perl 5's C<|> becomes either C<+|> or C<~|> or C<?|>, +depending on whether the operands are to be treated as numbers, +strings, or boolean values. Perl 5's left shift C< << > becomes +C< +< >, and correspondingly with right shift. Perl 5's unary C<~> +(one's complement) becomes either C<+^> or C<~^> or C<?^>, since a +bitwise NOT is like an exclusive-or against solid ones. Note that +C<?^> is functionally identical to C<!>, but conceptually coerces to +boolean first and then flips the bit. Please use C<!> instead. + +C<?|> is a logical OR but differs from C<||> in that C<?|> always +evaluates both sides and returns a standard boolean value. That is, +it's equivalent to C<< ?$a + ?$b != 0 >>. Another difference is that +it has the precedence of an additive operator. + +C<?&> is a logical AND but differs from C<&&> in that C<?&> always +evaluates both sides and returns a standard boolean value. That is, +it's equivalent to C<< ?$a * ?$b != 0 >>. Another difference is that +it has the precedence of a multiplicative operator. + +Bitwise string operators (those starting with C<~>) may only be +applied to C<Buf> types or similar compact integer arrays, and treat +the entire chunk of memory as a single huge integer. They differ from +the C<+> operators in that the C<+> operators would try to convert +the string to a number first on the assumption that the string was an +ASCII representation of a number. =item * C<x> splits into two operators: C<x> (which concatenates repetitions of a string to produce a single string), and C<xx> (which creates a list of @@ -108,7 +123,7 @@ ($a,$b,$c) = 1,2,3; -since list assignment operators are of assignment precedence to their left. +since assignment operators are tighter than comma to their left. =item * The scalar assignment operator still parses as it did before, so @@ -379,7 +394,8 @@ in terms of C<cmp>, so C<$a leg $b> is now defined as C<~$a cmp ~$b>. The sort operator still defaults to C<cmp> rather than C<leg>. The C<< <=> >> operator's semantics are unchanged except that it returns -an C<Order> value as described above. +an C<Order> value as described above. In other words, C<< $a <=> $b >> +is now equivalent to C<+$a cmp +$b>. =item * Binary C<< => >> is no longer just a "fancy comma". It now constructs a C<Pair> object that can, among other things, be used to @@ -393,8 +409,9 @@ is much more general now. See "Smart matching" below for details. (To catch "brainos", the Perl 6 parser defines an C<< infix:<=~> >> macro which always fails at compile time with a message directing the user either to use C<~~> -or C<~=> instead, or to put a space between if they really wanted to assign -a stringified value.) +or C<~=> (string append) instead, or to put a space between if they +really wanted to assign a stringified value.) A negated smart match is +spelled C<!~~>. =item * "Unary" C<.> calls its single argument (which must a postfix operator) on C<$_>. (It's not really a unary operator, so we put it in quotes.) @@ -582,11 +599,22 @@ =head1 Meta operators Perl 6's operators have been greatly regularized, for instance, by -consistently prefixing bitwise, stringwise, and boolean operators -with C<+>, C<~> and C<?> respectively to indicate operator type. -But that's just naming conventions. In addition to those naming -conventions, Perl 6 has four standard metaoperators for turning a -given standard operator into a related but more powerful operator. +consistently prefixing numeric, stringwise, and boolean operators +with C<+>, C<~> and C<?> respectively to indicate whether the bitwise +operation is done on a number, a string, or a single bit. +But that's just a naming convention, and if you wanted to add a new +bitwise C<¬> operator, you'd have the add the C<+¬>, C<~¬>, and C<?¬> +operators yourself. Similarly, the carets that exclude the endpoints +on ranges are there by convention only. + +In contrast to that, Perl 6 has four 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 +metaoperators 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. Note: spaces are never allowed between any metaoperator and the operator it's modifying, because all operators including modified @@ -608,19 +636,23 @@ Existing forms ending in C<=> may not be modified with this metaoperator. +Regardless of the precedence of the base operator, the precedence +of any assignment operators is forced to be the same as that of +ordinary assignment. + =head2 Negated relational operators. Any infix relational operator may be transformed into its negative -by prefixing with C<!>. A few of these have traditional shortcuts: +by prefixing with C<!>. A couple of these have traditional shortcuts: Full form Shortcut --------- -------- !== != !eq ne - !~~ !~ but most of them do not: + !~~ !< !>= !ge @@ -631,8 +663,7 @@ To avoid visual confusion with the C<!!> operator, you may not modify any operator already beginning with C<!>. -[Conjecture: we could probably do away with C<!~>, but probably not -C<!=> or C<ne>.] +The precedence of any negated operator is the same as the base operator. =head2 Hyper operators @@ -644,6 +675,8 @@ blunt end (except for postfix operators, which must still follow postfix spacing rules, but do allow for an additional dot before the "hyper"). +The precedence of any hyperoperator is the same as its base operator. +This means that you must parenthesize your lists for most operators. For example: (1,1,2,3,5) »+« (1,2,3,5,8); # (2,3,5,8,13) @@ -748,7 +781,8 @@ As with the all metaoperators, space is not allowed inside. The whole thing parses as a single token. -A reduction operator really is a list operator, and is invoked as one. +A reduction operator has the same precedence as a list operator. In fact, +a reduction operator really is a list operator, and is invoked as one. Hence, you can implement a reduction operator in one of two ways. Either you can write an explicit list operator: @@ -855,22 +889,26 @@ [&]() # all() [|]() # any() [^]() # one() - [!=]() # Bool::False (also for 1 arg) + [!==]() # Bool::False (also for 1 arg) [==]() # Bool::True (also for 1 arg) [<]() # Bool::True (also for 1 arg) [<=]() # Bool::True (also for 1 arg) [>]() # Bool::True (also for 1 arg) [>=]() # Bool::True (also for 1 arg) [~~]() # Bool::True (also for 1 arg) - [!~]() # Bool::False (also for 1 arg) + [!~~]() # Bool::False (also for 1 arg) [eq]() # Bool::True (also for 1 arg) - [ne]() # Bool::False (also for 1 arg) + [!eq]() # Bool::False (also for 1 arg) [lt]() # Bool::True (also for 1 arg) [le]() # Bool::True (also for 1 arg) [gt]() # Bool::True (also for 1 arg) [ge]() # Bool::True (also for 1 arg) [=:=]() # Bool::True (also for 1 arg) + [!=:=]() # Bool::False (also for 1 arg) [===]() # Bool::True (also for 1 arg) + [!===]() # Bool::False (also for 1 arg) + [eqv]() # Bool::True (also for 1 arg) + [!eqv]() # Bool::False (also for 1 arg) [&&]() # Bool::True [||]() # Bool::False [^^]() # Bool::False @@ -971,6 +1009,22 @@ it indicates to the compiler that there is no coupling between loop iterations and they can be run in any order or even in parallel. +Use of negative operators with syntactically recognizable junctions may +produce a warning on code that works differently in English than in Perl. +Instead of writing + + if $a != 1 | 2 | 3 {...} + +you need to write + + if not $a == 1 | 2 | 3 {...} + +However, this is only a syntactic warning, and + + if $a != $b {...} + +will not complain if $b happens to contain a junction at runtime. + =head1 Chained comparisons Perl 6 supports the natural extension to the comparison operators, @@ -1194,22 +1248,24 @@ my \$capture := func(); push [,] =$capture; -=head1 Piping operators +=head1 Feed operators The new operators C<< ==> >> and C<< <== >> are akin to UNIX pipes, but -work with functions that accept and return lists. For example, +work with functions that accept and return lists. Since these lists are +composed of discrete objects and not liquids, we call these I<feed> operators +rather than pipes. For example, @result = map { floor($^x / 2) }, grep { /^ \d+ $/ }, @data; -can also now be written: +can also now be written with rightward feeds as: @data ==> grep { /^ \d+ $/ } ==> map { floor($^x / 2) } ==> @result; -or: +or with leftward feeds as: @result <== map { floor($^x / 2) } <== grep { /^ \d+ $/ } @@ -1320,28 +1376,46 @@ Perl 6 has 22 precedence levels (which is fewer than Perl 5): - terms 42 3.14 "eek" $x /abc/ (1+2) a(1) :by(2) .meth listop - method postfix . .+ .? .* .() .[] .{} .<> .«» .:: .= + terms 42 3.14 "eek" qq["foo"] [1,2,3] {...} \(@a,$b,%c) + $x @y %z /abc/ MyType @@multidim $^a + (1+2) a(1) :by(2) :!verbose :(Dog $self:) + .meth with implicit invocant + listops leftward + method postfix .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^ autoincrement ++ -- exponentiation ** symbolic unary ! + - ~ ? $ @ % & +^ ~^ ?^ \ ^ = - multiplicative * / % x xx +& +< +> ~& ~< ~> - additive + - ~ +| +^ ~| ~^ + multiplicative * / % x xx +& +< +> ~& ~< ~> ?& + additive + - ~ +| +^ ~| ~^ ?| ?^ junctive and (all) & junctive or (any) | ^ named unary rand sleep abs etc. -e -r -w -x etc. - nonchaining binary but does cmp <=> .. ^.. ..^ ^..^ ff ^ff ff^ ^ff^ fff ^fff etc. - chaining binary != == < <= > >= ~~ !~ eq ne lt le gt ge =:= === + nonchaining binary but does <=> leg cmp + .. ^.. ..^ ^..^ + ff ^ff ff^ ^ff^ + fff ^fff fff^ ^fff^ + chaining binary != == < <= > >= + eq ne lt le gt ge + ~~ =:= === eqv + !== !~~ !eq !=:= !=== !eqv etc. tight and && tight or || ^^ // ternary ?? !! - assignment => := ::= += -= **= xx= .= etc. (also = with simple lvalues) + assignment := ::= => + (also = with simple lvalues) + += -= **= xx= .= etc. loose unary true not - list ops , print push any all '...' etc. (also list assignment) + list ops , print push say join split substr open etc. + any all one none + die fail warn + !!! ... ??? + [+] [*] [<] [,] [\+] [\*] etc. + (also = as list assignment) list infix ¥ <== ==> loose and and loose or or xor err expr terminator ; {} as control block, statement modifiers + unmatched ), ], }, etc. Comma is the only listop that is allowed to occur where an operator is expected. All other listops function as a term within the list to the left.