This page was generated at 2009-07-03 01:01:23 GMT.
(syn r27372, pugs-smoke 19912)
  [ Index of Synopses ]

 =encoding ALREADYDONE

TITLE

Synopsis 3: Perl 6 Operators

AUTHORS

    Luke Palmer <luke@luqui.org>
    Larry Wall <larry@wall.org>

VERSION

    Created: 8 Mar 2004
    Last Modified: 10 Jun 2009
    Version: 168

Overview

For a summary of the changes from Perl 5, see "Changes to Perl 5 operators".

Operator precedence

From t/spec/S03-operators/arith.t lines 48–430 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/precedence.t lines 5–207 (no results): (skip)

  Highlighted: small|full

Not counting terms and terminators, Perl 6 has 23 operator precedence levels (same as Perl 5, but differently arranged). Here we list the levels from "tightest" to "loosest", along with a few examples of each level:

    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
    L  Additive          + - +| +^ ~| ~^ ?| ?^
    L  Replication       x xx
    X  Concatenation     ~
    X  Junctive and      & also
    X  Junctive or       | ^
    L  Named unary       sleep abs sin temp let
    N  Nonchaining 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       true not
    X  Comma operator    , p5=> :
    X  List infix        Z minmax X X~ X* Xeqv ...
    R  List prefix       print push say die map substr ... [+] [*] any $ @
    X  Loose and         and andthen
    X  Loose or          or xor orelse
    X  Sequencer         <==, ==>, <<==, ==>>
    N  Terminator        ; {...}, unless, extra ), ], }

Using two ! 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:

        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)

For unaries this is interpreted as:

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

(In standard Perl there are no unaries that can take advantage of associativity, since at each precedence level the standard operators are either consistently prefix or postfix.)

Note that list associativity (X) only works between identical operators. If two different list-associative operators have the same precedence, they are assumed to be right-associative with respect to each other. For example, the X cross operator and the Z zip operator both have a precedence of "list infix", but:

    @a X @b Z @c

is parsed as:

    @a X (@b Z @c)

Similarly, if the only implementation of a list-associative operator is binary, it will be treated as right associative.

The standard precedence levels attempt to be consistent in their associativity, but user-defined operators and precedence levels may mix right and left associative operators at the same precedence level. If two conflicting operators are used ambiguously in the same expression, the operators will be considered non-associative with respect to each other, and parentheses must be used to disambiguoate.

If you don't see your favorite operator above, the following sections cover all the operators in precedence order. Basic operator descriptions are here; special topics are covered afterwards.

Term precedence

This isn't really a precedence level, but it's in here because no operator can have tighter precedence than a term. See S02 for longer descriptions of various terms. Here are some examples.

Method postfix precedence

All method postfixes start with a dot, though the dot is optional for subscripts. Since these are the tightest standard operator, you can often think of a series of method calls as a single term that merely expresses a complicated name.

See S12 for more discussion of single dispatch method calls.

Autoincrement precedence

From t/spec/S03-operators/increment.t lines 7–104 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/overflow.t lines 7–79 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/autoincrement.t lines 9–51 (30 √, 0 ×): (skip)

  Highlighted: small|full

As in C, these operators increment or decrement the object in question either before or after the value is taken from the object, depending on whether it is put before or after. Also as in C, multiple references to a single mutating object in the same expression may result in undefined behavior unless some explicit sequencing operator is interposed. See "Sequence points".

As with all postfix operators in Perl 6, no space is allowed between a term and its postfix. See S02 for why, and for how to work around the restriction with an "unspace".

As mutating methods, all these operators dispatch to the type of the operand and return a result of the same type, but they are legal on value types only if the (immutable) value is stored in a mutable container. However, a bare undefined value (in a suitable Scalar container) is allowed to mutate itself into an Int in order to support the common idiom:

    say $x unless %seen{$x}++;

Increment of a Str (in a suitable container) works similarly to Perl 5, but is generalized slightly. A scan is made for the final alphanumeric sequence in the string that is not preceded by a '.' character. Unlike in Perl 5, this alphanumeric sequence need not be anchored to the beginning of the string, nor does it need to begin with an alphabetic character; the final sequence in the string matching <!after '.'> <rangechar>+ is incremented regardless of what comes before it.

