=encoding ALREADYDONE
Synopsis 3: Perl 6 Operators
Luke Palmer <luke@luqui.org>
Larry Wall <larry@wall.org>
Created: 8 Mar 2004
Last Modified: 10 Jun 2009
Version: 168
For a summary of the changes from Perl 5, see "Changes to Perl 5 operators".
From t/spec/S03-operators/arith.t lines 48–430 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/precedence.t lines 5–207 (no results): (skip)
Highlighted: small|fullNot 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.
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.
Int literal
42
Num literal
3.14
Str literal
'$100'
Str literal
"Answer = $answer\n"
Str literal
q["$100"]
qq["$answer"]
qq:to/END/
Dear $recipient:
Thanks!
Sincerely,
$me
END
[1,2,3]
Provides list context inside. (Technically, it really provides a "semilist" context, which is a semicolon-separated list of statements, each of which is interpreted in list context and then concatenated into the final list.)
{ }
{ a => 42 }
Inside must be either empty, or a single list starting with a pair or a hash, otherwise you must use hash() or %() instead.
{ ... }
When found where a statement is expected, executes immediately. Otherwise always defers evaluation of the inside scope.
\(@a,$b,%c)
An abstraction representing an argument list that doesn't yet know its context.
$x
@y
%z
$^a
$?FILE
@@slice
&func
&div:(Int, Int --> Int)
$()
@()
%()
&()
@@()
/abc/
rx:i[abc]
s/foo/bar/
tr/a..z/A..Z/
Note ranges use .. rather than -.
Num
::Some::Package
(1+2)
Parentheses are parsed on the inside as a semicolon-separated list of statements, which (unlike the statements in a block) returns the results of all the statements concatenated together as a List of Capture. How that is subsequently treated depends on its eventual binding.
a(1)
In term position, any identifier followed immediately by a parenthesized expression is always parsed as a term representing a function call even if that identifier also has a prefix meaning, so you never have to worry about precedence in that case. Hence:
not($x) + 1 # means (not $x) + 1
abs($x) + 1 # means (abs $x) + 1
:by(2)
:!verbose
:(Dog $self:)
.meth # call on $_
.=meth # modify $_
Note that this may occur only where a term is expected. Where a postfix is expected, it is a postfix. If only an infix is expected (that is, after a term with intervening whitespace), .meth is a syntax error. (The .=meth form is allowed there only because there is a special .= infix assignment operator that is equivalent in semantics to the method call form but that allows whitespace between the = and the method name.)
4,3, sort 2,1 # 4,3,1,2
As in Perl 5, a list operator looks like a term to the expression on its left, so it binds tighter than comma on the left but looser than comma on the right--see List prefix precedence below.
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.
$obj.meth
$obj.+meth
$obj.?meth
$obj.*meth
In addition to the ordinary . method invocation, there are variants .*, .?, and .+ to control how multiple related methods of the same name are handled.
$obj.::Class::meth
$obj.Class::meth # same thing, assuming Class is predeclared
As in Perl 5, tells the dispatcher which class to start searching from, not the exact method to call.
$obj.=meth
The .= operator does inplace modification of the object on the left.
$obj.^meth
The .^ operator calls a class metamethod; foo.^bar is short for foo.HOW.bar.
$routine.()
$array.[]
$hash.{}
$hash.<>
$hash.«»
The dotless forms of these have exactly the same precedences.
$x.++ # postfix:<++>($x)
$x.:<++> # prefix:<++>($x)
infix:<.> operator, so
$foo . $bar
will always result in a compile-time error indicating the user should use infix:<~> instead. This is to catch an error likely to be made by Perl 5 programmers learning Perl 6.
From t/spec/S03-operators/increment.t lines 7–104 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/overflow.t lines 7–79 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/autoincrement.t lines 9–51 (30 √, 0 ×): (skip)
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)
From t/spec/S03-operators/autoincrement.t lines 178–191 (no results): (skip)
Highlighted: small|fullThe <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.
prefix:<++> or postfix:<++> operator
$x++
++$x;
prefix:<--> or postfix:<--> operator
$x--
--$x
infix:<**> exponentiation operator
$x ** 2
If the right argument is not a non-negative integer, the result is likely to be an approximation. If the right argument is of an integer type, exponentiation is at least as accurate as repeated multiplication on the left side's type. (From which it can be deduced that Int**UInt is always exact, since Int supports arbitrary precision.) If the right argument is an integer represented in a non-integer type, the accuracy is left to implementation provided by that type; there is no requirement to recognize an integer to give it special treatment.
prefix:<?>, boolean context
?$x
Evaluates the expression as a boolean and returns True if expression is true or False otherwise. See "true" below for a low-precedence alternative.
prefix:<!>, boolean negation
From t/spec/S03-operators/context-forcers.t lines 138–198 (no results): (skip)
Highlighted: small|full!$x
Returns the opposite of what ? would. See "not" below for a low-precedence alternative.
prefix:<+>, numeric context
+$x
Unlike in Perl 5, where + is a no-op, this operator coerces to numeric context in Perl 6. (It coerces only the value, not the original variable.) For values that are not already considered numeric, the narrowest appropriate type of Int, Num, or Complex will be returned; however, string containing two integers separated by a / will be returned as a Rat. Exponential notation and radix notations are recognized.
prefix:<->, numeric negation
From t/spec/S03-operators/context-forcers.t lines 79–91 (no results): (skip)
Highlighted: small|full-$x
Coerces to numeric and returns the arithmetic negation of the resulting number.
prefix:<~>, string context
~$x
Coerces the value to a string. (It only coerces the value, not the original variable.)
prefix:<|>, flatten object into arglist
| $capture
Interpolates the contents of the Capture (or Capture-like) value into the current argument list as if they had been specified literally. If the first argument of the capture is marked as an invocant but is used in a context not expecting one, it is treated as an ordinary positional argument.
prefix:<+^>, numeric bitwise negation
+^$x
Coerces to integer and then does bitwise negation (complement) on the number.
prefix:<~^>, string bitwise negation
~^$x Coerces to string buffer and then does bitwise negation (complement) on each element.
prefix:<?^>, boolean bitwise negation
?^$x
Coerces to boolean and then flips the bit. (Same as !.)
prefix:<^>, upto operator
From t/spec/S03-operators/context-forcers.t lines 199–220 (no results): (skip)
Highlighted: small|full^$limit
Constructs a range of 0 ..^ $limit or locates a metaclass as a shortcut for $limit.HOW. See "Range and RangeIterator semantics".
infix:<*>
$x*$y
Multiplication, resulting in wider type of the two.
infix:</>
$numerator / $denominator
If either operand is of Num type, converts both operands to Num and does division returning Num. If the denominator is zero, returns an object representing either +Inf, NaN, or -Inf as the numerator is positive, zero, or negative. (This is construed as the best default in light of the operator's possible use within hyperoperators and junctions. Note however that these are not actually the native IEEE non-numbers; they are undefined values of the "unthrown exception" type that happen to represent the corresponding IEEE concepts, and if you subsequently try to use one of these values in a non-parallel computation, it will likely throw an exception at that point.)
If both operands are of integer type, you still get a Num, but the Num type is allowed to do the division lazily; internally it may store a Rat until the time a value is called for. If converted to Rat directly no division ever need be done.
infix:<div>, generic division
$numerator div $denominator
Dispatches to the infix:<div> multi most appropriate to the operand types. Policy on what to do about division by zero is up to the type, but for the sake of hyperoperators and junctions those types that can represent overflow (or that can contain an unthrown exception) should try to do so rather than simply throwing an exception. (And in general, other operators that might fail should also consider their use in hyperops and junctions, and whether they can profitably benefit from a lazy exception model.)
Use of div on two Int values results in a ratio of the Rat type.
infix:<%>, modulus
$x % $mod
Always floor semantics using Num or Int.
infix:<mod>, generic modulus
$x mod $mod
Dispatches to the infix:<mod> multi most appropriate to the operand types.
infix:{'+&'}, numeric bitwise and
$x +& $y
Converts both arguments to integer and does a bitwise numeric AND.
infix:{'+<'}, numeric shift left
$integer +< $bits
infix:{'+>'}, numeric shift right
$integer +> $bits
By default, signed types do sign extension, while unsigned types do not, but this may be enabled or disabled with a :signed or :!signed adverb.
infix:<~&>, buffer bitwise and
$x ~& $y
infix:{'~<'}, buffer bitwise shift left
$buf ~< $bits
infix:{'~>'}, buffer bitwise shift right
$buf ~> $bits
Sign extension is not done by default but may be enabled with a :signed adverb.
infix:<?&>, boolean bitwise and
$x ?& $y
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.
infix:<+>, numeric addition
$x + $y
Microeditorial: As with most of these operators, any coercion or type mismatch is actually handled by multiple dispatch. The intent is that all such variants preserve the notion of numeric addition to produce a numeric result, presumably stored in suitably "large" numeric type to hold the result. Do not overload the + operator for other purposes, such as concatenation. (And please do not overload the bitshift operators to do I/O.) In general we feel it is much better for you to make up a different operator than overload an existing operator for "off topic" uses. All of Unicode is available for this purpose.
infix:<->, numeric subtraction
$x - $y
infix:<+|>, numeric bitwise inclusive or
$x +| $y
infix:<+^> numeric bitwise exclusive or
$x +^ $y
infix:<~|>, buffer bitwise inclusive or
$x ~| $y
infix:<~^> buffer bitwise exclusive or
$x ~^ $y
infix:<?|>, boolean bitwise inclusive or
$x ?| $y
infix:<?^> boolean bitwise exclusive or
$x ?^ $y
infix:<x>, string/buffer replication
$string x $count
Evaluates the left argument in string context, replicates the resulting string value the number of times specified by the right argument and returns the result as a single concatenated string regardless of context.
If the count is less than 1, returns the null string. The count may not be * because Perl 6 does not support infinite strings. (At least, not yet...) Note, however, that an infinite string may be emulated with cat($string xx *).
infix:<xx>, list replication
@list xx $count
Evaluates the left argument in list context, replicates the resulting Capture value the number of times specified by the right argument and returns the result in a context dependent fashion. If the operator is being evaluated in ordinary list context, the operator returns a flattened list. In slice (@@) context, the operator converts each Capture to a separate sublist and returns the list of those sublists.
If the count is less than 1, returns the empty list, (). If the count is *, returns an infinite list (lazily, since lists are lazy by default).
From t/spec/S03-operators/misc.t lines 17–19 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/misc.t lines 49–53 (no results): (skip)
Highlighted: small|fullinfix:<~>, string/buffer concatenation
$x ~ $y
infix:<&>, all() operator
$a & $b & $c ...
infix:<also>, short-circuit junctional and operator
From t/spec/S03-operators/also.t lines 4–21 (no results): (skip)
Highlighted: small|fullEXPR also EXPR also EXPR ...
Can be used to construct ANDed patterns with the same semantics as infix:<&>, but with left-to-right evaluation guaranteed, for use in guarded patterns:
$target ~~ MyType also .mytest1 also .mytest2
This is useful when later tests might throw exceptions if earlier tests don't pass. This cannot be guaranteed by:
$target ~~ MyType & .mytest1 & .mytest2
infix:<|>, any() operator
$a | $b | $c ...
infix:<^>, one() operator
$a ^ $b ^ $c ...
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|fullis a syntax error (two terms in a row), because int is a type name now.
prefix:<int>
Coerces to type Int. Floor semantics are used for fractional values, including strings that appear to express fractional values. That is, int($x) must have the same result as int(+$x) in all cases. All implicit conversions to integer use the same semantics.
(Note that, despite the fact that int is a valid native type name, this function does not express conversion to that native type. Such subtype conversions are done automatically upon assignment to a subtyped container, and fail if the container cannot hold the value.)
prefix:<sleep>
Suspends the current thread of execution for the specified number of seconds, which may be fractional.
prefix:<abs>
Returns the absolute value of the specified argument.
infix:<but>
$value but Mixin
infix:<does>
$object does Mixin
$num1 <=> $num2
$str1 leg $str2
$obj1 cmp $obj2
These operators compare their operands using numeric, string, or eqv semantics respectively, and depending on the order return one of Order::Increase, Order::Same, or Order::Decrease (which numerify to -1, 0, or +1). See "Comparison semantics".
From t/spec/S03-operators/comparison.t lines 8–12 (2 √, 0 ×): (skip)
$min .. $max
$min ^.. $max
$min ..^ $max
$min ^..^ $max
Constructs Range objects, optionally excluding one or both endpoints. See "Range and RangeIterator semantics".
Note that these differ:
0 ..^ 10 # 0 .. 9
0 .. ^10 # 0 .. (0..9)
(It's not yet clear what the second one should mean, but whether it succeeds or fails, it won't do what you want.)
From t/spec/S03-operators/equality.t lines 10–41 (15 √, 0 ×): (skip)
From t/spec/S03-operators/relational.t lines 9–81 (36 √, 0 ×): (skip)
All operators on this precedence level may be chained; see "Chained comparisons".
infix:<==> etc.
From t/spec/S03-operators/misc.t lines 26–48 (no results): (skip)
Highlighted: small|full== != < <= > >=
As in Perl 5, converts to Num before comparison. != is short for !==.
infix:<eq> etc.
eq ne lt le gt ge
As in Perl 5, converts to Str before comparison. ne is short for !eq.
$a before $b
$a after $b
$obj ~~ $pattern
Perl 5's =~ becomes the "smart match" operator ~~, with an extended set of semantics. See "Smart matching" for details.
To catch "brainos", the Perl 6 parser defines an infix:<=~> operator which always fails at compile time with a message directing the user to use ~~ or ~= (string append) instead if they meant it as a single operator, or to put a space between if they really wanted to assign a stringified value as two separate operators.
From t/spec/S03-operators/brainos.t lines 15–24 (no results): (skip)
Highlighted: small|fullA negated smart match is spelled !~~.
VAR($a) =:= VAR($b)
$x === $y
For objects that are not value types, their identities are their values. (Identity is returned by the .WHICH metamethod.) The actual contents of the objects are ignored. These semantics are those used by hashes that allow objects for keys. See also "Comparison semantics".
$obj1 eqv $obj2
Compares two objects for canonical equivalence. For value types compares the values. For object types, compares current contents according to some scheme of canonicalization. These semantics are those used by hashes that allow only values for keys (such as Perl 5 string-key hashes). See also "Comparison semantics".
From t/spec/S03-operators/value_equivalence.t lines 139–148 (no results): (skip)
Highlighted: small|full $num !== 42
$str !eq "abc"
"foo" !~~ /^ <ident> $/
VAR($a) !=:= VAR($b)
$a !=== $b
$a !eqv $b
infix:<&&>, short-circuit and
$a && $b && $c ...
Returns the first argument that evaluates to false, otherwise returns the result of the last argument. In list context forces a false return to mean (). See and below for low-precedence version.
infix:<||>, short-circuit inclusive-or
From t/spec/S03-operators/misc.t lines 54–68 (no results): (skip)
Highlighted: small|full$a || $b || $c ...
Returns the first argument that evaluates to a true value, otherwise returns the result of the last argument. It is specifically allowed to use a list or array both as a boolean and as a list value produced if the boolean is true:
@a = @b || @c; # broken in Perl 5; works in Perl 6
In list context this operator forces a false return to mean (). See or below for low-precedence version.
infix:<^^>, short-circuit exclusive-or
$a ^^ $b ^^ $c ...
Returns the true argument if there is one (and only one). Returns Bool::False if all arguments are false or if more than one argument is true. In list context forces a false return to mean (). See xor below for low-precedence version.
This operator short-circuits in the sense that it does not evaluate any arguments after a 2nd true result. Closely related is the reduce operator:
[^^] a(), b(), c() ...
but note that reduce operators are not macros but ordinary list operators, so c() is always called before the reduce is done.
infix:<//>, short-circuit default operator
$a // $b // $c ...
Returns the first argument that evaluates to a defined value, otherwise returns the result of the last argument. In list context forces a false return to mean (). See orelse below for a similar but not identical low-precedence version.
$a min $b min $c ...
$a max $b max $c ...
These return the minimum or maximum value. See also the minmax listop.
Not all types can support the concept of infinity. Therefore any value of any type may be compared with +Inf or -Inf values, in which case the infinite value stands for "larger/smaller than any possible value of the type." That is,
From t/spec/S03-operators/misc.t lines 133–140 (no results): (skip)
Highlighted: small|full "foo" min +Inf # "foo"
"foo" min -Inf # -Inf
"foo" max +Inf # +Inf
"foo" max -Inf # "foo"
All orderable object types must support +Inf and -Inf values as special forms of the undefined value. It's an error, however, to attempt to store an infinite value into a native type that cannot support it:
my int $max;
$max max= -Inf; # ERROR
say "My answer is: ", $maybe ?? "yes" !! "no";
Also known as the "ternary" or "trinary" operator, but we prefer "conditional" just to stop people from fighting over the terms. The operator syntactically separates the expression into three subexpressions. It first evaluates the left part in boolean context, then based on that selects one of the other two parts to evaluate. (It never evaluates both of them.) If the conditional is true it evaluates and returns the middle part; if false, the right part. The above is therefore equivalent to:
From t/spec/S03-operators/misc.t lines 20–25 (no results): (skip)
Highlighted: small|full say "My answer is: ", do {
if $maybe {
"yes";
}
else {
"no";
}
};
It is a syntax error to use an operator in the middle part that binds looser in precedence, such as =.
my $x;
hmm() ?? $x = 1 !! $x = 2; # ERROR
hmm() ?? ($x = 1) !! ($x = 2); # works
Note that both sides have to be parenthesized. A partial fix is even wronger:
hmm() ?? ($x = 1) !! $x = 2; # parses, but WRONG
That actually parses as:
(
hmm() ?? ($x = 1) !! $x
) = 2;
and always assigns 2 to $x (because ($x = 1) is a valid lvalue).
And in any case, repeating the $x forces you to declare it earlier. The best don't-repeat-yourself solution is simply:
my $x = hmm() ?? 1 !! 2; # much better
infix:<?>
To catch likely errors by people familiar with C-derived languages (including Perl 5), a bare question mark in infix position will produce an error suggesting that the user use ?? !! instead.
start() ff end()
start() ^ff end()
start() ff^ end()
start() ^ff^ end()
start() fff end()
start() ^fff end()
start() fff^ end()
start() ^fff^ end()
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.
From t/spec/S03-operators/binding-nested.t lines 5–340 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/binding-arrays.t lines 5–228 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/binding-attributes.t lines 4–80 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/binding-subs.t lines 7–113 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/binding-hashes.t lines 5–183 (no results): (skip)
Highlighted: small|fullinfix:<=>
$x = 1, $y = 2;
With simple lvalues, = has this precedence, which is tighter than comma. (List assignments have listop precedence below.)
infix:<:=>, run-time binding
$signature := $capture
A new form of assignment is present in Perl 6, called binding, used in place of typeglob assignment. It is performed with the := operator. Instead of replacing the value in a container like normal assignment, it replaces the container itself. For instance:
From t/spec/S03-operators/binding-scalars.t lines 9–132 (no results): (skip)
Highlighted: small|full my $x = 'Just Another';
my $y := $x;
$y = 'Perl Hacker';
After this, both $x and $y contain the string "Perl Hacker", since they are really just two different names for the same variable.
There is also an identity test, =:=, which tests whether two names are bound to the same underlying variable. $x =:= $y would return true in the above example.
The binding fails if the type of the variable being bound is sufficiently inconsistent with the type of the current declaration. Strictly speaking, any variation on
my Any $x;
$x := [1,2,3];
should fail because the type being bound is not consistent with Scalar of Any, but since the Any type is not a real instantiable type but a generic (non)constraint, and Scalar of Any is sort of a double non-constraint similar to Any, we treat this situation specially as the equivalent of binding to a typeless variable.
infix:<::=>, compile-time binding
$signature ::= $capture
This does the same as := except it does it at compile time. (This implies that the expression on the right is also evaluated at compile time; it does not bind a lazy thunk.)
infix:{'=>'}, Pair constructor
foo => 1, bar => "baz"
Binary => is no longer just a "fancy comma". It now constructs a Pair object that can, among other things, be used to pass named arguments to functions. It provides item context to both sides. It does not actually do an assignment except in a notional sense; however its precedence is now equivalent to assignment, and it is also right associative. Note that, unlike in Perl 5, => binds tighter than comma.
+= -= **= xx= .= etc.
From t/spec/S03-operators/true.t lines 5–20 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/not.t lines 13–30 (no results): (skip)
Highlighted: small|fullprefix:<true>
true any(@args) eq '-v' | '-V'
prefix:<not>
not any(@args) eq '-v' | '-V'
infix:<,>, the argument separator
1, 2, 3, @many
Unlike in Perl 5, comma operator never returns the last value. (In item context it returns a list instead.)
infix:«p5=>», the Perl 5 fatarrow
From t/spec/S03-operators/p5arrow.t lines 7–28 (no results): (skip)
Highlighted: small|fullThis operator, which behaves exactly like the Perl 5 fatarrow in being equivalent to a comma, is purely for easier migration from Perl 5 to Perl 6. It is not intended for use by programmers in fresh code; it is for use by the p5-to-p6 translator to preserve Perl 5 argument passing semantics without losing the intent of the notation.
This operator is purposefully ugly and easy to search for. Note that, since the operator is equivalent to a comma, arguments come in as positional pairs rather than named arguments. Hence, if you have a Perl 5 sub that manually handles named argument processing by assigning to a hash, it will continue to work. If, however, you edit the p5=> operator in an argument list to Perl 6's => operator, it becomes a real named argument, so you must also change the called sub to handle real named args, since the named pair will no longer come in via @_. You can either name your formal parameters explicitly if there is an explicit signature, or pull them out of %_ rather than @_ if there is no explicit signature.
infix:<:>, the invocant marker
say $*OUT: "howdy, world"
say($*OUT: "howdy, world")
push @array: 1,2,3
push(@array: 1,2,3)
\($object: 1,2,3, :foo, :!bar)
The colon operator parses just like a comma, but marks the argument to its left as an invocant, which has the effect of turning what would otherwise be a function call into a method call. It may only be used on the first argument of an argument list or capture, and will fail to parse if used in any other position. When used within a capture, it is not yet known what signature the capture will be bound to; if bound to a non-method's signature, the invocant merely turns into the first positional argument, as if the colon had been a comma.
To avoid confusion with other colon forms, the colon infix operator must be followed by whitespace or a terminator. It may optionally have whitespace in front of it.
Note: distinguish this infix operator from the colon in
@array.push: 1,2,3
@array.push(1,2,3): 4,5,6
push(@array, 1,2,3): 4,5,6
which is a special form that turns an ordinary function or method call into a list operator. The special form is recognized only after a dotty method call, or after the right parenthesis of a method or function call. The special form does not allow intervening whitespace, but requires whitespace before the next argument. In all other cases a colon will be parsed as the start of an adverb if possible, or otherwise the invocant marker (the infix described above).
Another way to think of it is that the special colon is allowed to add listop arguments to a parenthesized argument list only after the right parenthesis of that argument list, with the proviso that you're allowed to shorten .foo(): 1,2,3 down to .foo: 1,2,3. (But only for method calls, since ordinary functions don't need the colon in the first place to turn into a listop, just whitespace. If you try to extend a function name with a colon, it's likely to be taken as a label.)
foo $obj.bar: 1,2,3 # special, means foo($obj.bar(1,2,3))
foo $obj.bar(): 1,2,3 # special, means foo($obj.bar(1,2,3))
foo $obj.bar(1): 2,3 # special, means foo($obj.bar(1,2,3))
foo $obj.bar(1,2): 3 # special, means foo($obj.bar(1,2,3))
foo($obj.bar): 1,2,3 # special, means foo($obj.bar, 1,2,3)
foo($obj.bar, 1): 2,3 # special, means foo($obj.bar, 1,2,3)
foo($obj.bar, 1,2): 3 # special, means foo($obj.bar, 1,2,3)
foo $obj.bar : 1,2,3 # infix:<:>, means $obj.bar.foo(1,2,3)
foo ($obj.bar): 1,2,3 # infix:<:>, means $obj.bar.foo(1,2,3)
foo $obj.bar:1,2,3 # syntax error
foo $obj.bar :1,2,3 # syntax error
foo $obj.bar :baz # adverb, means foo($obj.bar(:baz))
foo ($obj.bar) :baz # adverb, means foo($obj.bar, :baz)
foo $obj.bar:baz # extended identifier, foo( $obj.'bar:baz' )
foo $obj.infix:<+> # extended identifier, foo( $obj.'infix:<+>' )
foo: 1,2,3 # label at statement start, else infix
The moral of the story is, if you don't know how the colon is going to bind, use whitespace or parentheses to make it clear.
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.
infix:<Z>, the zip operator
1,2 Z 3,4 # (1,3),(2,4)
infix:<minmax>, the minmax operator
$min0, $max0 minmax $min1, $max1 # ($min0 min $min1, $max0 max $max1)
The minmax operator is for calculating both a minimum and maximum in a single expression. Otherwise you'd have to write twice as many expressions. Instead of
@a minmax @b
you'd have to say something like
($a[0] min $b[0], $a[1] max $b[1])
Note that there is no guarantee that the resulting minimum and maximum come from the same side. The two calculations are bundled but independent.
infix:<X>, the cross operator
From t/spec/S03-operators/cross-metaop.t lines 6–16 (no results): (skip)
Highlighted: small|full1,2 X 3,4 # (1,3), (1,4), (2,3), (2,4)
In contrast to the zip operator, the X operator returns all possible lists formed by taking one element from each of its list arguments. The returned lists are ordered such that the rightmost elements vary most rapidly. If there are just two lists, for instance, it forms all pairs where one element is from the first list and the other one from the second, with the second element varying most rapidly. Hence you may say:
<a b> X <1 2>
and you end up with
('a', '1'), ('a', '2'), ('b', '1'), ('b', '2')
This becomes a flat list in @ context and a list of arrays in @@ context:
From t/spec/S03-operators/cross-metaop.t lines 17–26 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/cross-metaop.t lines 27–35 (no results): (skip)
Highlighted: small|full say @(<a b> X <1 2>)
'a', '1', 'a', '2', 'b', '1', 'b', '2'
say @@(<a b> X <1 2>)
['a', '1'], ['a', '2'], ['b', '1'], ['b', '2']
The operator is list associative, so
1,2 X 3,4 X 5,6
produces
(1,3,5),(1,3,6),(1,4,5),(1,4,6),(2,3,5),(2,3,6),(2,4,5),(2,4,6)
On the other hand, if any of the lists is empty, you will end up with a null list.
Only the leftmost list may usefully be an infinite list. For instance
<a b> X 0..*
would produce
('a',0), ('a',1), ('a',2), ('a',3), ('a',4), ('a',5), ...
and you'd never get to 'b'.
@files X~ '.' X~ @extensions
1..10 X* 1..10
@x Xeqv @y
etc.
See "Cross operators".
infix:<...>, the series operator.
From t/spec/S03-operators/series.t lines 4–141 (no results): (skip)
Highlighted: small|fullThis operator takes a concrete list on its left and a function to be iterated on its right when the list must be extended. Each time the function must be called, it extends the list with the values returned by the function (if any).
The value of the operator is the lazy list formed of the concrete list followed by the result of applying the function to the tail of the list as needed. The function indicates by its signature how many of the preceding values to pay attention to (and which the operator must track internally). Demonstration of this falls to the lot of the venerable Fibonacci sequence:
1, 1 ... { $^y + $^z } # 1,1,2,3,5,8...
1, 1 ... &infix:<+> # 1,1,2,3,5,8...
More typically the function is unary, in which case any extra values in the list may be construed as human-readable documentation:
0,2,4 ... { $_ + 2 } # same as 1..*:by(2)
<a b c> ... { .succ } # same as 'a'..*
The function need not be monotonic, of course:
1 ... { -$_ } # 1, -1, 1, -1, 1, -1...
False ... &prefix:<!> # False, True, False...
The function can be 0-ary as well:
() ... { rand } # list of random numbers
The function may also be slurpy (*-ary), in which case all the preceding values are passed in (which means they must all be cached by the operator, so performance may suffer).
The arity of the function need not match the number of return values, but if they do match you may interleave unrelated sequences:
1,1 ... { $^a + 1, $^b * 2 } # 1,1,2,2,3,4,4,8,5,16,6,32...
If the right operand is * (Whatever) and the sequence is obviously arithmetic or geometric, the appropriate function is deduced:
1, 3, 5 ... * # odd numbers
1, 2, 4 ... * # powers of 2
Conjecture: other such patterns may be recognized in the future, depending on which unrealistic benchmarks we want to run faster. :)
Note: the yada operator is recognized only where a term is expected. This operator may only be used where an infix is expected. If you put a comma before the ... it will be taken as a yada list operator expressing the desire to fail when the list reaches that point:
1..20, ... "I only know up to 20 so far mister"
If the yada operator finds a closure for its argument at compile time, it should probably whine about the fact that it's difficult to turn a closure into an error message. Alternately, we could treat an ellipsis as special when it follows a comma to better support traditional math notation.
The function may choose to terminate its list by returning (). Since this operator is list associative, an inner function may be followed by a ... and another function to continue the list, and so on. Hence,
1 ... { $_ + 1 if $_ < 10 }
... { $_ + 10 if $_ < 100 }
... { $_ + 100 if $_ < 1000 }
produces
1,2,3,4,5,6,7,8,9,
10,20,30,40,50,60,70,80,90,
100,200,300,400,500,600,700,800,900
In slice context the function's return value is appended as a capture rather than as a flattened list of values, and the argument to each function call is the previous capture in the list.
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.
infix:<=>, list assignment
@array = 1,2,3;
With compound targets, performs list assignment. The right side is looser than comma. You might be wondering why we've classified this as a prefix operator when its token name is infix:<=>. That's because you can view the left side as a special syntax for a prefix listop, much as if you'd said:
@array.assign: 1,2,3
However, the tokener classifies it as infix because it sees it when it's expecting an infix operator. Assignments in general are treated more like retroactive macros, since their meaning depends greatly on what is on the left, especially if what is on the left is a declarator of some sort. We even call some of them pseudo-assignments, but they're all a bit pseudo insofar as we have to figure out whether the left side is a list or a scalar destination.
In any case, list assignment is defined to be arbitrarily lazy, insofar as it basically does the obvious copying as long as there are scalar destinations on the left or already-computed values on the right. However, many list lvalues end with an array destination (where assignment directly to an array can be considered a degenerate case). When copying into an array destination, the list assignment continues to copy in known values immediately, but suspends when it hits an actively iterating iterator (but not one merely passed as an object within the list). The array location on the left is then set up as a self-extending array, with the remainder of the list on the right as the "specs" for its remaining values, to be reified on demand. Hence it is legal to say:
@natural = 0..*;
(Note that when we say that an iterator in list context suspends, it is not required to suspend immediately. When the scheduler is running an iterator, it may choose to precompute values in batches if it thinks that approach will increase throughput. This is likely to be the case on single-core architectures with heavy context switching, and may very well be the case even on manycore CPU architectures when there are more iterators than cores, such that cores may still have to do context switching. In any case, this is all more-or-less transparent to the user because in the abstract the list is all there, even if it hasn't been entirely computed yet.)
Though elements may be reified into an array on demand, they act like ordinary array elements both before and after reification, as far as the user is concerned. These elements may be written to if the underlying container type supports it:
@unnatural = 0..*;
@unnatural[42] = "Life, the Universe, and Everything";
Note that, unlike assignment, binding replaces the container, so the following fails because a range object cannot be subscripted:
@natural := 0..*; # bind a Range object
@natural[42] = "Life, the Universe, and Everything"; # FAILS
but this succeeds:
@unnatural := [0..*]; # bind an Array object
@unnatural[42] = "Life, the Universe, and Everything"; # ok
It is erroneous to make use of any side effects of reification, such as movement of a file pointer, since different implementations may have different batch semantics, and in any case the unreified part of the list already "belongs" to the array.
When a self-extending array is asked for its count of elements, it is allowed to return +Inf without blowing up if it can determine by inspection that its unreified parts contain any infinite lists. If it cannot determine this, it is allowed to use all your memory, and then some. :)
Assignment to a hash is not lazy (probably).
print push say join split substr open etc.
any all one none
fail "Division by zero"
die System::Error(ENOSPC,"Drive $d seems to be full");
warn "Can't open file: $!"
...
!!! "fill this in later, Dave"
??? "oops in $?CLASS"
The ... operator is the "yada, yada, yada" list operator, which among other things is used as the body in function prototypes. It complains bitterly (by calling fail) if it is ever executed. Variant ??? calls warn, and !!! calls die. The argument is optional, but if provided, is passed onto the fail, warn, or die. Otherwise the system will make up a message for you based on the context, indicating that you tried to execute something that is stubbed out. (This message differs from what fail, warn, and die would say by default, since the latter operators typically point out bad data or programming rather than just an incomplete design.)
[+] [*] [<] [\+] [\*] etc.
See "Reduction operators" below.
Sigil Alpha variant
----- -------------
$ item
@ list
@@ slice
% hash
These may only be used as functions with explicit parens:
$(1,2 Z 3,4) # [\(1,3),\(2,4)]
@(1,2 Z 3,4) # 1,3,2,4
@@(1,2 Z 3,4) # [1,3],[2,4]
%(1,2 Z 3,4) # { 1 => 3, 2 => 4 }
$(1,2 X 3,4) # [\(1,3),\(1,4),\(2,3),\(2,4)]
@(1,2 X 3,4) # 1,3,1,4,2,3,2,4
@@(1,2 X 3,4) # [1,3],[1,4],[2,3],[2,4]
These can also influence the result of functions that returns lists of captures:
$(map { $_, $_*2 }, ^4) # [\(0,0),\(1,2),\(2,4),\(3,6)]
@(map { $_, $_*2 }, ^4) # 0,0,1,2,2,4,3,6
@@(map { $_, $_*2 }, ^4) # [0,0],[1,2],[2,4],[3,6]
%(map { $_, $_*2 }, ^4) # { 0 => 0, 1 => 2, 2 => 4, 3 => 6 }
The parens may not be omitted on the sigiled forms, but the alpha variants may be used as normal listops:
item map { $_, $_*2 }, ^4 # [\(0,0),\(1,2),\(2,4),\(3,6)]
list map { $_, $_*2 }, ^4 # 0,0,1,2,2,4,3,6
slice map { $_, $_*2 }, ^4 # [0,0],[1,2],[2,4],[3,6]
hash map { $_, $_*2 }, ^4 # { 0 => 0, 1 => 2, 2 => 4, 3 => 6 }
item contextualizer
From t/spec/S03-operators/context.t lines 33–64 (no results): (skip)
Highlighted: small|fullitem foo()
The new name for Perl 5's scalar contextualizer. Equivalent to $(...) (except that empty $() means $<? // Str($/)>, while empty item() yields Failure). We still call the values scalars, and talk about "scalar operators", but scalar operators are those that put their arguments into item context.
If given a list, this function makes a Capture object from it. The function is agnostic about any Captures embedded in such a capture. (Use @ or @@ below to force that one way or the other).
Note that this is a list operator, not a unary prefix operator, since you'd generally want it for converting a list to an item. Single items don't need to be converted to items.
list contextualizer
From t/spec/S03-operators/context.t lines 7–32 (no results): (skip)
Highlighted: small|fulllist foo()
Forces the subsequent expression to be evaluated in list context. A list of Captures will be transformed into a flat list. Equivalent to @(...) (except that empty @() means @($/), while empty list() means an empty list).
slice contextualizer
slice foo()
Forces the subsequent expression to be evaluated in slice context. (Slices are considered to be potentially multidimensional in Perl 6.) A list of Captures will be transformed into a list of lists. Equivalent to @@(...) (except that empty @@() means @@($/), while empty slice() means a null slice).
hash contextualizer
hash foo()
Forces the subsequent expression to be evaluated in hash context. The expression is evaluated in list context (flattening any Captures), then a hash will be created from the list, taken as a list of Pairs. (Any element in the list that is not a Pair will pretend to be a key and grab the next value in the list as its value.) Equivalent to %(...) (except that empty %() means %($/), while empty hash() means an empty hash).
infix:<and>, short-circuit and
$a and $b and $c ...
Returns the first argument that evaluates to false, otherwise returns the result of the last argument. In list context forces a false return to mean (). See && above for high-precedence version.
infix:<andthen>, proceed on success
test1() andthen test2() andthen test3() ...
Returns the first argument whose evaluation indicates failure (that is, if the result is undefined). Otherwise it evaluates and returns the right argument.
If the right side is a block or pointy block, the result of the left side is bound to any arguments of the block. If the right side is not a block, a block scope is assumed around the right side, and the result of the left side is implicitly bound to $_ for the scope of the right side. That is,
test1() andthen test2()
is equivalent to
test1() andthen -> $_ { test2() }
There is no corresponding high-precedence version.
infix:<or>, short-circuit inclusive or
From t/spec/S02-builtin_data_types/parsing-bool.t lines 7–15 (no results): (skip)
Highlighted: small|full$a or $b or $c ...
Returns the first argument that evaluates to true, otherwise returns the result of the last argument. In list context forces a false return to mean (). See || above for high-precedence version.
infix:<xor>, exclusive or
$a xor $b xor $c ...
Returns the true argument if there is one (and only one). Returns Bool::False if all arguments are false or if more than one argument is true. In list context forces a false return to mean (). See ^^ above for high-precedence version.
infix:<orelse>, proceed on failure
test1() orelse test2() orelse test3() ...
Returns the first argument that evaluates successfully (that is, if the result is defined). Otherwise returns the result of the right argument.
If the right side is a block or pointy block, the result of the left side is bound to any arguments of the block. If the right side is not a block, a block scope is assumed around the right side, and the result of the left side is implicitly bound to $! for the scope of the right side. That is,
test1() orelse test2()
is equivalent to
test1() orelse -> $! { test2() }
(The high-precedence // operator is similar, but does not set $! or treat blocks specially.)
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.)
$x = 1; $y = 2;
The context determines how the expressions terminated by semicolon are interpreted. At statement level they are statements. Within a bracketing construct they are interpreted as lists of Captures, which in slice context will be treated as the multiple dimensions of a multidimensional slice. (Other contexts may have other interpretations or disallow semicolons entirely.)
source() ==> filter() ==> sink()
The forms with the double angle append rather than clobber the sink's todo list. The ==>> form always looks ahead for an appropriate target to append to, either the final sink in the chain, or the next filter stage with an explicit @(*) or @@(*) target. This means you can stack multiple feeds onto one filter command:
source1() ==>>
source2() ==>>
source3() ==>>
filter(@(*)) ==> sink()
Similar semantics apply to <<== except it looks backward for an appropriate target to append to.
When a block occurs after whitespace where an infix is expected, it is interpreated as a control block for a statement control construct. (If there is no whitespace, it is a subscript, and if it is where a term is expected, it's just a bare closure.) If there is no statement looking for such a block currently, it is a syntax error.
Statement modifiers terminate one expression and start another.
Calls into the operator precedence parser may be parameterized to recognize additional terminators, but right brackets of any sort (except angles) are automatically included in the set of terminators as tokens of length one. (An infix of longer length could conceivably start with one of these characters, and would be recognized under the longest-token rule and continue the expression, but this practice is discouraged. It would be better to use Unicode for your weird operator.) Angle brackets are exempted so that they can form hyperoperators (see "Hyper operators").
From t/spec/S03-operators/scalar-assign.t lines 8–26 (no results): (skip)
Highlighted: small|fullSeveral operators have been given new names to increase clarity and better Huffman-code the language, while others have changed precedence.
${...}, @{...}, %{...}, etc. dereferencing forms are now $(...), @(...), %(...), etc. instead. (Use of the Perl 5 curly forms will result in an error message pointing the user to the new forms.) As in Perl 5, the parens may be dropped when dereferencing a scalar variable.
From t/spec/S03-operators/context.t lines 65–83 (no results): (skip)
Highlighted: small|full-> becomes ., like the rest of the world uses. There is a pseudo postfix:{'->'} operator that produces a compile-time error reminding Perl 5 users to use dot instead. (The "pointy block" use of -> in Perl 5 requires preceding whitespace when the arrow could be confused with a postfix, that is when an infix is expected. Preceding whitespace is not required in term position.)
From t/spec/S12-methods/chaining.t lines 7–61 (no results): (skip)
Highlighted: small|fullFrom t/spec/S12-methods/chaining.t lines 62–77 (no results): (skip)
Highlighted: small|full. becomes ~. Think of it as "stitching" the two ends of its arguments together. String append is likewise ~=.
From t/spec/S32-str/append.t lines 6–29 (no results): (skip)
Highlighted: small|fullPair as a pattern that calls an object's method:
From t/spec/S16-filehandles/filetest.t lines 26–130 (no results): (skip)
Highlighted: small|full if $filename ~~ :e { say "exists" }
is the same as
if $filename.e { say "exists" }
The 1st form actually translates to the latter form, so the object's class decides how to dispatch methods. It just happens that Str (filenames), IO (filehandles), and Statbuf (stat buffers) default to the expected filetest semantics, but $regex.i might tell you whether the regex is case insensitive, for instance.
Using the pattern form, multiple tests may be combined via junctions:
given $handle {
when :r & :w & :x {...}
when :!w | :!x {...}
when * {...}
}
When adverbial pairs are stacked into one term, it is assumed they are ANDed together, so
when :r :w :x
is equivalent to either of:
when :r & :w & :x
when all(:r,:w,:x)
The advantage of the method form is that it can be used in places that require tighter precedence than ~~ provides:
sort { $^a.M <=> $^b.M }, @files
though that's a silly example since you could just write:
sort { .M }, @files
But that demonstrates the other advantage of the method form, which is that it allows the "unary dot" syntax to test the current topic.
Unlike in earlier versions of Perl 6, these filetests do not return stat buffers, but simple scalars of type Bool, Int, or Num.
In general, the user need not worry about caching the stat buffer when a filename is queried. The stat buffer will automatically be reused if the same object has recently been queried, where "recently" is defined as less than a second or so. If this is a concern, an explicit stat() or lstat() may be used to return an explicit stat buffer object that will not be subject to timeout, and may be tested repeatedly just as a filename or handle can. A Statbuf object has a .file method that can be queried for its filename (if known); the .io method returns the handle (if known). If the Statbuf object doesn't know its filename but does know its IO handle, then .file attempts to return .io.file.
Note that :s still returns the filesize, but :!s is true only if the file is of size 0, since it is smartmatched against the implicit False argument. By the same token, :s(0..1024) will be true only for files of size 1K or less.
(Inadvertent use of the Perl 5 forms will normally result in treatment as a negated postdeclared subroutine, which is likely to produce an error message at the end of compilation.)
x().foo doesn't mean you can write x()foo. Likewise the ability to say $x.'foo' does not imply that $x'foo' will work.)
The postfix interpretation of an operator may be overridden by use of a quoted method call, which calls the prefix form instead. So x().! is always the postfix operator, but x().'!' will always call !x(). In particular, you can say things like $array.'@'. This also includes any operator that would look like something with a special meaning if used after the method-calling dot. For example, If you defined a prefix:<= >, and you wanted to write it using the method-call syntax instead of =$object, the parser would take $object.= as the mutation syntax (see S12, "Mutating methods"). Writing $object.'=' will call your prefix operator.
~ now imposes a string (Str) context on its argument, and + imposes a numeric (Num) context (as opposed to being a no-op in Perl 5). Along the same lines, ? imposes a boolean (Bool) context, and the | unary operator imposes a function-arguments (Capture) context on its argument. Unary sigils are allowed when followed by a $ sigil on a scalar variable; they impose the container context implied by their sigil. As with Perl 5, however, $$foo[bar] parses as ( $($foo) )[bar], so you need $($foo[bar]) to mean the other way. In other words, sigils are not really parsed as operators, and you must use the parenthetical form for anything complicated.
From t/spec/S03-operators/context-forcers.t lines 93–108 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/context-forcers.t lines 110–137 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/numeric-context.t lines 5–52 (no results): (skip)
Highlighted: small|full+, ~, or ?. For example, Perl 5's | becomes either +| or ~| or ?|, depending on whether the operands are to be treated as numbers, strings, or boolean values. Perl 5's left shift << becomes +< , and correspondingly with right shift. Perl 5's unary ~ (one's complement) becomes either +^ or ~^ or ?^, since a bitwise NOT is like an exclusive-or against solid ones. Note that ?^ is functionally identical to !, but conceptually coerces to boolean first and then flips the bit. Please use ! instead.
From t/spec/S03-operators/bit.t lines 13–102 (no results): (skip)
Highlighted: small|full?| is a logical OR but differs from || in that ?| always evaluates both sides and returns a standard boolean value. That is, it's equivalent to ?$a + ?$b != 0. Another difference is that it has the precedence of an additive operator.
?& is a logical AND but differs from && in that ?& always evaluates both sides and returns a standard boolean value. That is, it's equivalent to ?$a * ?$b != 0. Another difference is that it has the precedence of a multiplicative operator.
Bitwise string operators (those starting with ~) may only be applied to Buf types or similar compact integer arrays, and treat the entire chunk of memory as a single huge integer. They differ from the + operators in that the + operators would try to convert the string to a number first on the assumption that the string was an ASCII representation of a number.
x splits into two operators: x (which concatenates repetitions of a string to produce a single string), and xx (which creates a list of repetitions of a list or item). "foo" xx * represents an arbitrary number of copies, useful for initializing lists. The left side of an xx is evaluated only once. (To call a block repeatedly, use a map instead.)
From t/spec/S03-operators/repeat.t lines 13–21 (no results): (skip)
Highlighted: small|fullFrom t/spec/S03-operators/repeat.t lines 22–76 (no results): (skip)
Highlighted: small|full? : conditional operator becomes ?? !!. A pseudo operator, infix:<?>, catches migratory brainos at compile time.
From t/spec/S03-operators/ternary.t lines 8–70 (no results): (skip)
Highlighted: small|fullqw{ ... } gets a synonym: < ... >, and an interpolating variant, «...». For those still living without the blessings of Unicode, that can also be written: << ... >>.
, now constructs a List object from its operands. You have to use a [*-1] subscript to get the last one. (Note the *. Negative subscripts no longer implicitly count from the end; in fact, the compiler may complain if you use [-1] on an object known at compile time not to have negative subscripts.)
Capture in S02 for details. (No whitespace is allowed after the backslash because that would instead start an "unspace", that is, an escaped sequence of whitespace or comments. See S02 for details. However, oddly enough, because of that unspace rule, saying \\ $foo turns out to be equivalent to \$foo.)
.. flipflop operator is now done with ff operator. (.. now always produces a Range object even in item context.) The ff operator may take a caret on either end to exclude either the beginning or ending. There is also a corresponding fff operator with Perl 5's ... semantics. You may say
From t/spec/S03-operators/flip-flop.t lines 7–164 (no results): (skip)
Highlighted: small|full/foo/ ff *
to indicate a flipflop that never flops once flipped.
From t/spec/S03-operators/assign.t lines 7–964 (no results): (skip)