=encoding utf8

=head1 TITLE

Synopsis 3: Summary of Perl 6 Operators

=head1 AUTHOR

Luke Palmer <luke@luqui.org>

=head1 VERSION

  Maintainer: Larry Wall <larry@wall.org>
  Date: 8 Mar 2004
  Last Modified: 22 Feb 2005
  Number: 3
  Version: 5

=head1 Operator renaming

Several operators have been given new names to increase clarity and better
Huffman-code the language:

=over

=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.

=item * Unary C<~> now imposes a string context on its argument,
and C<+> imposes a numeric context (as opposed to being a no-op
in Perl 5).  Along the same lines, C<?> imposes a boolean context,
and C<*> imposes a list context.

=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.

=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 
repetitions of a list or scalar).

=item * Trinary C<? :> becomes C<?? ::>.

=item * C<qw{ ... }> gets a synonym: C< < ... > >, and an interpolating
variant, C<«...»>.
For those still living without the blessings of Unicode, that can also be
written: C<<< << ... >> >>>.

=item * The scalar comma C<,> now constructs a list reference of its
operands.  You have to use a C<[-1]> subscript to get the last one.

=back

=head1 New operators

=over

=item * Binary C<//> is just like C<||>, except that it tests its left
side for definedness instead of truth. There is a low-precedence form,
too: C<err>.

=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
pass named arguments to functions.  It provides scalar context to both sides.

=item * C<^^> is the high-precedence version of C<xor>.

=item * C<=~> becomes the "smart match" operator C<~~>, with a whole new
set of semantics.  Anywhere you used C<=~> before you now use C<~~>, but 
C<~~> is much more general now.  See L<Synopsis 4> for details.

=item * Unary C<.> calls its single argument (which must be a method, or an
dereferencer for a hash or array) on C<$_>.

=item * The C<..> binary range operator has variants with C<^> on either
end to indicate exclusion of that endpoint from the range.

=item * C<...> is a unary postfix operator that constructs a semi-infinite
(and lazily evaluated) list, starting at the value of its single argument.

=item * However, C<...> as a term is the "yada, yada, yada" operator,
which is used as the body in function prototypes.  It complains
bitterly if it is ever executed.

=item * In addition, to the ordinary C<.> method invocation, there are
variants C<.*>, C<.?>, and C<.+> to control how multiple parent methods
of the same name are handled.  The C<.=> operator does inplace modification
of the object on the left.

=item * Unary C<=> reads lines from a filehandle or filename, or in general
iterates an iterator.

=back

=head1 Hyper operators

The Unicode characters C<»> (C<\x[BB]>) and C<«> (C<\x[AB]>) and
their ASCII digraphs C<<< >> >>> and C<<< << >>> are used to denote
"list operations", which operate on each element of two lists (or
arrays) and return a list (or array) of the results.  Spaces are not
allowed on the "pointy" end of each "hyper", but are allowed on the
blunt end. For example:

     (1,1,2,3,5) »+« (1,2,3,5,8);  # (2,3,5,8,13)

If one argument is insufficiently dimensioned, Perl "upgrades" it:

     (3,8,2,9,3,8) >>-<< 1;          # (2,7,1,8,2,7)

When using a unary operator, only put it on the operand's side:

     @negatives = -« @positives;
     
     @positions »++;            # Increment all positions
     
     @objects ».run();
     ("f","oo","bar")».length;   # (1,2,3)

Note that method calls are really postfix operators, not infix, so you
shouldn't put a C<«> after the dot.

=head1 Junctive operators

C<|>, C<&>, and C<^> are no longer bitwise operators (see L</Operator
Renaming>) but now serve a much higher cause: they are now the
junction constructors.

A junction is a single value that is equivalent to multiple values. They
thread through operations, returning another junction representing the
result:

     1|2|3 + 4;                              # 5|6|7
     1|2 + 3&4;                              # (4|5) & (5|6)

Note how when two junctions are applied through an operator, the result
is a junction representing the operator applied to each combination of
values.

Junctions come with the functional variants C<any>, C<all>, C<one>, and C<none>.

This opens doors for constructions like:

     unless $roll == any(1..6) { print "Invalid roll" }

     if $roll == 1|2|3 { print "Low roll" }

Junctions work through subscripting:

    print if @foo[any(1,2,3)]

Junctions are specifically unordered.  So if you say

    for all(@foo) {...}

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.

=head1 Chained comparisons

Perl 6 supports the natural extension to the comparison operators,
allowing multiple operands.

     if 3 < $roll <= 6              { print "High roll" }
     
     if 1 <= $roll1 == $roll2 <= 6  { print "Doubles!" }