From t/spec/S03-operators/autoincrement.t lines 52–177 (8 √, 4 ×): (skip)

  Highlighted: small|full

From t/spec/S03-operators/autoincrement.t lines 178–191 (no results): (skip)

  Highlighted: small|full

The <rangechar> character class is defined as that subset of characters that Perl knows how to increment within a range, as defined below.

The additional matching behaviors provide two useful benefits: for its typical use of incrementing a filename, you don't have to worry about the path name or the extension:

    $file = "/tmp/pix000.jpg";
    $file++;            # /tmp/pix001.jpg, not /tmp/pix000.jph

Perhaps more to the point, if you happen to increment a string that ends with a decimal number, it's likely to do the right thing:

    $num = "123.456";
    $num++;             # 124.456, not 123.457

Character positions are incremented within their natural range for any Unicode range that is deemed to represent the digits 0..9 or that is deemed to be a complete cyclical alphabet for (one case of) a (Unicode) script. Only scripts that represent their alphabet in codepoints that form a cycle independent of other alphabets may be so used. (This specification defers to the users of such a script for determining the proper cycle of letters.) We arbitrarily define the ASCII alphabet not to intersect with other scripts that make use of characters in that range, but alphabets that intersperse ASCII letters are not allowed.

If the current character in a string position is the final character in such a range, it wraps to the first character of the range and sends a "carry" to the position left of it, and that position is then incremented in its own range. If and only if the leftmost position is exhausted in its range, an additional character of the same range is inserted to hold the carry in the same fashion as Perl 5, so incrementing '(zz99)' turns into '(aaa00)' and incrementing '(99zz)' turns into '(100aa)'.

The following Unicode ranges are some of the possible rangechar ranges. For alphabets we might have ranges like:

    A..Z        # ASCII uc
    a..z        # ASCII lc
    Α..Ω        # Greek uc
    α..ω        # Greek lc (presumably skipping U+03C2, final sigma)
    א..ת        # Hebrew
      etc.      # (XXX out of my depth here)

For digits we have ranges like:

    0..9        # ASCII
    ٠..٩        # Arabic-Indic
    ०..९        # Devangari
    ০..৯        # Bengali 
    ੦..੯        # Gurmukhi
    ૦..૯        # Gujarati
    ୦..୯        # Oriya
      etc.

Other non-script 0..9 ranges may also be incremented, such as

    ⁰..⁹        # superscripts (note, cycle includes latin-1 chars)
    ₀..₉        # subscripts
    0..9      # fullwidth digits

Conjecturally, any common sequence may be treated as a cycle even if it does not represent 0..9:

    Ⅰ..Ⅻ        # clock roman numerals uc
    ⅰ..ⅻ        # clock roman numerals lc
    ①..⑳        # circled digits 1..20
    ⒜..⒵        # parenthesize lc
    ⚀..⚅        # die faces 1..6
    ❶..❿        # dingbat negative circled 1..10
      etc.

While it doesn't really make sense to "carry" such numbers when they reach the end of their cycle, treating such values as incrementable may be convenient for writing outlines and similar numbered bullet items. (Note that we can't just increment unrecognized characters, because we have to locate the string's final sequence of rangechars before knowing which portion of the string to increment. Note also that all character increments can be handled by lookup in a single table of successors since we've defined our ranges not to include overlapping cycles.)

Perl 6 also supports Str decrement with similar semantics, simply by running the cycles the other direction. However, leftmost characters are never removed, and the decrement fails when you reach a string like "aaa" or "000".

Increment and decrement on non-<Str> types are defined in terms of the .succ and .pred methods on the type of object in the Scalar container. More specifically,

    ++$var
    --$var

are equivalent to

    $var.=succ
    $var.=pred

If the type does not support these methods, the corresponding increment or decrement operation will fail. (The optimizer is allowed to assume that the ordinary increment and decrement operations on integers will not be overridden.)

Increment of a Bool (in a suitable container) turns it true. Decrement turns it false regardless of how many times it was previously incremented. This is useful if your %seen array is actually a KeySet, in which case decrement actually deletes it from the KeySet.

Exponentiation precedence

Symbolic unary precedence

Multiplicative precedence

Any bit shift operator may be turned into a rotate operator with the :rotate adverb. If :rotate is specified, the concept of sign extension is meaningless, and you may not specify a :signed adverb.

