=begin pod

=TITLE Operators

=SUBTITLE Common Perl 6 infixes, prefixes, postfixes, and more!

=head1 Operator Precedence

In an expression like C<1 + 2 * 3>, the C<2 * 3> is evaluated first
because the infix C<*> has tighter B<precedence> than the C<+>.

The following table summarizes the precedence levels in Perl 6, from
tightest to loosest:

=begin table

    A  Level             Examples
    =  =====             ========
    N  Terms             42 3.14 "eek" qq["foo"] $x :!verbose @$array
    L  Method postfix    .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^ .:
    N  Autoincrement     ++ --
    R  Exponentiation    **
    L  Symbolic unary    ! + - ~ ? | || +^ ~^ ?^ ^
    L  Multiplicative    * / % %% +& +< +> ~& ~< ~> ?& div mod gcd lcm
    L  Additive          + - +| +^ ~| ~^ ?| ?^
    L  Replication       x xx
    X  Concatenation     ~
    X  Junctive and      &
    X  Junctive or       | ^
    L  Named unary       temp let
    N  Structural infix  but does <=> leg cmp .. ..^ ^.. ^..^
    C  Chaining infix    != == < <= > >= eq ne lt le gt ge ~~ === eqv !eqv
    X  Tight and         &&
    X  Tight or          || ^^ // min max
    R  Conditional       ?? !! ff fff
    R  Item assignment   = => += -= **= xx= .=
    L  Loose unary       so not
    X  Comma operator    , :
    X  List infix        Z minmax X X~ X* Xeqv ...
    R  List prefix       print push say die map substr ... [+] [*] any Z=
    X  Loose and         and andthen
    X  Loose or          or xor orelse
    X  Sequencer         <==, ==>, <<==, ==>>
    N  Terminator        ; {...}, unless, extra ), ], }

=end table

Using two C<!> symbols below generically to represent any pair of operators
that have the same precedence, the associativities specified above
for binary operators are interpreted as follows:

=begin table

    A   Assoc     Meaning of $a ! $b ! $c
    =   =====     =======================
    L   left      ($a ! $b) ! $c
    R   right     $a ! ($b ! $c)
    N   non       ILLEGAL
    C   chain     ($a ! $b) and ($b ! $c)
    X   list      infix:<!>($a; $b; $c)

=end table

For unary operators this is interpreted as:

=begin table

    A   Assoc     Meaning of !$a!
    =   =====     =========================
    L   left      (!$a)!
    R   right     !($a!)
    N   non       ILLEGAL

=end table

In the operator descriptions below, a default associativity of I<left>
is assumed.

=head1 Operator classification

Operators can occur in several positions relative to a term:

=begin table

    +term           prefix
    term1 + term2   infix
    term++          postfix
    (term)          circumfix
    term1[term2]    postcircumfix

=end table

Each operator is also available as a subroutine.
The name of the routine is formed of
the operator category, then a colon, and a list quote construct with the
symbol(s) that make up the operator:

    infix:<+>(1, 2)                 # same as 1 + 2
    circumfix:«( )»('a', 'b', 'c')  # same as ('a', 'b', 'c')

As a special case the I<listop> (list operator) can stand either as a
term or as a prefix. Subroutine calls are the most common listops. Other
cases include meta-reduced infix operators (C<[+]| 1, 2, 3>) and the
L<#prefix ...> etc. stub operators.


Defining custom operators is covered in
L</language/functions#Defining_Operators>.

=head1 Meta Operators

Meta operators can be parameterized with other operators in the same way as
functions can take functions as parameters. Perl 6 will generate the actual
combinded operator in the background, allowing the mechanism to be applied
to user defined operators. There are quite a few Meta operators with
different semantics, as explained in detail as follows.

=head2 Assignment Operators

Infix operators can be combined with the assignment operator to modify a
value and apply the result to a container in one go. Containers will be
autovivified if possible.

    my $a = 32;
    $a += 10;  # 42

    my $a = 3;
    $a min= 5; # still 3
    $a min= 2; # 2

Z<blocked by #63642 my @a = 1,2; @a ,= 3,4;>

This behavior is automatically extended to include custom-defined infix operators.

    sub infix:<space-concat> ($a,$b) { $a ~ " " ~ $b };
    my $a = 'word1';
    $a space-concat= 'word2'; # 'word1 word2'

Although not strictly operators, methods can be used in the same fashion.

    my Rat $a .= new;
    my $a = 3.14;
    $a .= Int; # 3

=head2 Negated Relational Operators

The result of a relational operator returning C<Bool> can be negated by
prefixing with C<!>. To avoid visial confusion with the C<!!> operator,
you may not modify any operator already beginning with C<!>.

There are shortcuts for C<!==> and C<!eq>, namely C<!=> and C<ne>.

    my $a = True;
    say so $a != True; # False
    my $i = 10;

    my $release = Date.new(:2015year, :12month, :24day);
    my $today = Date.today;
    say so $release !before $today; # True

=head2 Reversed Operators

Any infix operator may be called with its two arguments reversed by prefixing
with C<R>. Associativity of operands is reversed as well.

    say [R/] 2, 4, 16; # 2

=head2 Hyper Operators

Hyper operators apply a given operator enclosed by C<«> and C<»> to one or two
lists, returning the resulting list. The pointy part of C<«> or C<»> has to
point to the shorter list. A list with just one element is fine too. If one of
the lists is shorter then the other, the operator will cycle over the shorter
list until all elements of the longer list are processed.

    say (1,2,3) »*» 2;       # (2,4,6)
    say (1,2,3,4) »~» <a b>; # (1a 2b 3a 4b)
    say (1,2,3) »+« (4,5,6); # (5 7 9)

Assignment meta operators can be hyped.

    my @a = 1,2,3;
    say @a »+=» 1; # [2 3 4]

Hyper forms of unary opators have the pointy bit point to the operator and
the blunt end at the list to be operated on.

    my @wisdom = True, False, True;
    say !« @wisdom; # [False True False]
    
    my @a = 1,2,3;
    @a»++;          # (2,3,4)

Hyper operators are defined recursivly on nested arrays.

    say -« [[1, 2], 3]; # [[-1 -2] -3]

Methods can be called too, in a out of order, cuncurrent fashion. The resulting
list is in order. Please note that all hyper operators are candidates for
autothreading and will cause tears if said methods have side effects. The
optimizer has full reign over hyper operators, what is the reasion that they
can not be defined by the user.

    my CarefulClass @objs;
    my @results = @objs».take-care();

    my @slops; # May Contain Nuts
    @slops».?this-method-may-not-exist();

Hyper operatos can work with hashes. The pointy direction indicates if missing
keys are to be ignored in the resulting hash. The enclosed operator operates on
all values that have keys in both hashes.

=begin table
C<%foo «+» %bar;>       intersection of keys

C<%foo »+« %bar;>       union of keys