Note: any operator beginning with C<< < >> must have whitespace
in front of it, or it will be interpreted as a hash subscript instead.

=head1 Binding

A new form of assignment is present in Perl 6, called "binding," used in
place of typeglob assignment.  It is performed with the C<:=> operator.
Instead of replacing the value in a container like normal assignment, it
replaces the container itself.  For instance:

    my $x = 'Just Another';
    my $y := $x;
    $y = 'Perl Hacker';

After this, both C<$x> and C<$y> contain the string "Perl Hacker," since
they are really just two different names for the same variable.

There is another variant, spelled C<::=>, that does the same thing at
compile time.

There is also an identity test, C<=:=>, which tests whether two names
are bound to the same underlying variable.  C<$x =:= $y> would return
true in the above example.

=head1 List flattening

Since typeglobs are being removed, unary C<*> may now serve as a lazy list
flattening operator.  It is used to "flatten" an array into a list,
usually to allow the array's contents to be used as the arguments of a
subroutine call.  Note that those arguments still must comply with the
subroutine's signature, but the presence of C<*> defers that test until
run time for that argument (and for any subsequent arguments):

    my @args = (\@foo, @bar);
    push *@args;

is equivalent to:

    push @foo, @bar;

In list context, a scalar reference to an array does not flatten.  Hence

    $bar = @bar;
    push @foo, $bar;

merely pushes a single scalar reference onto C<@foo>.  You can
explicitly flatten it in any of these ways:

    push @foo, *$bar;
    push @foo, @$bar;
    push @foo, $bar[];

(The C<*> in list context doesn't change the call semantics as is
does in scalar context.)  Note that these three forms also allow you
to specify list context on assignment:

    *$bar = (1,2,3);
    @$bar = (1,2,3);
    $bar[] = (1,2,3);

The last is particularly useful at the end of a long name naming an
array attribute:

    $foo.bar.baz.bletch.whatever.attr[] = (1,2,3)

The empty C<[]> and C<.[]> postfix operators are interpreted as
zero-dimensional slices returning the entire array, not null slices
returning no elements.  Likewise for C<{}> and C<.{}> on hashes,
not to mention the C<< <> >>, C<< .<> >>, C<«»>, and C<.«»>
constant and interpolating slice subscripting forms.

The C<*> operator flattens lazily.  To get an immediate flattening like
Perl 5 does, use unary C<**> instead.  You may use either of them on
a scalar iterator to force it to iterate.

=head1 Piping operators

The new operators C<< ==> >> and C<< <== >> are akin to UNIX pipes, but
work with functions that accept and return lists.  For example,

     @result = map { floor($^x / 2) }
                 grep { /^ \d+ $/ }
                   @data;

Can also now be written:

     @data ==> grep { /^ \d+ $/ }
           ==> map { floor($^x / 2) }
           ==> @result;

or:

     @result <== map { floor($^x / 2) }
             <== grep { /^ \d+ $/ }
             <== @data;

Either form more clearly indicates the flow of data.  See L<Synopsis 6> for 
more of the (less-than-obvious) details on these two operators.

=head1 Invocant marker

An appended C<:> marks the invocant when using the indirect-object
syntax for Perl 6 method calls.  The following two statements are
equivalent:

    $hacker.feed('Pizza and cola');
    feed $hacker: 'Pizza and cola';

=head1 C<zip>

In order to support parallel iteration over multiple arrays, Perl 6 has
a C<zip> function that interleaves the elements of two or more arrays.

    for zip(@names, @codes) -> $name, $zip {
        print "Name: $name;   Zip code: $zip\n";
    }

C<zip> has an infix synonym, the Unicode operator C<¥>.

=head1 Minimal whitespace DWIMmery

Whitespace is no longer allowed before the opening bracket of an array
or hash accessor.  That is:

    %monsters{'cookie'} = Monster.new;  # Valid Perl 6
    %people  {'john'}   = Person.new;   # Not valid Perl 6

One of the several useful side-effects of this restriction is that
parentheses are no longer required around the condition of control
constructs:

    if $value eq $target {
        print "Bullseye!";
    }
    while 0 < $i { $i++ }

It is, however, still possible to align accessors by explicitly using the C<.>
operator:

     %monsters.{'cookie'} = Monster.new;
     %people  .{'john'}   = Person .new;
     %cats    .{'fluffy'} = Cat    .new;

=head1 Precedence

Perl 6 has 22 precedence levels (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 <=> .. ^.. ..^ ^..^
    chaining binary	!= == < <= > >= ~~ !~ eq ne lt le gt ge =:=
    tight and		&&
    tight or		|| ^^ //
    ternary		?? ::
    assignment		= := ::= += **= xx=
    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