Additive precedence

Replication

Concatenation

From t/spec/S03-operators/misc.t lines 17–19 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/misc.t lines 49–53 (no results): (skip)

  Highlighted: small|full

Junctive and (all) precedence

Junctive or (any) precedence

Named unary precedence

Functions of one argument

    sleep
    abs
    sin
    ...         # see S29 Functions

Note that, unlike in Perl 5, you must use the .meth forms to default to $_ in Perl 6.

There is no unary rand prefix in Perl 6, though there is a .rand method call and an argumentless rand term. There is no unary int prefix either; you must use a typecast to a type such as Int or int. (Typecasts require parentheses and may not be used as prefix operators.) In other words:

    my $i = int $x;   # ILLEGAL

From t/spec/S03-operators/precedence.t lines 208–213 (no results): (skip)

  Highlighted: small|full

is a syntax error (two terms in a row), because int is a type name now.

Nonchaining binary precedence

Chaining binary precedence

From t/spec/S03-operators/equality.t lines 10–41 (15 √, 0 ×): (skip)

  Highlighted: small|full

From t/spec/S03-operators/relational.t lines 9–81 (36 √, 0 ×): (skip)

  Highlighted: small|full

All operators on this precedence level may be chained; see "Chained comparisons".

Tight and precedence

Tight or precedence

Conditional operator precedence

Adverbs

Operator adverbs are special-cased in the grammar, but give the appearance of being parsed as trailing unary operators at a pseudo-precedence level slightly tighter than item assignment. (They're not officially "postfix" operators because those require the absense of whitespace, and these allow whitespace. These adverbs insert themselves in the spot where the parser is expecting an infix operator, but the parser continues to look for an infix after parsing the adverb and applying it to the previous term.) Thus,

    $a < 1 and $b == 2 :carefully

does the == carefully, while

    $a < 1 && $b == 2 :carefully

does the && carefully because && is of tighter precedence than "comma". Use

    $a < 1 && ($b == 2 :carefully)

to apply the adverb to the == operator instead. We say that == is the "topmost" operator in the sense that it is at the top of the parse tree that the adverb could possibly apply to. (It could not apply outside the parens.) If you are unsure what the topmost operator is, just ask yourself which operator would be applied last. For instance, in

    +%hash{$key} :foo

The subscript happens first and the + operator happens last, so :foo would apply to that. Use

    +(%hash{$key} :foo)

to apply :foo to the subscripting operator instead.

Adverbs will generally attach the way you want when you say things like

    1 .. $x+2 :by(2)

The proposed internal testing syntax makes use of these precedence rules:

    $x eqv $y+2  :ok<$x is equivalent to $y+2>;

Here the adverb is considered to be modifying the eqv operator.

Item assignment precedence

From t/spec/S03-operators/binding-nested.t lines 5–340 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/binding-arrays.t lines 5–228 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/binding-attributes.t lines 4–80 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/binding-subs.t lines 7–113 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/binding-hashes.t lines 5–183 (no results): (skip)

  Highlighted: small|full

Loose unary precedence

From t/spec/S03-operators/true.t lines 5–20 (no results): (skip)

  Highlighted: small|full

From t/spec/S03-operators/not.t lines 13–30 (no results): (skip)

  Highlighted: small|full

Comma operator precedence

List infix precedence

List infixes all have list associativity, which means that identical infix operators work together in parallel rather than one after the other. Non-identical operators are considered non-associative and must be parenthesized for clarity.

Many of these operators return a list of Captures, which depending on context may or may not flatten them all out into one flat list. The default is to flatten, but see the contextualizers below.

List prefix precedence

Loose and precedence

Loose or precedence

Terminator precedence

As with terms, terminators are not really a precedence level, but looser than the loosest precedence level. They all have the effect of terminating any operator precedence parsing and returning a complete expression to the main parser. They don't care what state the operator precedence parser is in. If the parser is currently expecting a term and the final operator in the expression can't deal with a nullterm, then it's a syntax error. (Notably, the comma operator and many prefix list operators can handle a nullterm.)

Changes to Perl 5 operators

From t/spec/S03-operators/scalar-assign.t lines 8–26 (no results): (skip)

  Highlighted: small|full

Several operators have been given new names to increase clarity and better Huffman-code the language, while others have changed precedence.