C<%outer »+» %inner;>   only keys of %inner that exist in %outer will occur in the result
=end table

    my %outer = 1,2,3 Z=> <a b c>; 
    my %inner = 1,2 Z=> <x z>; 
    say %outer «~» %inner; # {"1" => "ax", "2" => "bz"}

Hyper operators can take user defined operators as its operator argument.

    sub pretty-file-site (Int $size --> Str) {
        # rounding version of infix:</>(Int,Int)
        sub infix:<r/>(Int \i1, Int \i2) {
            round(i1 / i2, 0.1)
        }
    
        # we build a vector of fractions of $size and zip that with the fitting prefix
        for $size «[r/]« (2**60, 2**50, 2**40, 2**30, 2**20, 2**10)
                  Z      <EB     PB     TB     GB     MB     KB> -> [\v,\suffix] {
            # starting with the biggest suffix, we take the first that is 0.5 of that suffix or bigger
            return v ~ ' ' ~ suffix if v > 0.4
        }
        # this be smaller or equal then 0.4 KB
        return $size.Str;
    }
    
    for 60, 50, 40, 30, 20, 10 -> $test {
        my &a = { (2 ** $test) * (1/4, 1/2, 1, 10, 100).pick * (1..10).pick };
        print pretty-file-site(a.Int) xx 2, ' ';
    }

    # OUTPUT: «10 EB 4 EB 2 PB 5 PB 0.5 PB 4 TB 300 GB 4.5 GB 50 MB 200 MB 9 KB 0.6 MB»

Hyper operators do not descent into child lists. You can chain hyper operators
to destructure a List of Lists.

    my $neighbors = ((-1, 0), (0, -1), (0, 1), (1, 0));
    my $p = (2,3); 
    say $neighbors »>>+<<» ($p, *); # ((1 3) (2 2) (2 4) (3 3))

=head2 Reduction Operators

Reduction operators apply any infix operator, surrounded by C<[> and C<]>,
element by element and return the resulting value.

    say [+] 1,2,3; # 6

They can be defined as a list prefix operators or will be generated automatically. 

    multi infix:<[~~]> (@c, &test) is looser(&infix:<~~>) { 
        gather for @c { take $_ if test($_) } 
    }; 
    my @l = 1,'a',2,'b'; 
    say @l [~~] {$^a ~~ Str}; # (a b)

For list infix operators, flattening is not done on the input list. This
allowes list operators to become the reduction operator.

    [X~] (1,2), <a b> # 1,2 X~ <a b>

By default reduction meta operators are eager. To lazily generate values,
prefix the operater with a C<\>. If the non-meta part contains a C<\> already,
quote it with C<[]> (e.g. C<[\[\x]]>). 

    my $lazy := [\+] 1..*;
    say $lazy[^10]; # (1 3 6 10 15 21 28 36 45 55)

=head2 Cross Operators
TODO

=head2 Zip Operators

The zip metaoperator, C<Z>, will apply a given infix operator to pairs taken
one left, one right, from it's arguments. The resulting list is returned.

    my @l = <a b c> Z~ 1,2,3; # [a1 b2 c3]
    
If one of the operands runs out of elements prematurely, the zip operator will
stop. An infinite list can be used to repeat elements. A list with a final 
element of C<*> will repeat it's 2nd last element indefinitely.

    my @l = <a b c d> Z~ ':' xx *; # <a: b: c: d:> 
    my @l = <a b c d> Z~ 1, 2, *;  # <a1 b2 c2 d2>

=head2 Sequential Operators

The sequential metaoperator, C<S>, will suppress any concurrency, or reordering
done by the optimizer. Most simple infix operators are supported.

    say so 1 S& 2 S& 3; # True

=head2 Nesting of Meta Operators

To avoid ambiguity when chaining meta operators use square brackets to help the
compiler to understand you.

    my @a = 1,2,3; 
    my @b = 5,6,7; 
    @a X[+=] @b; 
    say @a; # [19 20 21]

=head1 Z<>Term Precedence

=head2 circumfix C«< >»

The quote-words construct. Breaks up the contents on whitespace, and returns
a L<List|/type/List> of the words. If a word
looks like a number literal or a C<Pair> literal, it is converted to the
appropriate number.

    say <a b c>[1];     # b

=head2 circumfix C«( )»

The grouping operator.

An empty group C<()> creates an empty L<List>.
Parens around non-empty expressions simply structure the expression, but
not have additional semantics.

In an argument list, putting parenthesis around an argument prevents it from
being interpreted as a named argument.

    multi sub p(:$a!) { say 'named'      }
    multi sub p($a)   { say 'positional' }
    p a => 1;       # named
    p (a => 1);     # positional

=head2 circumfix C«{ }»

Block or L<Hash> constructor.

If the contents looks like a list of pairs and does not use L<$_> or other
placeholder parameters, returns an itemized L<Hash>.

Otherwise it constructs a L<Block>.

Note that this construct does not re-parse the contents; rather the
contents are always parsed as a statement list (i.e. like a block),
and if the later analysis shows that it needs to be interpreted as a hash,
the block is executed and coerced to L<Hash>.

=head2 circumfix C«[ ]»

The L<Array> constructor. Returns an itemized L<Array> which does not flatten
in list context.

=head1 Method Postfix Precedence

=head2 postcircumfix C«[ ]»

    sub postcircumfix:<[ ]>(@container, **@index,
                            :$k, :$v, :$kv, :$p, :$exists, :$delete)

Universal interface for positional access to zero or more elements of a
@container, a.k.a. "array indexing operator".

    my @alphabet = 'a' .. 'z';
    say @alphabet[0];                   #-> a
    say @alphabet[1];                   #-> b
    say @alphabet[*-1];                 #-> z
    say @alphabet[100]:exists;          #-> False
    say @alphabet[15, 4, 17, 11].join;  #-> perl
    say @alphabet[23 .. *].perl;        #-> ("x", "y", "z")

    @alphabet[1, 2] = "B", "C";
    say @alphabet[0..3].perl            #-> ("a", "B", "C", "d")

See L<Subscripts|/language/subscripts> for a more detailed explanation of this
operator's behavior, and how to implement support for it in custom types.

=head2 postcircumfix C«{ }»

    sub postcircumfix:<{ }>(%container, **@key,
                            :$k, :$v, :$kv, :$p, :$exists, :$delete)

Universal interface for associative access to zero or more elements of a
%container, a.k.a. "hash indexing operator".

    my %color = kiwi => "green", banana => "yellow", cherry => "red";
    say %color{"banana"};               #-> yellow
    say %color{"cherry", "kiwi"}.perl;  #-> ("red", "green")
    say %color{"strawberry"}:exists;    #-> False

    %color{"banana", "lime"} = "yellowish", "green";
    %color{"cherry"}:delete;
    say %color;  #-> banana => yellowish, kiwi => green, lime => green

See L«C«postcircumfix < >»|/routine/[ ]#postcircumfix_<_>» and
L<C<postcircumfix « »>|/routine/[ ]#postcircumfix_«_»> for convenient
shortcuts, and L<Subscripts|/language/subscripts> for a more detailed
explanation of this operator's behavior, and how to implement support for it
in custom types.

=head2 postcircumfix C«< >»

Shortcut for L<C<postcircumfix { }>|/routine/[ ]#postcircumfix_{_}> that quotes
its argument using the same rules as the L«quote-words operator|
/routine/< >#circumfix_<_>» of the same name.

    my %color = kiwi => "green", banana => "yellow", cherry => "red";
    say %color<banana>;             #-> yellow
    say %color<cherry kiwi>.perl;   #-> ("red", "green")
    say %color<strawberry>:exists;  #-> False

This is not a real operator, just syntactic sugar that is turned into the
C<{ }> postcircumfix operator at compile-time.

=head2 postcircumfix C<« »>

Shortcut for L<C<postcircumfix { }>|/routine/[ ]#postcircumfix_{_}> that quotes
its argument using the same rules as the L<interpolating quote-words operator|
/routine/« »#circumfix_«_»> of the same name.

    my %color = kiwi => "green", banana => "yellow", cherry => "red";
    my $fruit = "kiwi";
    say %color«cherry $fruit».perl;   #-> ("red", "green")

This is not a real operator, just syntactic sugar that is turned into the
C<{ }> postcircumfix operator at compile-time.

=head2 postcircumfix C«( )»

The call operator. Treats the invocant as a L<Callable> and invokes it,
using the expression between the parens as arguments.

Note that an identifier followed by a pair of parens is always parsed as a
subroutine call.

If you want your objects to respond to the call operator, you need to
implement a C<method CALL-ME>.

=head2 postfix C«.»

The operator for calling one method, C<$invocant.method>.

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.=»

A mutating method call. C<$invocant.=method> desugars to
C<$invocant = $invocant.method>, similar to L<C<op=>>.

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.^»

A meta-method call. C<$invocant.^method> calls C<method> on C<$invocant>'s
metaclass. It desugars to C<$invocant.HOW.method($invocant, ...)>. See L<C<HOW>>
for more information.

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.?»

Potential method calls. C<$invocant.?method> calls method C<method> on
C<$invocant> if it has a method of such name. Otherwise it returns L<Nil>.

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.+»

C<$invocant.+method> calls all methods called C<method> from C<$invocant>,
and returns a L<List> of the results. Dies if no such method was found.

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.*»

C<$invocant.*method> calls all methods called C<method> from C<$invocant>,
and returns a L<List> of the results. If no such method was found, an empty
L<List> is returned.

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C<».> / postfix C«>>.»

Hyper method call operator will call a method on all elements of a C<List> out of order and return the list of return values in order.

    my @a = <a b c>;
    @a».say;                          # a␤b␤c␤
    my @b = @a».ord;                  # [97, 98, 99]
    sub foo(Str:D $c){ $c.ord * 2 };  # The first parameter of a method is the invocant.
    say @a».&foo;                     # So we can pretend to have a method call with a sub that got a good first positional argument.
    say @a».&({ .ord});               # Blocks have an implicit positional arguments that lands in $_. The latter can be obmitted for method calls.

=head2 X«postfix C<.postfix>
    |postfix,.postfix;postcircumfix,.( );postcircumfix,.[ ];postcircumfix,.{ };postcircumfix,.< >»

In most cases, a dot may be placed before a postfix or postcircumfix:

    @a[1, 2, 3];
    @a.[1, 2, 3]; # Same

This can be useful for visual clarity or brevity. For example, if an object's
attribute is a function, putting a pair of parentheses after the attribute name
will become part of the method call. So either two pairs of parentheses must be
used, or a dot has to come before the parentheses to separate it from the method
call.

    class Operation {
        has $.symbol;
        has &.function;
    }
    my $addition = Operation.new(:symbol<+>, :function{ $^a + $^b });
    say $addition.function()(1, 2); # 3
    # OR
    say $addition.function.(1,2); # 3

If the postfix is an identifier, however, it will be interpreted as a normal
method call.

    1.i # No such method 'i' for invocant of type 'Int'

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.:<prefix>»

A prefix can be called like a method using colonpair notation. For example:

    my $a = 1;
    say ++$a;     # 2
    say $a.:<++>; # 3

Technically this is not an operator, but syntax special-cased in the compiler.

=head2 postfix C«.::»

A class-qualified method call, used to call a method as defined in a parent
class or role, even after it has been redefined in the child class.

    class Bar {
        method baz { 42 }
    }
    class Foo is Bar {
        method baz { "nope" }
    }
    say Foo.Bar::baz; # 42

=head1 Autoincrement Precedence

=head2 prefix C«++»

    multi sub prefix:<++>($x is rw) is assoc<none>

Increments its argument by one, and returns the incremented value.

    my $x = 3;
    say ++$x;       # 4
    say $x;         # 4

It works by calling the L<succ> method (for I<successor>) on its argument,
which gives custom types the freedom to implement their own increment
semantics.

=head2 prefix C«--»

    multi sub prefix:<-->($x is rw) is assoc<none>

Decrements its argument by one, and returns the decremented value.

    my $x = 3;
    say --$x;       # 2
    say $x;         # 2

It works by calling the L<pred> method (for I<predecessor>) on its argument,
which gives custom types the freedom to implement their own decrement
semantics.


=head2 postfix C«++»

    multi sub postfix:<++>($x is rw) is assoc<none>

Increments its argument by one, and returns the unincremented value.

    my $x = 3;
    say $x++;       # 3
    say $x;         # 4

It works by calling the L<succ> method (for I<successor>) on its argument,
which gives custom types the freedom to implement their own incrementation
semantics.

Note that this does not necessarily return its argument. For example for
undefined values, it returns 0:

    my $x;
    say $x++;       # 0
    say $x;         # 1

=head2 postfix C«--»

    multi sub postfix:<-->($x is rw) is assoc<none>

Decrements its argument by one, and returns the undecremented value.

    my $x = 3;
    say $x--;       # 3
    say $x;         # 2

It works by calling the L<pred> method (for I<predecessor>) on its argument,
which gives custom types the freedom to implement their own decrementation
semantics.

Note that this does not necessarily return its argument. For example for
undefined values, it returns 0:

    my $x;
    say $x--;       # 0
    say $x;         # -1

=head1 Exponentiation Precedence

=head2 infix C«**»

    multi sub infix:<**>(Any, Any) returns Numeric:D is assoc<right>

The exponentiation operator coerces both arguments to L<Numeric>
and calculates the left-hand-side raised to the power of the right-hand side.

If the right-hand side is a non-negative integer and the left-hand side
is an arbitrary precision type (L<Int>, L<FatRat>), then the calculation
is carried out without loss of precision.

=head1 Symbolic Unary Precedence

=head2 prefix C«?»

    multi sub prefix:<?>(Mu) returns Bool:D

Boolean context operator.

Coerces the argument to L<Bool> by calling the C<Bool> method on it.
Note that this collapses L<Junction>s.

=head2 prefix C«!»

    multi sub prefix:<!>(Mu) returns Bool:D

Negated boolean context operator.

Coerces the argument to L<Bool> by calling the C<Bool> method on it,
and returns the negation of the result.
Note that this collapses L<Junction>s.

=head2 prefix C«+»

    multi sub prefix:<+>(Any) returns Numeric:D

Numeric context operator.

Coerces the argument to L<Numeric> by calling the C<Numeric> method on it.

=head2 prefix C«-»

    multi sub prefix:<->(Any) returns Numeric:D

Negative numeric context operator.

Coerces the argument to L<Numeric> by calling the C<Numeric> method on it,
and then negates the result.

=head2 prefix C«~»

    multi sub prefix:<->(Any) returns Str:D

String context operator.

Coerces the argument to L<Str> by calling the C<Str> method on it.

=head2 prefix C«|»

Flattens objects of type L<Capture>, L<Pair>, L<List> L<Map> and L<Hash>
into an argument list.

Outside of argument lists, it returns a L<Slip|/type/Slip>, which makes it
flatten into the outer list.

=head2 prefix C«+^»

    multi sub prefix:<+^>(Any) returns Int:D

Integer bitwise negation.

Coerces the argument to L<Int> and does a bitwise negation on the result,
assuming L<two's complement|https://en.wikipedia.org/wiki/Two%27s_complement>.

=head2 prefix C«?^»

    multi sub prefix:<?^>(Mu) returns Bool:D

Boolean bitwise negation.

Coerces the argument to L<Bool> and then does a bit flip, which makes it the
same as C<< prefix:<!> >>.

=head2 prefix C«^»

    multi sub prefix:<^>(Any) returns Range:D

I<upto> operator.

Coerces the argument to L<Numeric>, and generates a range from 0 up to (but
excluding) the argument.

    say ^5;         # 0..^5
    for ^5 { }      # 5 iterations

=head1 Multiplicative Precedence

=head2 infix C«*»

    multi sub infix:<*>(Any, Any) returns Numeric:D

Coerces both arguments to L<Numeric> and multiplies them. The result
is of the wider type. See L<Numeric> for details.

=head2 infix C«/»

    multi sub infix:</>(Any, Any) returns Numeric:D

Coerces both argument to L<Numeric> and divides the left through the right
number. Division of L<Int> values returns L<Rat>, otherwise the "wider type"
rule described in L<Numeric> holds.

=head2 infix C«div»

    multi sub infix:<div>(Int:D, Int:D) returns Int:D

Integer division. Rounds down.

=head2 infix C«%»

    multi sub infix:<%>($x, $y) return Numeric:D

Modulo operator. Coerces to L<Numeric> first.

Generally the following identity holds:

    $x % $y == $x - floor($x / $y) * $y

=head2 infix C«%%»

    multi sub infix:<%%>($a, $b) returns Bool:D

Divisibility operator. Returns C<True> if C<$a %  $b == 0>.

=head2 infix C«mod»

    multi sub infix:<mod>(Int:D $a, Int:D $b) returns Int:D

Integer modulo operator. Returns the remainder of an integer modulo operation.

=head2 infix C«+&»

    multi sub infix:<+&>($a, $b) returns Int:D

Numeric bitwise I<AND>. Coerces both arguments to L<Int> and does a bitwise
I<AND> operation assuming two's complement.

=head2 infix C«+<»

    multi sub infix:<< +< >>($a, $b) returns Int:D

Integer bit shift to the left.

=head2 infix C«+>»

    multi sub infix:<< +> >>($a, $b) returns Int:D

Integer bit shift to the right.

=head2 infix C«gcd»

    multi sub infix:<gcd>($a, $b) returns Int:D

Coerces both arguments to L<Int> and returns the greatest common denominator.

=head2 infix C«lcm»

    multi sub infix:<lcm>($a, $b) returns Int:D

Coerces both arguments to L<Int> and returns the least common multiple, that is
the smallest integer that is evenly divisible by both arguments.

=head1 Additive Precedence

=head2 infix C«+»

    multi sub infix:<+>($a, $b) returns Numeric:D

Coerces both arguments to L<Numeric> and adds them.

=head2 infix C«-»

    multi sub infix:<->($a, $b) returns Numeric:D

Coerces both arguments to L<Numeric> and subtracts the second from the
first.

=head2 infix C«+|»

    multi sub infix:<+|>($a, $b) returns Int:D

Coerces both arguments to L<Int> and does a bitwise I<OR> (inclusive OR)
operation.

=head2 infix C«+^»

    multi sub infix:<+^>($a, $b) returns Int:D

Coerces both arguments to L<Int> and does a bitwise I<XOR> (exclusive OR)
operation.

=head2 infix C«?|»

    multi sub infix:<?|>($a, $b) returns Bool:D

Coerces both arguments to L<Bool> and does a logical I<OR> (inclusive OR)
operation.

=head1 Replication Precedence

=head2 infix C«x»

    proto sub infix:<x>(Any, Any) returns Str:D
    multi sub infix:<x>(Any, Any)
    multi sub infix:<x>(Str:D, Int:D)

Coerces C<$a> to L<Str> and C<$b> to L<Int> and repeats the string C<$b>
times. Return the empty string if C<< $b <= 0 >>.

    say 'ab' x 3;       # ababab
    say 42 x 3;         # 424242

=head2 infix C«xx»

    multi sub infix:<xx>($a, $b) returns List:D

Returns a list of C<$a> repeated and evaluated C<$b> times (C<$b> is coerced
to L<Int>). If C<< $b <= 0 >>, the empty list is returned.

The left-hand side is evaluated for each repetition, so

    [1, 2] xx 5

returns five distinct arrays (but with the same content each time), and

    rand xx 3

returns three pseudo random numbers that are determined independently.

The right-hand side can be C<*>, in which case a lazy, infinite list
is returned.

=head1 Concatenation

=head2 infix C«~»

    proto sub infix:<~>(Any, Any) returns Str:D
    multi sub infix:<~>(Any,   Any)
    multi sub infix:<~>(Str:D, Str:D)

Coerces both arguments to L<Str> and concatenates them.

    say 'ab' ~ 'c';     # abc

=head1 Junctive AND (all) Precedence

=head2 infix C«&»

    multi sub infix:<&>($a, $b) returns Junction:D is assoc<list>

Creates an I<all> L<Junction> from its arguments. See L<Junction> for more
details.

=head1 Junctive OR (any) Precedence

=head2 infix C«|»

    multi sub infix:<|>($a, $b) returns Junction:D is assoc<list>

Creates an I<any> L<Junction> from its arguments. See L<Junction> for more
details.

=head2 infix C«^»

    multi sub infix:<^>($a, $b) returns Junction:D is assoc<list>

Creates a I<one> L<Junction> from its arguments. See L<Junction> for more
details.

=head1 Named Unary Precedence

=head2 prefix C«temp»

    sub prefix:<temp>(Mu $a is rw)

"temporizes" the variable passed as the argument, which means it is reset
to its old value on scope exit. (This is similar to the
L<local|http://perldoc.perl.org/functions/local.html> operator in Perl 5,
except that C<temp> does not reset the value).

=head2 prefix C«let»

    sub prefix:<let>(Mu $a is rw)

Restores the previous value if the block exits unsuccessfully. A
successful exit means the block returned a defined value or a list.

    my $answer = 42;

    {
        let $answer = 84;
        die if not Bool.pick;
        CATCH {
            default { say "it's been reset :(" }
        }
        say "we made it 84 sticks!";
    }

    say $answer;

In the above case, if the C<Bool.pick> returns true, the answer will
stay as 84 because the block returns a defined value (C<say> returns
true). Otherwise the C<die> statement will cause the block to exit
unsuccessfully, resetting the answer to 42.

=comment this is duplicated in variables.pod

=head1 Nonchaining Binary Precedence

=head2 infix C«does»

    sub infix:<does>(Mu $obj, Mu $role) is assoc<none>

Mixes C<$role> into C<$obj> at run time. Requires C<$obj> to be mutable.

C<$role> doesn't need to a be a role, it can be something that knows how
to act like a role, for example enum values.

=head2 infix C«but»

    sub infix:<but>(Mu $obj, Mu $role) is assoc<none>

Creates a copy of C<$obj> with C<$role> mixed in. Since C<$obj> is not
modified, C<but> can be used to created immutable values with mixins.

C<$role> doesn't need to a be a role, it can be something that knows how
to act like a role, for example enum values.

=head2 infix C«cmp»

    proto sub infix:<cmp>(Any, Any) returns Order:D is assoc<none>
    multi sub infix:<cmp>(Any,       Any)
    multi sub infix:<cmp>(Real:D,    Real:D)
    multi sub infix:<cmp>(Str:D,     Str:D)
    multi sub infix:<cmp>(Version:D, Version:D)

Generic, "smart" three-way comparator.

Compares strings with string semantics, numbers
with number semantics, L<Pair> objects first by key and then by value etc.

if C<$a eqv $b>, then C<$a cmp $b> always returns C<Order::Same>.

    say (a => 3) cmp (a => 4);      # Less
    say 4        cmp 4.0;           # Same
    say 'b'      cmp 'a';           # More

=head2 infix C«leg»

    proto sub infix:<leg>($a, $b) returns Order:D is assoc<none>
    multi sub infix:<leg>(Any,   Any)
    multi sub infix:<leg>(Str:D, Str:D)

String three-way comparator. Short for I<less, equal or greater?>.

Coerces both arguments to L<Str>, and then does a lexicographic comparison.

    say 'a' leg 'b';        Less
    say 'a' leg 'a';        Same
    say 'b' leg 'a';        More

=head2 infix C«<=>»

    multi sub infix:«<=>»($a, $b) returns Order:D is assoc<none>

Numeric three-way comparator.

Coerces both arguments to L<Real>, and then does a numeric comparison.

=head2 infix C«..»

    multi sub infix:<..>($a, $b) returns Range:D is assoc<none>

Constructs a L<Range> from the arguments.

=head2 infix C«..^»

    multi sub infix:<..^>($a, $b) returns Range:D is assoc<none>

Constructs a L<Range> from the arguments, excluding the end point.

=head2 infix C«^..»

    multi sub infix:<^..>($a, $b) returns Range:D is assoc<none>

Constructs a L<Range> from the arguments, excluding the start point.


=head2 infix C«^..^»

    multi sub infix:<^..^>($a, $b) returns Range:D is assoc<none>

Constructs a L<Range> from the arguments, excluding both start and end point.

=head1 Chaining Binary Precedence

=head2 infix C«==»

    proto sub infix:<==>($, $) returns Bool:D is assoc:<chain>
    multi sub infix:<==>(Any, Any)
    multi sub infix:<==>(Int:D, Int:D)
    multi sub infix:<==>(Num:D, Num:D)
    multi sub infix:<==>(Rational:D, Rational:D)
    multi sub infix:<==>(Real:D, Real:D)
    multi sub infix:<==>(Complex:D, Complex:D)
    multi sub infix:<==>(Numeric:D, Numeric:D)

Coerces both arguments to L<Numeric> if necessary, and returns C<True>
if they are equal.

=head2 infix C«!=»

    proto sub infix:<!=>(Mu, Mu) returns Bool:D is assoc<chain>

Coerces both arguments to L<Numeric> (if necessary), and returns C<True> if they are
distinct.

=head2 infix C«<»

    proto sub infix:«<»(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:«<»(Int:D, Int:D)
    multi sub infix:«<»(Num:D, Num:D)
    multi sub infix:«<»(Real:D, Real:D)

Coerces both arguments to L<Real> (if necessary), and returns C<True> if the first argument
is smaller than the second.

=head2 infix C«<=»

    proto sub infix:«<=»(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:«<=»(Int:D, Int:D)
    multi sub infix:«<=»(Num:D, Num:D)
    multi sub infix:«<=»(Real:D, Real:D)

Coerces both arguments to L<Real> (if necessary), and returns C<True> if the first argument
is smaller than or equal to the second.


=head2 infix C«>»

    proto sub infix:«>»(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:«>»(Int:D, Int:D)
    multi sub infix:«>»(Num:D, Num:D)
    multi sub infix:«>»(Real:D, Real:D)

Coerces both arguments to L<Real> (if necessary), and returns C<True> if the first argument
is larger than the second.

=head2 infix C«>=»

    proto sub infix:«>=»(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:«>=»(Int:D, Int:D)
    multi sub infix:«>=»(Num:D, Num:D)
    multi sub infix:«>=»(Real:D, Real:D)

Coerces both arguments to L<Real> (if necessary), and returns C<True> if
the first argument is larger than or equal to the second.

=head2 infix C«eq»

    proto sub infix:<eq>(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:<eq>(Any,   Any)
    multi sub infix:<eq>(Str:D, Str:D)

Coerces both arguments to L<Str> (if necessary), and returns C<True> if both
are equal.

Mnemonic: I<equal>

=head2 infix C«ne»

    proto sub infix:<ne>(Mu, Mu) returns Bool:D is assoc<chain>
    multi sub infix:<ne>(Mu,    Mu)
    multi sub infix:<ne>(Str:D, Str:D)

Coerces both arguments to L<Str> (if necessary), and returns C<False> if both
are equal.

Mnemonic: I<not equal>

=head2 infix C«gt»

    proto sub infix:<gt>(Mu, Mu) returns Bool:D is assoc<chain>
    multi sub infix:<gt>(Mu,    Mu)
    multi sub infix:<gt>(Str:D, Str:D)

Coerces both arguments to L<Str> (if necessary), and returns C<True> if
the first is larger than the second, as determined by lexicographic
comparison.

Mnemonic: I<greater than>

=head2 infix C«ge»

    proto sub infix:<ge>(Mu, Mu) returns Bool:D is assoc<chain>
    multi sub infix:<ge>(Mu,    Mu)
    multi sub infix:<ge>(Str:D, Str:D)

Coerces both arguments to L<Str> (if necessary), and returns C<True> if
the first is equal to or larger than the second, as determined by lexicographic
comparison.

Mnemonic: I<greater or equal>

=head2 infix C«lt»

    proto sub infix:<lt>(Mu, Mu) returns Bool:D is assoc<chain>
    multi sub infix:<lt>(Mu,    Mu)
    multi sub infix:<lt>(Str:D, Str:D)

Coerces both arguments to L<Str> (if necessary), and returns C<True> if
the first is smaller than the second, as determined by lexicographic
comparison.

Mnemonic: I<less than>

=head2 infix C«le»

    proto sub infix:<le>(Mu, Mu) returns Bool:D is assoc<chain>
    multi sub infix:<le>(Mu,    Mu)
    multi sub infix:<le>(Str:D, Str:D)

Coerces both arguments to L<Str> (if necessary), and returns C<True> if
the first is equal to or smaller than the second, as determined by lexicographic
comparison.

Mnemonic: I<less or equal>

=head2 infix C«before»

    proto sub infix:<before>(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:<before>(Any,       Any)
    multi sub infix:<before>(Real:D,    Real:D)
    multi sub infix:<before>(Str:D,     Str:D)
    multi sub infix:<before>(Version:D, Version:D)

Generic ordering, uses the same semantics as L<cmp|#infix cmp>.
Returns C<True> if the first argument is smaller than the second.

=head2 infix C«after»

    proto sub infix:<after>(Any, Any) returns Bool:D is assoc<chain>
    multi sub infix:<after>(Any,       Any)
    multi sub infix:<after>(Real:D,    Real:D)
    multi sub infix:<after>(Str:D,     Str:D)
    multi sub infix:<after>(Version:D, Version:D)

Generic ordering, uses the same semantics as L<cmp|#infix cmp>.
Returns C<True> if the first argument is larger than the second.

=head2 infix C«eqv»

    proto sub infix:<eqv>(Any, Any) returns Bool:D is assoc<chain>
    proto sub infix:<eqv>(Any, Any)

Equivalence operator. Returns C<True> if the two arguments are structurally
the same, i.e. from the same type and (recursively) contain the same values.

    say [1, 2, 3] eqv [1, 2, 3];        # True
    say Any eqv Any;                    # True
    say 1 eqv 2;                        # False
    say 1 eqv 1.0;                      # False

For arbitrary objects this is not possible with the default C<eqv> operator.
E.g., C<eqv> will not consider two instances of the same object as being
structurally equivalent:

    class A {
        has $.a;
    }
    say A.new(a => 5) eqv A.new(a => 5);  #=> False

To get C<eqv> semantics for objects of this class, one would need to
implement an appropriate infix C<eqv> operator:

    class A {
        has $.a;
    }
    multi infix:<eqv>(A $l, A $r) { $l.a eqv $r.a }
    say A.new(a => 5) eqv A.new(a => 5);  #=> True

=head2 infix C«===»

    proto sub infix:<===>(Any, Any) returns Bool:D is assoc<chain>
    proto sub infix:<===>(Any, Any)

Value identity. Returns C<True> if both arguments are the same object.

    class A { };
    my $a = A.new;
    say $a === $a;              # True
    say A.new === A.new;        # False
    say A === A;                # True

For value types, C<===> behaves like C<eqv>:

    say 'a' === 'a';            # True
    say 'a' === 'b';            # False

    # different types
    say 1 === 1.0;              # False

C<===> uses the L<WHICH> method to obtain the object identity, so all value
types must override method C<WHICH>.

=head2 infix C«=:=»

    proto sub infix:<=:=>(Mu \a, Mu \b) returns Bool:D is assoc<chain>
    multi sub infix:<=:=>(Mu \a, Mu \b)

Container identity. Returns L<True> if both arguments are bound to the same
container. If it returns C<True>, it generally means that modifying one will
also modify the other.

    my ($a, $b) = (1, 3);
    say $a =:= $b;      # False
    $b = 2;
    say $a;             # 1
    $b := $a;
    say $a =:= $b;      # True
    $a = 5;
    say $b;             # 5

=head2 infix C«~~»

The smart-match operator. Aliases the left-hand side to C<$_>, then evaluates
the right-hand side, and calls C<.ACCEPTS($_)> on it. The semantics are left
to the type of the right-hand side operand.

Here is an excerpt of built-in smart-matching functionality:

=begin table

    Right-hand side     Comparison semantics
    ===============     ====================
    Mu:U                type check
    Str                 string equality
    Numeric             numeric equality
    Regex               regex match
    Callable            boolean result of invocation
    Any:D               object identity

=end table

=head1 Tight AND Precedence

=head2 infix C«&&»

Returns the first argument that evaluates to C<False> in boolean context,
or otherwise the last argument.

Note that this short-circuits, i.e. if one of the arguments evaluates to a
false value, the arguments to the right of are never evaluated.

    sub a { 1 }
    sub b { 0 }
    sub c { die "never called" };
    say a() && b() && c();      # 0

=head1 Tight OR Precedence

=head2 infix C«||»

Returns the first argument that evaluates to C<True> in boolean context,
or otherwise the last argument.

Note that this short-circuits, i.e. if one of the arguments evaluates to a
true value, the arguments to the right of are never evaluated.

    sub a { 0 }
    sub b { 1 }
    sub c { die "never called" };
    say a() || b() || c();      # 1

=head2 infix C«^^»

Returns the first true argument if there is only one, and L<Nil> otherwise.
Short-circuits as soon as two true arguments are found.

    say 0 ^^ 42;                # 42
    say 0 ^^ 42 ^^ 1 ^^ die 8;  # (empty line)

Note that the semantics of this operator may not be what you assume: infix C«^^»
flips to first true value it finds, and then flips to Nil I<forever> after the
second, no matter how many more true values there are. (In other words, it has
"find the one true value" semantics, not "boolean parity" semantics.)

=head2 infix C«//»

Defined-or operator. Returns the first defined operand, or else the last
operand. Short-circuits.

    say Any // 0 // 42;         # 0

=head2 infix C«min»

Returns the smallest of the arguments, as determined by L<cmp> semantics.

    $foo min= 0  # read as: $foo decreases to 0

=head2 infix C«max»

Returns the largest of the arguments, as determined by L<cmp> semantics.

    $foo max= 0  # read as: $foo increases to 0

=head1 Conditional Operator Precedence

=head2 infix C<?? !!>

Ternary operator, conditional operator.

C<$condition ?? $true !! $false> evaluates and returns the expression from the
C<$true> branch if C<$condition> is a true value. Otherwise it evaluates and
returns the C<$false> branch.

=head2 infix C«ff»

    sub infix:<ff>(Mu $a, Mu $b)

Flipflop operator.

Compares both arguments to C<$_> (that is, C<$_ ~~ $a> and C<$_ ~~
$b>). Evaluates to C<False> until the left-hand smartmatch is C<True>, at which
point it evaluates to C<True> until the right-hand smartmatch is C<True>.

In effect, the left-hand argument is the "start" condition, and the right-hand
is the "stop" condition. This construct is typically used to pick up only a
certain section of lines. For example:

=begin code :allow<B V>
    my $excerpt = q:to/END/;
    Here's some unimportant text.
    V<=>begin code
        This code block is what we're after.
        We'll use 'ff' to get it.
    V<=>end code
    More unimportant text.
    END

    my @codelines = gather for $excerpt.lines {
        take $_ if B<"=begin code" ff "=end code">
    }

    # this will print four lines, starting with "=begin code" and ending with
    # "=end code"
    say @codelines.join("\n");
=end code

After matching the start condition, the operator will then match the same C<$_>
to the stop condition, and act accordingly if successful. In this example, only
the first element is printed:

    for <AB C D B E F> {
        say $_ if /A/ ff /B/;  # prints only "AB"
    }

If you only want to test against a start condition, and have no stop condition,
C<*> can be used as the "stop" condition.

    for <A B C D E> {
        say $_ if /C/ ff *; # prints C, D, and E
    }

For the sed-like version, which does I<not> try C<$_> on the stop condition
after succeeding on the start condition, see L<C<fff>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«^ff»

    sub infix:<^ff>(Mu $a, Mu $b)

Works like L<C<ff>>, except it does not return C<True> for items matching the
start condition (including items also matching the stop condition).

A comparison:

    my @list = <A B C>;
    say $_ if /A/ ff /C/ for @list;  # prints A, B, and C
    say $_ if /A/ ^ff /C/ for @list; # prints B and C

The sed-like version can be found in L<C<^fff>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«ff^»

    sub infix:<ff^>(Mu $a, Mu $b)

Works like L<C<ff>>, except it does not return C<True> for items matching the
stop condition (including items that first matched the start condition).

    my @list = <A B C>;
    say $_ if /A/ ff /C/ for @list;  # prints A, B, and C
    say $_ if /A/ ff^ /C/ for @list; # prints A and B

The sed-like version can be found in L<C<fff^>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«^ff^»

    sub infix:<^ff^>(Mu $a, Mu $b)

Works like L<C<ff>>, except it does not return C<True> for items matching either
the stop or start condition (or both).

    my @list = <A B C>;
    say $_ if /A/ ff /C/ for @list;  # prints A, B, and C
    say $_ if /A/ ^ff^ /C/ for @list; # prints B

The sed-like version can be found in L<C<^fff^>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«fff»

    sub infix:<fff>(Mu $a, Mu $b)

Performs a sed-like flipflop operation, wherein it returns C<False> until the
left argument smartmatches against C<$_>, and after that returns C<True> until
the right argument smartmatches against C<$_>.

Works similarly to L<C<ff>>, except that it only tries one argument per
invocation. That is, if C<$_> smartmatches the left argument, C<fff> will B<not>
then try to match that same C<$_> against the right argument.

    for <AB C D B E F> {
        say $_ if /A/ fff /B/;  # Prints "AB", "C", "D", and "B"
    }

The non-sed-like flipflop (which after successfully matching the left argument
against C<$_> will try that same C<$_> against the right argument and act
accordingly), see L<C<ff>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«^fff»

    sub infix:<^fff>(Mu $a, Mu $b)

Like L<C<fff>>, except it does not return true for matches to the left argument.

    my @list = <A B C>;
    say $_ if /A/ fff /C/ for @list;  # prints A, B, and C
    say $_ if /A/ ^fff /C/ for @list; # prints B and C

For the non-sed version, see L<C<^ff>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«fff^»

    sub infix:<fff^>(Mu $a, Mu $b)

Like L<C<fff>>, except it does not return true for matches to the right argument.

    my @list = <A B C>;
    say $_ if /A/ fff /C/ for @list;  # prints A, B, and C
    say $_ if /A/ fff^ /C/ for @list; # prints A and B

For the non-sed version, see L<C<ff^>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head2 infix C«^fff^»

    sub infix:<^fff^>(Mu $a, Mu $b)

Like L<C<fff>>, except it does not return true for matches to either the left or
right argument.

    my @list = <A B C>;
    say $_ if /A/ fff /C/ for @list;  # prints A, B, and C
    say $_ if /A/ ^fff^ /C/ for @list; # prints B

For the non-sed version, see L<C<^ff^>>.

This operator cannot be overloaded, as it is handled specially by the compiler.

=head1 Item Assignment Precedence

=head2 infix C«=»

    sub infix:<=>(Mu $a is rw, Mu $b)

Item assignment.

Places the value of the right-hand side into the container on the left-hand
side. Its exact semantics are left to the container type on the left-hand side.

(Note that item assignment and list assignment have different precedence
levels, and the syntax of the left-hand side decides whether an equal sign
C<=> is parsed as item assignment or list assignment operator).

=head2 infix C«=>»

    sub infix:«=>»($key, Mu $value) returns Pair:D

L<Pair> constructor.

Constructs a L<Pair> object with the left-hand side as the key and the
right-hand side as the value.

Note that the C<< => >> operator is syntactically special-cased, in that
it allows unquoted identifier on the left-hand side.

    my $p = a => 1;
    say $p.key;         # a
    say $p.value;       # 1

A L<Pair> within an argument list with an unquoted identifier on the left
is interpreted as a named argument.

See L<the Terms language documentation|/language/terms#Pair> for more ways to
create C<Pair> objects.

=head1 Loose Unary Precedence

=head2 prefix C«not»

    multi sub prefix:<not>(Mu $x) returns Bool:D

Evaluates its argument in boolean context (and thus collapses L<Junction>s),
and negates the result.

=head2 prefix C«so»

    multi sub prefix:<so>(Mu $x) returns Bool:D

Evaluates its argument in boolean context (and thus collapses L<Junction>s),
and returns the result.

=head1 Comma Operator Precedence

=head2 infix C«,»

    sub infix:<,>(*@a) is assoc<list> returns List:D

Constructs a L<List> from its arguments. Also used syntactically as the
separator of arguments in calls.

=head2 infix C«:»

Used as an argument separator just like infix C<,> and marks the argument to
its left as the invocant. That turns what would otherwise be a function call
into a method call.

    substr('abc': 1);       # same as 'abc'.substr(1)

Infix C<:> is only allowed after the first argument of a non-method call. In
other positions it is a syntax error.

=head1 List Infix Precedence

=head2 infix C«Z»

    sub infix:<Z>(**@lists) returns List:D is assoc<chain>

Zip operator.

Interleaves the lists passed to C<Z> like a zipper, stopping as soon as
the first input list is exhausted:

    say (1, 2 Z <a b c> Z <+ ->).perl;  #=> ((1, "a", "+"), (2, "b", "-")).Seq

The C<Z> operator also exists as a meta operator, in which case the inner
lists are replaced by the value from applying the meta'ed operator to the
list:

    say 100, 200 Z+ 42, 23;             #=> (142 223)
    say 1..3 Z~ <a b c> Z~ 'x' xx 3;    #=> (1ax 2bx 3cx)

=head2 infix C«X»

    sub infix:<X>(**@lists) returns List:D is assoc<chain>

Creates a cross product from all the lists, order so that the rightmost
elements vary most rapidly

    1..3 X <a b c> X 9
    # produces ((1 a 9) (1 b 9) (1 c 9)
    #           (2 a 9) (2 b 9) (2 c 9)
    #           (3 a 9) (3 b 9) (3 c 9))

The C<X> operator also exists as a meta operator, in which case the inner
lists are replaced by the value from applying the meta'ed operator to the
list:

    1..3 X~ <a b c> X~ 9
    # produces (1a9 1b9 1c9 2a9 2b9 2c9 3a9 3b9 3c9)

=head2 infix C«...»

    multi sub infix:<...>(**@) is assoc<list>
    multi sub infix:<...^>(**@) is assoc<list>

The sequence operator is a generic operator to produce lazy lists.

It can have initial elements and a generator on left-hand side, and an
endpoint on the right-hand side.

The sequence operator invokes the generator with as many arguments as
necessary. The arguments are taken from the initial elements and the already
generated elements.

The default generator is C<*.>L<succ> or C<*.>L<pred>, depending on how
the end points compare:

    say 1 ... 4;        # 1 2 3 4
    say 4 ... 1;        # 4 3 2 1
    say 'a' ... 'e';    # a b c d e
    say 'e' ... 'a';    # e d c b a

An endpoint of C<*> (L<Whatever>) generates an infinite sequence,
with a default generator of *.succ

    say (1 ... *)[^5];  # 1 2 3 4 5


Custom generators are the last argument before the '...' operator.
This one takes two arguments, and generates the Fibonacci numbers

    say (1, 1, -> $a, $b { $a + $b } ... *)[^8];    # 1 1 2 3 5 8 13 21
    # same but shorter
    say (1, 1, *+* ... *)[^8];                      # 1 1 2 3 5 8 13 21

Of course the generator can also take only one argument.

    say 5, { $_ * 2 } ... 40;                       # 5 10 20 40

There must be at least as many initial elements as arguments to the generator.

Without a generator, and more than one initial element, and all initial
elements numeric, the sequence operator tries to deduce the generator. It
knows about arithmetic and geometric sequences.

    say 2, 4, 6 ... 12;     # 2 4 6 8 10 12
    say 1, 2, 4 ... 32;     # 1 2 4 8 16 32

If the endpoint is not C<*>, it is smart-matched against each generated
element, and the sequence is terminated when the smart-match succeeded.
For the C<...> operator, the final element is included, for the C<...^>
operator it is excluded.

This allows you to write

    say 1, 1, *+* ...^ *>= 100;

To generate all Fibonacci numbers up to but excluding 100.

The C<...> operators consider the initial values as "generated elements" as
well, so the are also checked against the endpoint:

    my $end = 4;
    say 1, 2, 4, 8, 16 ... $end;
    # outputs 1 2 4

=head1 List Prefix Precedence

=head2 infix C«=»

List assignment. Its exact semantics are left to the container type on the
left-hand side. See L<Array> and L<Hash> for common cases.

The distinction between item assignment and list assignment is determined by
the parser depending on the syntax of the left-hand side.

=head2 infix C«:=»

Binding. Whereas C<$x = $y> puts the value in C<$y> into C<$x>, C<$x :=
$y> makes C<$x> and C<$y> the same thing.

    =for code :allow<B L>
    my $a = 42;
    my $b B<=> $a;
    $bL<++>;
    say $a;

This will output 42, because C<$a> and C<$b> both contained the number
C<42>, but the L<containers|/language/containers.html#Binding> were
different.

    =for code :allow<B L>
    my $a = 42;
    my $b B<:=> $a;
    $bL<++>;
    say $a;

This will output 43, since C<$b> and C<$a> both represented the same
object.

=head2 infix C«::=»

Read-only binding. See L<C<infix :=>|:=>.

=head2 listop C«...»

The I<yada, yada, yada> operator or I<stub> operator. If it is the only
statement in a routine or type, it marks that routine or type as a stub
(which is significant in the context of pre-declaring types and composing
roles).

If the C<...> statement is executed, it calls L<&fail>, with the default
message C<stub code executed>.

=head2 listop C«!!!»

If it is the only
statement in a routine or type, it marks that routine or type as a stub
(which is significant in the context of pre-declaring types and composing
roles).

If the C<!!!> statement is executed, it calls L<&die>, with the default
message C<stub code executed>.

=head2 listop C«???»

If it is the only
statement in a routine or type, it marks that routine or type as a stub
(which is significant in the context of pre-declaring types and composing
roles).

If the C<???> statement is executed, it calls L<&warn>, with the default
message C<stub code executed>.

=head2 Reduction operators

Any infix operator (except for non-associating operators) can be
surrounded by square brackets in term position to create a list operator
that reduces using that operation.

=begin code

    [+] 1, 2, 3;      # 1 + 2 + 3 = 6
    my @a = (5,6);
    [*] @a;           # 5 * 6 = 30

=end code

Reduction operators have the same associativity as the operators they are based on.

=begin code

    [-] 4, 3, 2;      # 4-3-2 = (4-3)-2 = -1
    [**] 4, 3, 2;     # 4**3**2 = 4**(3**2) = 262144

=end code

=head1 Loose AND precedence

=head2 infix C«and»

Same as L<#infix &&>, except with looser precedence.

Returns the first operand that evaluates to C<False> in boolean context, or
otherwise the last operand. Short-circuits.

=head2 infix C«andthen»

Returns the first undefined argument, otherwise the last argument.
Short-circuits.  The result of the left side is bound to $_ for the
right side, or passed as arguments if the right side is a block or
pointy block.

=head1 Loose OR Precedence

=head2 infix C«or»

Same as C<infix ||>, except with looser precedence.

Returns the first argument that evaluates to C<True> in boolean context,
or otherwise the last argument. Short-circuits.

=head2 infix C«orelse»

Same as C<infix //>, except with looser precedence.

Returns the first defined argument, or else the last argument.
Short-circuits.

=end pod

# vim: expandtab shiftwidth=4 ft=perl6
