Operators
Common Perl 6 infixes, prefixes, postfixes, and more!
See creating operators on how to define new operators.
Operator precedence
In an expression like 1 + 2 * 3
, the 2 * 3
is evaluated first because the infix *
has tighter precedence than the +
.
The following table summarizes the precedence levels in Perl 6, from tightest to loosest:
A | Level | Examples |
---|---|---|
N | Terms | 42 3.14 "eek" qq["foo"] $x :!verbose @$array rand time now ∅ |
L | Method postfix | .meth .+ .? .* .() .[] .{} .<> .«» .:: .= .^ .: |
N | Autoincrement | ++ -- |
R | Exponentiation | ** |
L | Symbolic unary | ! + - ~ ? | || +^ ~^ ?^ ^ |
L | Dotty infix | .= . |
L | Multiplicative | * × / ÷ % %% +& +< +> ~& ~< ~> ?& div mod gcd lcm |
L | Additive | + - − +| +^ ~| ~^ ?| ?^ |
L | Replication | x xx |
X | Concatenation | ~ o ∘ |
X | Junctive and | & (&) (.) ∩ ⊍ |
X | Junctive or | | ^ (|) (^) (+) (-) ∪ ⊖ ⊎ ∖ |
L | Named unary | temp let |
N | Structural infix | but does <=> leg unicmp cmp coll .. ..^ ^.. ^..^ |
C | Chaining infix | != ≠ == < <= ≤ > >= ≥ eq ne lt le gt ge ~~ === eqv !eqv =~= ≅ (elem) (cont) (<) (>) (<=) (>=) (<+) (>+) ∈ ∉ ∋ ∌ ⊂ ⊄ ⊃ ⊅ ⊆ ⊈ ⊇ ⊉ ≼ ≽ |
X | Tight and | && |
X | Tight or | || ^^ // min max |
R | Conditional | ?? !! ff ff^ ^ff ^ff^ fff fff^ ^fff ^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 notandthen |
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:
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) |
For unary operators this is interpreted as:
A | Assoc | Meaning of !$a! |
---|---|---|
L | left | (!$a)! |
R | right | !($a!) |
N | non | ILLEGAL |
In the operator descriptions below, a default associativity of left is assumed.
Operator classification
Operators can occur in several positions relative to a term:
+term | prefix |
term1 + term2 | infix |
term++ | postfix |
(term) | circumfix |
term1[term2] | postcircumfix |
.+(term) | method |
Each operator (except method operators) is also available as a subroutine. The name of the routine is formed from the operator category, followed by a colon, then a list quote construct with the symbol(s) that make up the operator:
infix:<+>(1, 2); # same as 1 + 2circumfix:«[ ]»(<a b c>); # same as [<a b c>]
As a special case, a listop (list operator) can stand either as a term or as a prefix. Subroutine calls are the most common listops. Other cases include metareduced infix operators ([+] 1, 2, 3
) and the prefix ... etc. stub operators.
Defining custom operators is covered in Defining operators functions.
Metaoperators
Metaoperators can be parameterized with other operators or subroutines in the same way as functions can take functions as parameters. To use a subroutine as a parameter, prefix its name with a &
. Perl 6 will generate the actual combined operator in the background, allowing the mechanism to be applied to user defined operators. To disambiguate chained metaoperators, enclose the inner operator in square brackets. There are quite a few metaoperators with different semantics as explained, next.
Substitution operators
Each substitution operator comes into two main forms: a lowercase one (e.g., s///
) that performs in-place (i.e., destructive behavior; and an uppercase form (e.g., S///
) that provides a non-destructive behavior.
s///
in-place substitution
my = 'old string';~~ s/o .+ d/new/;say ; # OUTPUT: «new string»
s///
operates on the $_
topical variable, changing it in place. It uses the given Regex
to find portions to replace and changes them to the provided replacement string. Sets $/
to the Match
object or, if multiple matches were made, a List
of Match
objects. Returns $/
.
It's common to use this operator with the ~~
smartmatch operator, as it aliases left-hand side to $_
, which s///
uses.
Regex captures can be referenced in the replacement part; it takes the same adverbs as the .subst
method, which go between the s
and the opening /
, separated with optional whitespace:
my = 'foo muCKed into the lEn';# replace second 'o' with 'x'~~ s:2nd/o/x/;# replace 'M' or 'L' followed by non-whitespace stuff with 'd'# and lower-cased version of that stuff:~~ s :g :i/ (\S+)/d/;say ; # OUTPUT: «fox ducked into the den»
You can also use a different delimiter:
my = 'foober';~~ s!foo!fox!;~~ s{b(.)r} = " d$0n";say ; # OUTPUT: «fox den»
Non-paired characters can simply replace the original slashes. Paired characters, like curly braces, are used only on the match portion, with the substitution given by assignment (of anything: a string, a routine call, etc.).
S///
non-destructive substitution
say S/o .+ d/new/ with 'old string'; # OUTPUT: «new string»S:g/« (.)/$0.uc()/.say for <foo bar ber>; # OUTPUT: «FooBarBer»
S///
uses the same semantics as the s///
operator, except it leaves the original string intact and returns the resultant string instead of $/
($/
still being set to the same values as with s///
).
Note: since the result is obtained as a return value, using this operator with the ~~
smartmatch operator is a mistake and will issue a warning. To execute the substitution on a variable that isn't the $_
this operator uses, alias it to $_
with given
, with
, or any other way. Alternatively, use the .subst
method.
tr///
in-place transliteration
my = 'old string';~~ tr/dol/wne/;say ; # OUTPUT: «new string»
tr///
operates on the $_
topical variable and changes it in place. It behaves similar to Str.trans
called with a single Pair argument, where key is the matching part (characters dol
in the example above) and value is the replacement part (characters wne
in the example above). Accepts the same adverbs as Str.trans
. Returns the StrDistance object that measures the distance between original value and the resultant string.
my = 'old string';~~ tr:c:d/dol st//;say ; # OUTPUT: «ring»
TR///
non-destructive transliteration
with 'old string'
TR///
behaves the same as the tr///
operator, except that it leaves the $_
value untouched and instead returns the resultant string.
say TR:d/dol // with 'old string'; # OUTPUT: «string»
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. Some examples:
my = 32;+= 10; # 42-= 2; # 40= 3;min= 5; # still 3min= 2; # 2my = 'a';~= 'b'; # 'ab'
This behavior is automatically extended to include custom-defined infix operators.
sub infix:<space-concat> (, ) ;my = 'word1';space-concat= 'word2'; # RESULT: «'word1 word2'»
Although not strictly operators, methods can be used in the same fashion.
my Real = 1/2;= 3.14;.= round; # RESULT: «3»
Negated relational operators
The result of a relational operator returning Bool
can be negated by prefixing with !
. To avoid visual confusion with the !!
operator, you may not modify any operator already beginning with !
.
There are shortcuts for !==
and !eq
, namely !=
and ne
.
my = True;say so != True; # OUTPUT: «False»my = 10;my = Date.new(:2015year, :12month, :24day);my = Date.today;say so !before ; # OUTPUT: «False»
Reversed operators
Any infix operator may be called with its two arguments reversed by prefixing with R
. Associativity of operands is reversed as well.
say 4 R/ 12; # OUTPUT: «3»say [R/] 2, 4, 16; # OUTPUT: «2»say [RZ~] <1 2 3>,<4 5 6> # OUTPUT: «(41 52 63)»
Hyper operators
Hyper operators include «
and »
, with their ASCII variants <<
and >>
. They apply a given operator enclosed (or preceded or followed, in the case of unary operators) by «
and/or »
to one or two lists, returning the resulting list, with the pointy part of «
or »
aimed at the shorter list. Single elements are turned to a list, so they can be used too. If one of the lists is shorter than the other, the operator will cycle over the shorter list until all elements of the longer list are processed.
say (1, 2, 3) »*» 2; # OUTPUT: «(2 4 6)»say (1, 2, 3, 4) »~» <a b>; # OUTPUT: «(1a 2b 3a 4b)»say (1, 2, 3) »+« (4, 5, 6); # OUTPUT: «(5 7 9)»say (, , )».(0.5);# OUTPUT: «(0.479425538604203 0.877582561890373 0.707106781186548)»
The last example illustrates how postcircumfix operators (in this case .()) can also be hypered.
my = <1 2 3>;my = <4 5 6>;say (,)»[1]; # OUTPUT: «(2 5)»
In this case, it's the postcircumfix[] which is being hypered.
Assignment metaoperators can be hyped.
my = 1, 2, 3;say »+=» 1; # OUTPUT: «[2 3 4]»my (, , );((, ), ) «=» ((1, 2), 3);say "$a, $c"; # OUTPUT: «1, 3»
Hyper forms of unary operators have the pointy bit aimed at the operator and the blunt end at the list to be operated on.
my = True, False, True;say !« ; # OUTPUT: «[False True False]»my = 1, 2, 3;»++; # OUTPUT: «(2, 3, 4)»
Hyper operators are defined recursively on nested arrays.
say -« [[1, 2], 3]; # OUTPUT: «[[-1 -2] -3]»
Also, methods can be called in an out of order, concurrent fashion. The resulting list will be in order. Note that all hyper operators are candidates for parallelism and will cause tears if the methods have side effects. The optimizer has full reign over hyper operators, which is the reason that they cannot be defined by the user.
my CarefulClass ;my = ».take-care();my ; # May Contain Nuts».?this-method-may-not-exist();
Hyper operators 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.
%foo «+» %bar; | intersection of keys |
%foo »+« %bar; | union of keys |
%outer »+» %inner; | only keys of %inner that exist in %outer will occur in the result |
my = 1, 2, 3 Z=> <a b c>;my = 1, 2 Z=> <x z>;say «~» ; # OUTPUT: «{"1" => "ax", "2" => "bz"}»
Hyper operators can take user-defined operators as their operator argument.
sub pretty-file-size (Int --> Str)for 60, 50, 40, 30, 20, 10 -># 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»
Whether hyperoperators descend into child lists depends on the nodality of the inner operator of a chain. For the hyper method call operator (».), the nodality of the target method is significant.
say (<a b>, <c d e>)».elems; # OUTPUT: «(2 3)»say (<a b>, <c d e>)».&; # OUTPUT: «((1 1) (1 1 1))»
You can chain hyper operators to destructure a List of Lists.
my = ((-1, 0), (0, -1), (0, 1), (1, 0));my = (2, 3);say »>>+<<» (, *); # OUTPUT: «((1 3) (2 2) (2 4) (3 3))»
Reduction metaoperators
The reduction metaoperator, [ ]
, reduces a list with the given infix operator. It gives the same result as the reduce routine - see there for details.
# These two are equivalent:say [+] 1, 2, 3; # OUTPUT: «6»say reduce :<+>, 1, 2, 3; # OUTPUT: «6»
No whitespace is allowed between the square brackets and the operator. To wrap a function instead of an operator, provide an additional layer of square brackets:
sub plus ;say [[]] 1, 2, 3; # OUTPUT: «6»
The argument list is iterated without flattening. This means that you can pass a nested list to the reducing form of a list infix operator:
say [X~] (1, 2), <a b>; # OUTPUT: «(1a 1b 2a 2b)»
which is equivalent to 1, 2 X~ <a b>
.
By default, only the final result of the reduction is returned. Prefix the wrapped operator with a \
, to return a lazy list of all intermediate values instead. This is called a "triangular reduce". If the non-meta part contains a \
already, quote it with []
(e.g. [\[\x]]
).
my = [\~] 1..*;say [^5]; # OUTPUT: «(1 12 123 1234 12345)»
Cross operators
The cross metaoperator, X
, will apply a given infix operator in order of cross product to all lists, such that the rightmost operator varies most quickly.
1..3 X~ <a b> # RESULT: «<1a, 1b, 2a, 2b, 3a, 3b>»
Zip metaoperator
The zip metaoperator (which is not the same thing as Z) will apply a given infix operator to pairs taken one left, one right, from its arguments. The resulting list is returned.
my = <a b c> Z~ 1, 2, 3; # RESULT: «[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 *
will repeat its 2nd last element indefinitely.
my = <a b c d> Z~ ':' xx *; # RESULT: «<a: b: c: d:>»= <a b c d> Z~ 1, 2, *; # RESULT: «<a1 b2 c2 d2>»
If an infix operator is not given, the ,
(comma operator) will be used by default:
my = 1 Z 2; # RESULT: «[(1 2)]»
Sequential operators
The sequential metaoperator, S
, will suppress any concurrency or reordering done by the optimizer. Most simple infix operators are supported.
say so 1 S& 2 S& 3; # OUTPUT: «True»
Nesting of metaoperators
To avoid ambiguity when chaining metaoperators, use square brackets to help the compiler understand you.
my = 1, 2, 3;my = 5, 6, 7;X[+=] ;say ; # OUTPUT: «[19 20 21]»
Term precedence
term < >
The quote-words construct breaks up the contents on whitespace and returns a List of the words. If a word looks like a number literal or a Pair
literal, it's converted to the appropriate number.
say <a b c>[1]; # OUTPUT: «b»
term ( )
The grouping operator.
An empty group ()
creates an empty list. Parentheses around non-empty expressions simply structure the expression, but do 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(:!)multi sub p()p a => 1; # OUTPUT: «named»p (a => 1); # OUTPUT: «positional»
term { }
If the content is empty, or contains a single list that starts with a Pair literal or %
-sigiled variable, and the $_
variable or placeholder parameters are not used, the constructor returns a Hash. Otherwise it constructs a Block.
To force construction of a Block, follow the opening brace with a semicolon. To always ensure you end up with a Hash, you can use %( )
coercer or hash routine instead:
.^name.say; # OUTPUT: «Hash».^name.say; # OUTPUT: «Block».^name.say; # OUTPUT: «Block»%(:).^name.say; # OUTPUT: «Hash»hash(:).^name.say; # OUTPUT: «Hash»
circumfix [ ]
The Array constructor returns an itemized Array that does not flatten in list context. Check this:
say .perl for [3,2,[1,0]]; # OUTPUT: «32$[1, 0]»
This array is itemized, in the sense that every element constitutes an item, as shown by the $
preceding the last element of the array, the (list) item contextualizer.
Terms
Terms have their own extended documentation.
Method postfix precedence
postcircumfix [ ]
sub postcircumfix:<[ ]>(, **,:, :, :, :, :, :)
Universal interface for positional access to zero or more elements of a @container, a.k.a. "array indexing operator".
my = 'a' .. 'z';say [0]; # OUTPUT: «a»say [1]; # OUTPUT: «b»say []; # OUTPUT: «z»say [100]:exists; # OUTPUT: «False»say [15, 4, 17, 11].join; # OUTPUT: «perl»say [23 .. *].perl; # OUTPUT: «("x", "y", "z")»[1, 2] = "B", "C";say [0..3].perl # OUTPUT: «("a", "B", "C", "d")»
See Subscripts, for a more detailed explanation of this operator's behavior and for how to implement support for it in custom types.
postcircumfix { }
sub postcircumfix:<>(, **,:, :, :, :, :, :)
Universal interface for associative access to zero or more elements of a %container, a.k.a. "hash indexing operator".
my = kiwi => "green", banana => "yellow", cherry => "red";say ; # OUTPUT: «yellow»say .perl; # OUTPUT: «("red", "green")»say :exists; # OUTPUT: «False»= "yellowish", "green";:delete;say ; # OUTPUT: «banana => yellowish, kiwi => green, lime => green»
See postcircumfix < >
and postcircumfix « »
for convenient shortcuts, and Subscripts for a more detailed explanation of this operator's behavior and how to implement support for it in custom types.
postcircumfix <>
Decontainerization operator, which extracts the value from a container and makes it independent of the container type.
use JSON::Tiny;my = from-json('{ "files": 3, "path": "/home/perl6/perl6.pod6" }');say .perl; # OUTPUT: «${:files(3), :path("/home/perl6/perl6.pod6")}»my = <>;say .perl; # OUTPUT: «{:files(3), :path("/home/perl6/perl6.pod6")}»
It's a Hash
in both cases, and it can be used like that; however, in the first case it was in item context, and in the second case it has been extracted to its proper context.
postcircumfix < >
Shortcut for postcircumfix { }
that quotes its argument using the same rules as the quote-words operator of the same name.
my = kiwi => "green", banana => "yellow", cherry => "red";say <banana>; # OUTPUT: «yellow»say <cherry kiwi>.perl; # OUTPUT: «("red", "green")»say <strawberry>:exists; # OUTPUT: «False»
Technically, not a real operator; it's syntactic sugar that's turned into the { }
postcircumfix operator at compile-time.
postcircumfix « »
Shortcut for postcircumfix { }
that quotes its argument using the same rules as the interpolating quote-words operator of the same name.
my = kiwi => "green", banana => "yellow", cherry => "red";my = "kiwi";say «cherry "$fruit"».perl; # OUTPUT: «("red", "green")»
Technically, not a real operator; it's syntactic sugar that's turned into the { }
postcircumfix operator at compile-time.
postcircumfix ( )
The call operator treats the invocant as a Callable and invokes it, using the expression between the parentheses as arguments.
Note that an identifier followed by a pair of parentheses is always parsed as a subroutine call.
If you want your objects to respond to the call operator, implement a method CALL-ME
.
methodop .
The operator for calling one method, $invocant.method
.
Technically, not a real operator; it's syntax special-cased in the compiler.
methodop .&
The operator to call a subroutine (with at least one positional argument), such as a method. The invocant will be bound to the first positional argument.
Technically, not a real operator; it's syntax special-cased in the compiler.
my sub f()42.;# OUTPUT: «The arg has a value of 42»42.&(-> );# OUTPUT: «The arg has a value of 42»
methodop .=
A mutating method call. $invocant.=method
desugars to $invocant = $invocant.method
, similar to = .
Technically, not a real operator; it's syntax special-cased in the compiler.
methodop .^
A metamethod call. $invocant.^method
calls method
on $invocant
's metaclass. It desugars to $invocant.HOW.method($invocant, ...)
. See the metaobject protocol documentation for more information.
Technically, not a real operator; it's syntax special-cased in the compiler.
methodop .?
Safe call operator. $invocant.?method
calls method method
on $invocant
if it has a method of such name. Otherwise it returns Nil.
Technically, not a real operator; it's syntax special-cased in the compiler.
methodop .+
$foo.+meth
walks the MRO and calls all the methods called meth
and submethods called meth
if the type is the same as type of $foo
. Those methods might be multis, in which case the matching candidate would be called.
After that, a List of the results are returned. If no such method was found, it throws a X::Method::NotFound exception.
is Ais B is Asay C.+foo; # OUTPUT: «from Cfrom Bfrom A(True True True)»
methodop .*
$foo.*meth
walks the MRO and calls all the methods called meth
and submethods called meth
if the type is the same as type of $foo
. Those methods might be multis, in which case the matching candidate would be called.
After that, a List of the results are returned. If no such method was found, an empty List is returned.
Technically, postfix .+
calls .*
at first. Read postfix .+
section to see examples.
methodop ».
/ methodop >>.
This is the hyper method call operator. Will call a method on all elements of a List
out of order and return the list of return values in order.
my = <a b c>;my = ».ord; # OUTPUT: «[97, 98, 99]»# The first parameter of a method is the invocant.sub foo(Str );# So we can pretend to have a method call with a sub that got a good# first positional argument.say ».;# Blocks have an implicit positional arguments that lands in $_. The latter can# be omitted for method calls.say ».&;
Hyper method calls may appear to be the same as doing a map call, however along with being a hint to the compiler that it can parallelize the call, the behavior is also affected by nodality of the method being invoked, depending on which either nodemap or deepmap semantics are used to perform the call.
The nodality is checked by looking up whether the Callable provides nodal
method. If the hyper is applied to a method, that Callable is that method name, looked up on List type; if the hyper is applied to a routine (e.g. ».&foo
), that routine functions as that Callable. If the Callable is determined to provide nodal
method, nodemap semantics are used to perform the hyper call, otherwise duckmap semantics are used.
Take care to avoid a common mistake of expecting side-effects to occur in order. The following say
is not guaranteed to produce the output in order:
».say; # WRONG! Could produce abc or cba or any other order
methodop .postfix
/ .postcircumfix
In most cases, a dot may be placed before a postfix or postcircumfix:
my ;[1, 2, 3];.[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.
my = Operation.new(:symbol<+>, :function);say .function()(1, 2); # OUTPUT: «3»# ORsay .function.(1, 2); # OUTPUT: «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, not a real operator; it's syntax special-cased in the compiler.
methodop .:<prefix>
An operator in prefix form can still be called like a method, that is, using the .
methodop notation, by preceding it by a colon. For example:
my = 1;say ++; # OUTPUT: «2»say .:<++>; # OUTPUT: «3»
Technically, not a real operator; it's syntax special-cased in the compiler, that is why it's classified as a methodop.
methodop .::
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.
is Barsay Foo.Bar::baz; # OUTPUT: «42»
postfix ,=
Creates an object that concatenates, in a class-dependent way, the contents of the variable on the left hand side and the expression on the right hand side:
my = :11a, :22b;,= :33x;say # OUTPUT: «{a => 11, b => 22, x => 33}»
Autoincrement precedence
prefix ++
multi sub prefix:<++>( is rw) is assoc<non>
This is the . Increments its argument by one and returns the updated value.
my = 3;say ++; # OUTPUT: «4»say ; # OUTPUT: «4»
It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.
prefix --
multi sub prefix:<-->( is rw) is assoc<non>
Decrements its argument by one and returns the updated value.
my = 3;say --; # OUTPUT: «2»say ; # OUTPUT: «2»
It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.
postfix ++
multi sub postfix:<++>( is rw) is assoc<non>
Increments its argument by one and returns the original value.
my = 3;say ++; # OUTPUT: «3»say ; # OUTPUT: «4»
It works by calling the succ method (for successor) on its argument, which gives custom types the freedom to implement their own increment semantics.
Note that this does not necessarily return its argument; e.g., for undefined values, it returns 0:
my ;say ++; # OUTPUT: «0»say ; # OUTPUT: «1»
Increment on Str will increment the number part of a string and assign the resulting string to the container. A is rw
-container is required.
my = "somefile-001.txt";say ++ for 1..3;# OUTPUT: «somefile-001.txtsomefile-002.txtsomefile-003.txt»
postfix --
multi sub postfix:<-->( is rw) is assoc<non>
Decrements its argument by one and returns the original value.
my = 3;say --; # OUTPUT: «3»say ; # OUTPUT: «2»
It works by calling the pred method (for predecessor) on its argument, which gives custom types the freedom to implement their own decrement semantics.
Note that this does not necessarily return its argument;e.g., for undefined values, it returns 0:
my ;say --; # OUTPUT: «0»say ; # OUTPUT: «-1»
Decrement on Str will decrement the number part of a string and assign the resulting string to the container. A is rw
-container is required. Crossing 0 is prohibited and throws X::AdHoc
.
my = "somefile-003.txt";say -- for 1..3;# OUTPUT: «somefile-003.txtsomefile-002.txtsomefile-001.txt»
Exponentiation precedence
infix **
multi sub infix:<**>(Any, Any --> Numeric) is assoc<right>
The exponentiation operator coerces both arguments to 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 (Int, FatRat), then the calculation is carried out without loss of precision.
Unicode superscripts will behave in exactly the same way.
sub squared( Int ) ;say squared() for ^5; OUTPUT: «014916»
It also works for sequences of several Unicode superscript numbers:
sub twenty-second-power( Int ) ;say twenty-second-power() for ^5; # OUTPUT: «0141943043138105960917592186044416»
Symbolic unary precedence
prefix ?
multi sub prefix:<?>(Mu --> Bool)
Coerces the argument to Bool by calling the Bool
method on it. Note that this collapses Junctions.
prefix !
multi sub prefix:<!>(Mu --> Bool)
Negated boolean context operator.
Coerces the argument to Bool by calling the Bool
method on it, and returns the negation of the result. Note that this collapses Junctions.
prefix +
multi sub prefix:<+>(Any --> Numeric)
Coerces the argument to Numeric by calling the Numeric
method on it.
prefix -
multi sub prefix:<->(Any --> Numeric)
Negative numeric context operator.
Coerces the argument to Numeric by calling the Numeric
method on it, and then negates the result.
prefix ~
multi sub prefix:<~>(Any --> Str)
Coerces the argument to Str by calling the Str method on it.
prefix |
Flattens objects of type Capture, Pair, List, Map and Hash into an argument list.
sub slurpee( |args );slurpee( <a b c d>, , 'e' => 'f' => 33 )# OUTPUT: «\(("a", "b", "c", "d"), {:e(3)}, :e(:f(33)))»
Please see the Signature
page, specially the section on Captures for more information on the subject.
Outside of argument lists, it returns a Slip, which makes it flatten into the outer list. Inside argument list Positional
s are turned into positional arguments and Associative
s are turned into named arguments.
prefix +^
multi sub prefix:<+^>(Any --> Int)
Integer bitwise negation operator: Coerces the argument to Int and does a bitwise negation on the result, assuming two's complement.
prefix ~^
Coerces the argument to a non-variable-encoding string buffer type (e.g. buf8
, buf16
, buf32
) and then flips each bit in that buffer.
Please note that this has not yet been implemented.
prefix ?^
multi sub prefix:<?^>(Mu --> Bool)
Boolean bitwise negation operator: Coerces the argument to Bool and then does a bit flip, which makes it the same as prefix:<!>
.
prefix ^
multi sub prefix:<^>(Any --> Range)
Coerces the argument to Numeric, and generates a range from 0 up to (but excluding) the argument.
say ^5; # OUTPUT: «0..^5»for ^5 # 5 iterations
Dotty infix precedence
These operators are like their Method Postfix counterparts, but require surrounding whitespace (before and/or after) to distinguish them.
infix .=
Calls the right-side method on the value in the left-side container, replacing the resulting value in the left-side container.
In most cases, this behaves identically to the postfix mutator, but the precedence is lower:
my = -5;say ++.=abs;# OUTPUT: «6»
say ++ .= abs;# OUTPUT: «Cannot modify an immutable Int# in block <unit> at <tmp> line 1»
infix .
Calls the following method (whose name must be alphabetic) on the left-side invocant.
Note that the infix form of the operator has a slightly lower precedence than postfix .meth
.
say -5.abs; # like: -(5.abs)# OUTPUT: «-5»say -5 . abs; # like: (-5) . abs# OUTPUT: «5»say -5 .abs; # following whitespace is optional# OUTPUT: «5»
Multiplicative precedence
infix *
multi sub infix:<*>(Any, Any --> Numeric)
Coerces both arguments to Numeric and multiplies them. The result is of the wider type. See Numeric for details.
infix /
multi sub infix:</>(Any, Any --> Numeric)
Coerces both argument to Numeric and divides the left through the right number. Division of Int values returns Rat, otherwise the "wider type" rule described in Numeric holds.
infix div
multi sub infix:<div>(Int, Int --> Int)
Integer division operator. Rounds down.
infix %
multi sub infix:<%>(, --> Numeric)
Modulo operator. Coerces to Numeric first.
Generally the following identity holds:
my (, ) = 1,2;% == - floor( / ) *
infix %%
multi sub infix:<%%>(, --> Bool)
Divisibility operator. Returns True
if $a % $b == 0
.
infix mod
multi sub infix:<mod>(Int , Int --> Int)
Integer modulo operator. Returns the remainder of an integer modulo operation.
infix +&
multi sub infix:<+&>(, --> Int)
Numeric bitwise AND operator. Coerces both arguments to Int and does a bitwise AND operation assuming two's complement.
infix +<
multi sub infix:<< +< >>(, --> Int)
Integer bit shift to the left.
infix +>
multi sub infix:<< +> >>(, --> Int)
Integer bit shift to the right.
infix ~&
Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8
, buf16
, buf32
) and then performs a numeric bitwise AND on corresponding integers of the two buffers, padding the shorter buffer with zeroes.
infix ~<
Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8
, buf16
, buf32
) and then performs a numeric bitwise left shift on the bits of the buffer.
Please note that this has not yet been implemented.
infix ~>
Coerces the left argument to a non-variable-encoding string buffer type (e.g. buf8
, buf16
, buf32
) and then performs a numeric bitwise right shift on the bits of the buffer.
Please note that this has not yet been implemented.
infix gcd
multi sub infix:<gcd>(, --> Int)
Coerces both arguments to Int and returns the greatest common divisor. If one of its arguments is 0, the other is returned (when both arguments are 0, the operator returns 0).
infix lcm
multi sub infix:<lcm>(, --> Int)
Coerces both arguments to Int and returns the least common multiple; that is, the smallest integer that is evenly divisible by both arguments.
Additive precedence
infix +
multi sub infix:<+>(, --> Numeric)
Coerces both arguments to Numeric and adds them.
infix -
multi sub infix:<->(, --> Numeric)
Coerces both arguments to Numeric and subtracts the second from the first.
infix +|
multi sub infix:<+|>(, --> Int)
Integer bitwise OR operator: Coerces both arguments to Int and does a bitwise OR (inclusive OR) operation.
infix +^
multi sub infix:<+^>(, --> Int)
Integer bitwise XOR operator: Coerces both arguments to Int and does a bitwise XOR (exclusive OR) operation.
infix ~|
Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8
, buf16
, buf32
) and then performs a numeric bitwise OR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.
infix ~^
Coerces each argument to a non-variable-encoding string buffer type (e.g. buf8
, buf16
, buf32
) and then performs a numeric bitwise XOR on corresponding integers of the two buffers, padding the shorter buffer with zeroes.
infix ?^
multi sub infix:<?^>(Mu = Bool::False)multi sub infix:<?^>(Mu \a, Mu \b)
Boolean bitwise XOR operator: Coerces the argument(s) to Bool and performs logical XOR on them: it will return True if and only if just one of the argument is true. It returns identity on a single argument.
infix ?|
multi sub infix:<?|>(, --> Bool)
Coerces both arguments to Bool and does a logical OR (inclusive OR) operation.
Replication precedence
infix x
sub infix:<x>(, --> Str)
Repeats the string $a
$b
times, if necessary coercing $a
to Str
and $b
Int
. Returns an empty string if $b <= 0
. An exception X::Numeric::CannotConvert
will be thrown if $b
is -Inf
or NaN
.
say 'ab' x 3; # OUTPUT: «ababab»say 42 x 3; # OUTPUT: «424242»my = 'a'.IO;my = 3.5;say x ; # OUTPUT: «aaa»
infix xx
Defined as:
multi sub infix:<xx>()multi sub infix:<xx>(Mu \x)multi sub infix:<xx>(, Num() )multi sub infix:<xx>(, Whatever)multi sub infix:<xx>(, Bool )multi sub infix:<xx>(, Int )multi sub infix:<xx>(Mu \x, Num() )multi sub infix:<xx>(Mu \x, Whatever)multi sub infix:<xx>(Mu \x, Bool )multi sub infix:<xx>(Mu \x, Int )
In general, it returns a Sequence of $a
repeated and evaluated $b
times ($b
is coerced to Int). If $b <= 0
, the empty list is returned. It will return an error with no operand, and return the operand itself with a single operand. An exception X::Numeric::CannotConvert
will be thrown if $b
is -Inf
or NaN
.
The left-hand side is evaluated for each repetition, so
say [1, 2] xx 5;# OUTPUT: «([1 2] [1 2] [1 2] [1 2] [1 2])»
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 *
, in which case a lazy, infinite list is returned. If it's a Bool
, a Seq
with a single element is returned if it's True
.
Concatenation
Same as the rest of the infix operators, these can be combined with metaoperators such as assignment, for instance.
infix ~
multi sub infix:<~>(Any, Any)multi sub infix:<~>(Str, Str)multi sub infix:<~>(Buf, Buf)
This is the string concatenation operator, which coerces both arguments to Str and concatenates them. If both arguments are Buf, a combined buffer is returned.
say 'ab' ~ 'c'; # OUTPUT: «abc»
infix ∘
multi sub infix:<∘>()multi sub infix:<∘>()multi sub infix:<∘>(, --> Block)
The function composition operator infix:<∘>
or infix:<o>
combines two functions, so that the left function is called with the return value of the right function. If the .count
of the left function is greater than 1, the return value of the right function will be slipped into the left function.
Both .count
and .arity
of the right-hand side will be maintained.
sub f()sub g()my = ∘ ;say composed 2; # OUTPUT: «gf2»# equivalent to:say 2..;# or to:say f g 2;
sub f(, , )sub g()my = ∘ ;say composed 'abc'; # OUTPUT: «cba»# equivalent to:say f |g 'abc';
The single-arg candidate returns the given argument as is. The zero-arg candidate returns an identity routine that simply returns its argument.
my = [∘] ;say composed 'foo'; # OUTPUT: «FOO»my = [∘];say composed 'foo'; # OUTPUT: «foo»
Junctive AND (all) precedence
infix &
multi sub infix:<&>(, --> Junction) is assoc<list>
Creates an all Junction from its arguments. See Junction for more details.
infix (&)
, infix ∩
multi sub infix:<(&)>(**)multi sub infix:<∩>(**)
Returns the intersection of all of its arguments. This creates a new Set that contains only the elements common to all of the arguments if none of the arguments are a Bag, BagHash, Mix or MixHash.
say <a b c> (&) <b c d>; # OUTPUT: «set(b c)»<a b c d> ∩ <b c d e> ∩ <c d e f>; # OUTPUT: «set(c d)»
If any of the arguments are Baggy or Mixy>, the result is a new Bag
(or Mix
) containing the common elements, each weighted by the largest common weight (which is the minimum of the weights of that element over all arguments).
say <a a b c a> (&) bag(<a a b c c>); # OUTPUT: «Bag(a(2), b, c)»
∩
is equivalent to (&)
, at codepoint U+2229 (INTERSECTION).
infix (.)
, infix ⊍
multi sub infix:<(.)>(**)multi sub infix:<⊍>(**)
Baggy multiplication operator.
Returns the Baggy multiplication of its arguments, i.e., a Bag that contains each element of the arguments with the weights of the element across the arguments multiplied together to get the new weight. Returns a Mix if any of the arguments is a Mixy.
say <a b c> (.) <a b c d>; # OUTPUT: «Bag(a, b, c)»# Since 1 * 0 == 0, in the case of 'd'say <a a b c a d> ⊍ bag(<a a b c c>); # OUTPUT: «Bag(a(6), b, c(2))»
⊍
is equivalent to (.)
, at codepoint U+228D (MULTISET MULTIPLICATION).
Junctive OR (any) precedence
infix |
multi sub infix:<|>(, --> Junction) is assoc<list>
Creates an any Junction from its arguments.
my = // | /<[i j k]>/ | /<[x y z]>/;say .perl; # OUTPUT: «any(/<[a b c]>/, /<[i j k]>/, /<[x y z]>/)»say 'b' ~~ ; # OUTPUT: «True»
This first creates an any
Junction
of three regular expressions (every one of them matching any of 3 letters), and then uses smartmatching to check whether the letter b
matches any of them, resulting in a positive match. See also Junction for more details.
infix (|)
, infix ∪
multi sub infix:<(|)>(**)multi sub infix:<∪>(**)
Returns the union of all of its arguments. This creates a new Set that contains all the elements its arguments contain if none of the arguments are a Bag, BagHash, Mix or MixHash.
say <a b d> ∪ bag(<a a b c>); # OUTPUT: «Bag(a(2), b, c, d)»
If any of the arguments are Baggy or Mixy>, the result is a new Bag
(or Mix
) containing all the elements, each weighted by the highest weight that appeared for that element.
say <a b d> ∪ bag(<a a b c>); # OUTPUT: «Bag(a(2), b, c, d)»
∪
is equivalent to (|)
, at codepoint U+222A (UNION).
infix (+)
, infix ⊎
multi sub infix:<(+)>(**)multi sub infix:<⊎>(**)
Returns the Baggy addition of its arguments. This creates a new Bag from each element of the arguments with the weights of the element added together to get the new weight, if none of the arguments are a Mix or MixHash.
say <a a b c a d> (+) <a a b c c>; # OUTPUT: «Bag(a(5), b(2), c(3), d)»
If any of the arguments is a Mixy, the result is a new Mix
.
say <a b c> (+) (a => 2.5, b => 3.14).Mix; # OUTPUT: «Mix(a(3.5), b(4.14), c)»
⊎
is equivalent to (+)
, at codepoint U+228E (MULTISET UNION).
infix (-)
, infix ∖
multi sub infix:<(-)>(**)multi sub infix:<∖>(**)
Returns the set difference of all its arguments. This creates a new Set that contains all the elements the first argument has but the rest of the arguments don't, i.e., of all the elements of the first argument, minus the elements from the other arguments. But only if none of the arguments are a Bag, BagHash, Mix or MixHash.
say <a a b c a d> (-) <a a b c c>; # OUTPUT: «set(d)»say <a b c d e> (-) <a b c> (-) <a b d>; # OUTPUT: «set(e)»
If any of the arguments are Baggy or Mixy>, the result is a new Bag
(or Mix
) containing all the elements remaining after the first argument with its weight subtracted by the weight of that element in each of the other arguments.
say <a a b c a d> (-) bag(<a b c c>); # OUTPUT: «Bag(a(2), d)»say <a a b c a d> ∖ mix(<a b c c>); # OUTPUT: «Mix(a(2), c(-1), d)»
∖
is equivalent to (-)
, at codepoint U+2216 (SET MINUS).
infix ^
multi sub infix:<^>(, --> Junction) is assoc<list>
Creates a one Junction from its arguments. See Junction for more details.
infix (^)
, infix ⊖
multi sub infix:<(^)>(, )multi sub infix:<⊖>(,)multi sub infix:<(^)>(**)multi sub infix:<⊖>(**)
Symmetric set difference operator.
Returns the symmetric set difference of all its arguments. This creates a new Set made up of all the elements that $a
has but $b
doesn't and all the elements $b
has but $a
doesn't if none of the arguments are a Bag, BagHash, Mix or MixHash. Equivalent to ($a ∖ $b) ∪ ($b ∖ $a)
.
say <a b> (^) <b c>; # OUTPUT: «set(a c)»
If any of the arguments are Baggy or Mixy>, the result is a new Bag
(or Mix
).
say <a b> ⊖ bag(<b c>); # OUTPUT: «Bag(a, c)»
⊖
is equivalent to (^)
, at codepoint U+2296 (CIRCLED MINUS).
Named unary precedence
prefix temp
sub prefix:<temp>(Mu is rw)
"temporizes" the variable passed as the argument. The variable begins with the same value as it had in the outer scope, but can be assigned new values in this scope. Upon exiting the scope, the variable will be restored to its original value.
my = "three";say ; # OUTPUT: «three»say ; # OUTPUT: «three»
You can also assign immediately as part of the call to temp:
temp = "five";
Be warned the temp
effects get removed once the block is left. If you were to access the value from, say, within a Promise after the temp
was undone, you'd get the original value, not the temp
one:
my = "original";say "Left the block; value is now `$v`";sleep 2;# OUTPUT:# [PROMISE] Value before block is left: `new one`# About to leave the block; value is `new one`# Left the block; value is now `original`# [PROMISE] Block was left while we slept; value is now `original`
prefix let
sub prefix:<let>(Mu is rw)
Refers to a variable in an outer scope whose value will be restored if the block exits unsuccessfully, implying that the block returned a defined object.
my = "Jane Doe";say "We got $name";
This code provides a default name for $name
. If the user exits from the prompt or simply does not provide a valid input for $name
; let
will restore the default value provided at the top. If user input is valid, it will keep that.
Nonchaining binary precedence
infix does
sub infix:<does>(Mu , Mu ) is assoc<non>
Mixes $role
into $obj
at runtime. Requires $obj
to be mutable.
Similar to but operator, the $role
can instead be an instantiated object, in which case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name
and that returns $obj
:
my = class .new;put ; # OUTPUT: «original»does "modded";put ; # OUTPUT: «modded»
If methods of the same name are present already, the last mixed in role takes precedence.
infix but
multi sub infix:<but>(Mu , Mu ) is assoc<non>multi sub infix:<but>(Mu , Mu ) is assoc<non>
Creates a copy of $obj
with $role
mixed in. Since $obj
is not modified, but
can be used to created immutable values with mixins.
Instead of a role, you can provide an instantiated object. In this case, the operator will create a role for you automatically. The role will contain a single method named the same as $obj.^name
and that returns $obj
:
my = 42 but 'forty two';say +33; # OUTPUT: «75»say .^name; # OUTPUT: «Int+{<anon|1>}»say .Str; # OUTPUT: «forty two»
Calling ^name
shows that the variable is an Int
with an anonymous object mixed in. However, that object is of type Str
, so the variable, through the mixin, is endowed with a method with that name, which is what we use in the last sentence.
We can also mixin classes, even created on the fly.
my = 12 but .new;say .Warbles.hi; # OUTPUT: «hello»say + 42; # OUTPUT: «54»
To access the mixed-in class, as above, we use the class name as is shown in the second sentence. If methods of the same name are present already, the last mixed in role takes precedence. A list of methods can be provided in parentheses separated by comma. In this case conflicts will be reported at runtime.
infix cmp
multi sub infix:<cmp>(Any, Any)multi sub infix:<cmp>(Real, Real)multi sub infix:<cmp>(Str, Str)multi sub infix:<cmp>(Version, Version)
Generic, "smart" three-way comparator.
Compares strings with string semantics, numbers with number semantics, Pair objects first by key and then by value etc.
if $a eqv $b
, then $a cmp $b
always returns Order::Same
.
say (a => 3) cmp (a => 4); # OUTPUT: «Less»say 4 cmp 4.0; # OUTPUT: «Same»say 'b' cmp 'a'; # OUTPUT: «More»
Strings are compared codepoint by codepoint; if leading codepoints are the same, the result of comparing the first differing codepoint is returned or the longer string if their lenghts differ.
"abcd" cmp "abcde" # OUTPUT: «Less»"abcd " cmp "abcde" # OUTPUT: «Less»'A' cmp 'Ẳ' # OUTPUT: «Less»
infix coll
Defined as:
multi sub infix:<coll>(Str \a, Str \b --> Order)multi sub infix:<coll>(Cool \a, Cool \b --> Order)multi sub infix:<coll>(Pair \a, Pair \b --> Order)
coll
is a sorting operator that takes pairs of Str
s, Cool
s or Pair
s and returns an Order
that uses the $*COLLATION
order. The default behavior disregards diacritic marks and capitalization, for instance.
say "b" cmp "à"; # OUTPUT: «Less»say "b" coll "à"; # OUTPUT: «More»
In the first case, lexicographic or codepoint order is taken into account. In the second, which uses coll
, the diacritic is not considered and sorting happens according to intuitive order.
NOTE: These are not yet implemented in the JVM.
infix unicmp
Defined as:
multi sub infix:<unicmp>(Str \a, Str \b --> Order)multi sub infix:<unicmp>(Pair \a, Pair \b --> Order)multi sub infix:<coll>(Pair \a, Pair \b --> Order)
Unlike the cmp operator which sorts according to codepoint, unicmp
and coll
sort according to how most users would expect, that is, disregarding aspects of the particular character like capitalization.
say 'a' unicmp 'Z'; # Lesssay 'a' coll 'Z'; # Lesssay 'a' cmp 'Z'; # More
The main difference between coll
and unicmp
is that the behavior of the former can be changed by the $*COLLATION
dynamic variable.
NOTE: These are not yet implemented in the JVM.
infix leg
multi sub infix:<leg>(Any, Any)multi sub infix:<leg>(Str, Str)
String three-way comparator. Short for less, equal or greater?.
Coerces both arguments to Str and then does a lexicographic comparison.
say 'a' leg 'b'; # OUTPUT: «Less»say 'a' leg 'a'; # OUTPUT: «Same»say 'b' leg 'a'; # OUTPUT: «More»
infix <=>
multi sub infix:«<=>»(, --> Order) is assoc<non>
Coerces both arguments to Real and then does a numeric comparison.
infix ..
multi sub infix:<..>(, --> Range) is assoc<non>
Constructs a Range from the arguments.
infix ..^
multi sub infix:<..^>(, --> Range) is assoc<non>
Constructs a Range from the arguments, excluding the end point.
infix ^..
multi sub infix:<^..>(, --> Range) is assoc<non>
Constructs a Range from the arguments, excluding the start point.
infix ^..^
multi sub infix:<^..^>(, --> Range) is assoc<non>
Constructs a Range from the arguments, excluding both start and end point.
Chaining binary precedence
infix ==
multi sub infix:<==>(Any, Any)multi sub infix:<==>(Int, Int)multi sub infix:<==>(Num, Num)multi sub infix:<==>(Rational, Rational)multi sub infix:<==>(Real, Real)multi sub infix:<==>(Complex, Complex)multi sub infix:<==>(Numeric, Numeric)
Coerces both arguments to Numeric (if necessary); returns True
if they are equal.
infix !=
sub infix:<!=>(Mu, Mu --> Bool)
Coerces both arguments to Numeric (if necessary); returns True
if they are distinct.
Is an alias to !==
.
infix ≠
Numeric inequality operator.
Equivalent to !=, at codepoint U+2260 (NOT EQUAL TO).
infix <
multi sub infix:«<»(Int, Int)multi sub infix:«<»(Num, Num)multi sub infix:«<»(Real, Real)
Coerces both arguments to Real (if necessary); returns True
if the first argument is smaller than the second.
infix <=
multi sub infix:«<=»(Int, Int)multi sub infix:«<=»(Num, Num)multi sub infix:«<=»(Real, Real)
Numeric less than or equal to operator.
Coerces both arguments to Real (if necessary); returns True
if the first argument is smaller than or equal to the second.
infix ≤
Numeric less than or equal to operator.
Equivalent to <=, at codepoint U+2264 (LESS-THAN OR EQUAL TO).
infix >
multi sub infix:«>»(Int, Int)multi sub infix:«>»(Num, Num)multi sub infix:«>»(Real, Real)
Numeric greater than operator.
Coerces both arguments to Real (if necessary); returns True
if the first argument is larger than the second.
infix >=
multi sub infix:«>=»(Int, Int)multi sub infix:«>=»(Num, Num)multi sub infix:«>=»(Real, Real)
Numeric greater than or equal to operator.
Coerces both arguments to Real (if necessary); returns True
if the first argument is larger than or equal to the second.
infix ≥
Numeric greater than or equal to operator.
Equivalent to >=, at codepoint U+2265 (GREATER-THAN OR EQUAL TO).
infix eq
multi sub infix:<eq>(Any, Any)multi sub infix:<eq>(Str, Str)
Coerces both arguments to Str (if necessary); returns True
if both are equal.
Mnemonic: equal
infix ne
multi sub infix:<ne>(Mu, Mu)multi sub infix:<ne>(Str, Str)
Coerces both arguments to Str (if necessary); returns False
if both are equal.
Mnemonic: not equal
infix gt
multi sub infix:<gt>(Mu, Mu)multi sub infix:<gt>(Str, Str)
Coerces both arguments to Str (if necessary); returns True
if the first is larger than the second, as determined by lexicographic comparison.
Mnemonic: greater than
infix ge
multi sub infix:<ge>(Mu, Mu)multi sub infix:<ge>(Str, Str)
String greater than or equal to operator.
Coerces both arguments to Str (if necessary); returns True
if the first is equal to or larger than the second, as determined by lexicographic comparison.
Mnemonic: greater or equal
infix lt
multi sub infix:<lt>(Mu, Mu)multi sub infix:<lt>(Str, Str)
Coerces both arguments to Str (if necessary); returns True
if the first is smaller than the second, as determined by lexicographic comparison.
Mnemonic: less than
infix le
multi sub infix:<le>(Mu, Mu)multi sub infix:<le>(Str, Str)
String less than or equal to operator.
Coerces both arguments to Str (if necessary); returns True
if the first is equal to or smaller than the second, as determined by lexicographic comparison.
Mnemonic: less or equal
infix before
multi sub infix:<before>(Any, Any)multi sub infix:<before>(Real, Real)multi sub infix:<before>(Str, Str)multi sub infix:<before>(Version, Version)
Generic ordering, uses the same semantics as cmp. Returns True
if the first argument is smaller than the second.
infix after
multi sub infix:<after>(Any, Any)multi sub infix:<after>(Real, Real)multi sub infix:<after>(Str, Str)multi sub infix:<after>(Version, Version)
Generic ordering, uses the same semantics as cmp. Returns True
if the first argument is larger than the second.
infix eqv
sub infix:<eqv>(Any, Any)
Equivalence operator. Returns True
if the two arguments are structurally the same, i.e. from the same type and (recursively) contain equivalent values.
say [1, 2, 3] eqv [1, 2, 3]; # OUTPUT: «True»say Any eqv Any; # OUTPUT: «True»say 1 eqv 2; # OUTPUT: «False»say 1 eqv 1.0; # OUTPUT: «False»
Lazy Iterables
cannot be compared, as they're assumed to be infinite. However, the operator will do its best and return False
if the two lazy Iterables
are of different types or if only one Iterable
is lazy.
say (1…∞) eqv (1…∞).List; # Both lazy, but different types; OUTPUT: «False»say (1…∞) eqv (1…3); # Same types, but only one is lazy; OUTPUT: «False»(try say (1…∞) eqv (1…∞)) # Both lazy and of the same type. Cannot compare; throws.orelse say $!.^name; # OUTPUT: «X::Cannot::Lazy»
The default eqv
operator even works with arbitrary objects. E.g., eqv
will consider two instances of the same object as being structurally equivalent:
mysay A.new(a => 5) eqv A.new(a => 5); # OUTPUT: «True»
Although the above example works as intended, the eqv
code might fall back to a slower code path in order to do its job. One way to avoid this is to implement an appropriate infix eqv
operator:
mymulti infix:<eqv>(A , A )say A.new(a => 5) eqv A.new(a => 5); # OUTPUT: «True»
Note that eqv
does not work recursively on every kind of container type, e.g. Set
:
mysay Set(A.new(a => 5)) eqv Set(A.new(a => 5)); # OUTPUT: «False»
Even though the contents of the two sets are eqv
, the sets are not. The reason is that eqv
delegates the equality check to the Set
object which relies on element-wise ===
comparison. Turning the class A
into a value type by giving it a WHICH
method produces the expected behavior:
mysay Set(A.new(a => 5)) eqv Set(A.new(a => 5)); # OUTPUT: «True»
infix ===
sub infix:<===>(Any, Any)
Value identity operator. Returns True
if both arguments are the same object, disregarding any containerization.
my ;my = A.new;say === ; # OUTPUT: «True»say A.new === A.new; # OUTPUT: «False»say A === A; # OUTPUT: «True»
For value types, ===
behaves like eqv
:
say 'a' === 'a'; # OUTPUT: «True»say 'a' === 'b'; # OUTPUT: «False»my = 'a';say === 'a'; # OUTPUT: «True»# different typessay 1 === 1.0; # OUTPUT: «False»
===
uses the WHICH method to obtain the object identity.
If you want to create a class that should act as a value type, then that class must create an instance method WHICH
, that should return a ValueObjAt object that won't change for the lifetime of the object.
infix =:=
multi sub infix:<=:=>(Mu \a, Mu \b)
Container identity operator. Returns True
if both arguments are bound to the same container. If it returns True
, it generally means that modifying one will also modify the other.
my (, ) = (1, 3);say =:= ; # OUTPUT: «False»= 2;say ; # OUTPUT: «1»:= ;say =:= ; # OUTPUT: «True»= 5;say ; # OUTPUT: «5»
infix ~~
The smartmatch operator aliases the left-hand side to $_
, then evaluates the right-hand side and calls .ACCEPTS($_)
on it. The semantics are left to the type of the right-hand side operand.
Here is a partial list of some of the built-in smartmatching functionality. For full details, see ACCEPTS documentation for the type on the right-hand side of the operator.
Right-hand side | Comparison semantics |
---|---|
Mu:U | type check |
Str | string equality |
Numeric | numeric equality |
Regex | regex match |
Callable | boolean result of invocation |
Set/Bag | equal element values |
Any:D | object identity |
infix =~=
multi sub infix:<=~=>(Any, Any)multi sub infix:<=~=>(Int, Int)multi sub infix:<=~=>(Num, Num)multi sub infix:<=~=>(Rational, Rational)multi sub infix:<=~=>(Real, Real)multi sub infix:<=~=>(Complex, Complex)multi sub infix:<=~=>(Numeric, Numeric)
The approximately-equal operator ≅
, whose ASCII variant is =~=
, calculates the relative difference between the left-hand and right-hand sides and returns True
if the difference is less than $*TOLERANCE
(which defaults to 1e-15). However, if either side is zero then it checks that the absolute difference between the sides is less than $*TOLERANCE
. Note that this operator is not arithmetically symmetrical (doesn't do ± Δ):
my = 1;say ( + ) ; # OUTPUT: «False»say ( - ) ; # OUTPUT: «True»
The tolerance is supposed to be modifiable via an adverb:
my (, ) = 42, 42.1;say :tolerance(.1);
However, this is not yet implemented. The same effect can be achieved by assigning to $*TOLERANCE.
Note that setting $*TOLERANCE = 0 will cause all comparisons to fail.
infix (elem), infix ∈»
multi sub infix:<(elem)>(, --> Bool)multi sub infix:<∈>(, --> Bool)
Returns True
if $a
is an element of $b
.
say 2 (elem) (1, 2, 3); # OUTPUT: «True»say 4 ∈ (1, 2, 3); # OUTPUT: «False»
∈
is equivalent to (elem)
, at codepoint U+2208 (ELEMENT OF).
infix ∉
multi sub infix:<∉>(, --> Bool)
Returns True
if $a
is not an element of $b
. Equivalent to !(elem)
.
say 4 ∉ (1, 2, 3); # OUTPUT: «True»say 2 !(elem) (1, 2, 3); # OUTPUT: «False»
∉
is codepoint U+2209 (NOT AN ELEMENT OF).
infix (cont), infix ∋»
multi sub infix:<(cont)>(, --> Bool)multi sub infix:<∋>(, --> Bool)
Returns True
if $a
is an element of $b
.
say (1,2,3) (cont) 2; # OUTPUT: «True»say (1, 2, 3) ∋ 4; # OUTPUT: «False»
∋
is equivalent to (cont)
, at codepoint U+220B (CONTAINS AS MEMBER).
infix ∌
multi sub infix:<∌>(, --> Bool)
Returns True
if $a
is not an element of $b
. Equivalent to !(cont)
.
say (1,2,3) ∌ 4; # OUTPUT: «True»say (1,2,3) !(cont) 2; # OUTPUT: «False»
∉
is codepoint U+220C (DOES NOT CONTAIN AS MEMBER).
infix (<)
, infix ⊂
multi sub infix:<< (<) >>(, --> Bool)multi sub infix:<⊂>(, --> Bool)
Returns True
if $a
is a strict subset of $b
, i.e., that all the elements of $a
are elements of $b
but $a
is a smaller set than $b
.
say (1,2,3) (<) (2,3,1); # OUTPUT: «False»say (2,3) (<) (2,3,1); # OUTPUT: «True»say 4 ⊂ (1,2,3); # OUTPUT: «False»
⊂
is equivalent to (<)
, at codepoint U+2282 (SUBSET OF).
infix ⊄
multi sub infix:<⊄>(, --> Bool)
Returns True
if $a
is not a strict subset
of $b
. Equivalent to !(<)
.
say (1,2,3) ⊄ (2,3,1); # OUTPUT: «True»say (2,3) ⊄ (2,3,1); # OUTPUT: «False»say 4 !(<) (1,2,3); # OUTPUT: «True»
⊄
is codepoint U+2284 (NOT A SUBSET OF).
infix (<=)
, infix ⊆
multi sub infix:<< (<=) >>(, --> Bool)multi sub infix:<⊆>(, --> Bool)
Subset of or equal to operator.
Returns True
if $a
is a subset of $b
, i.e., that all the elements of $a
are elements of $b
but $a
is a smaller or equal sized set than $b
.
say (1,2,3) (<=) (2,3,1); # OUTPUT: «True»say (2,3) (<=) (2,3,1); # OUTPUT: «True»say 4 ⊆ (1,2,3); # OUTPUT: «False»
⊆
is equivalent to (<=)
, at codepoint U+2286 (SUBSET OF OR EQUAL TO).
infix ⊈
multi sub infix:<⊈>(, --> Bool)
Not a subset of nor equal to operator.
Returns True
if $a
is not a subset
of $b
. Equivalent to !(<=)
.
say (1,2,3) ⊄ (2,3,1); # OUTPUT: «True»say (2,3) ⊄ (2,3,1); # OUTPUT: «False»say 4 !(<=) (1,2,3); # OUTPUT: «True»
⊈
is codepoint U+2288 (NEITHER A SUBSET OF NOR EQUAL TO).
infix (>)
, infix ⊃
multi sub infix:<< (>) >>(, --> Bool)multi sub infix:<⊃>(, --> Bool)
Returns True
if $a
is a strict superset of $b
, i.e., that all the elements of $b
are elements of $a
but $a
is a larger set than $b
.
say (1,2,3) (>) (2,3,1); # OUTPUT: «False»say (1,2,3) (>) (2,3); # OUTPUT: «True»say 4 ⊃ (1,2,3); # OUTPUT: «False»
⊃
is equivalent to (>)
, at codepoint U+2283 (SUPERSET OF).
infix ⊅
multi sub infix:<⊅>(, --> Bool)
Returns True
if $a
is not a strict superset
of $b
. Equivalent to !(>)
.
say (1,2,3) ⊅ (2,3,1); # OUTPUT: «True»say (1,2,3) ⊅ (2,3); # OUTPUT: «False»say 4 !(>) (1,2,3); # OUTPUT: «True»
⊅
is codepoint U+2285 (NOT A SUPERSET OF).
infix (>=)
, infix ⊇
multi sub infix:<< (>=) >>(, --> Bool)multi sub infix:<⊇>(, --> Bool)
Superset of or equal to operator.
Returns True
if $a
is a superset of $b
, i.e., that all the elements of $b
are elements of $a
but $a
is a larger or equal sized set than $b
.
say (1,2,3) (>=) (2,3,1); # OUTPUT: «True»say (1,2,3) (>=) (2,3); # OUTPUT: «True»say 4 ⊇ (1,2,3); # OUTPUT: «False»
⊇
is equivalent to (>=)
, at codepoint U+2287 (SUPERSET OF OR EQUAL TO).
infix ⊉
multi sub infix:<⊉>(, --> Bool)
Not a superset of nor equal to operator.
Returns True
if $a
is not a superset
of $b
. Equivalent to !(>=)
.
say (1,2,3) ⊉ (2,3,1); # OUTPUT: «False»say (1,2,3) ⊉ (2,3); # OUTPUT: «False»say 4 !(>=) (1,2,3); # OUTPUT: «True»
⊉
is codepoint U+2289 (NEITHER A SUPERSET OF OR EQUAL TO).
Tight AND precedence
infix &&
Returns the first argument that evaluates to False
in boolean context, otherwise returns 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 are never evaluated.
sub asub bsub c ;say a() && b() && c(); # OUTPUT: «0»
Tight OR precedence
infix ||
Returns the first argument that evaluates to True
in boolean context, otherwise returns the last argument.
Note that this short-circuits; i.e., if one of the arguments evaluates to a true value, the remaining arguments are not evaluated.
sub asub bsub c ;say a() || b() || c(); # OUTPUT: «1»
infix ^^
Short-circuit exclusive-or. Returns the true argument if there is one (and only one). Returns the last argument if all arguments are false. Returns Nil
when more than one argument is true.
This operator short-circuits in the sense that it does not evaluate any arguments after a 2nd true result.
say 0 ^^ 42; # OUTPUT: «42»say '' ^^ 0; # OUTPUT: «0»say 0 ^^ 42 ^^ 1 ^^ die "never called"; # OUTPUT: «Nil»
Note that the semantics of this operator may not be what you assume: infix ^^
flips to the first true value it finds and then flips to Nil 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.)
infix //
The defined-or operator or infix // returns the first defined operand, or else the last operand. Short-circuits.
say Any // 0 // 42; # OUTPUT: «0»
infix min
Returns the smallest of the arguments, as determined by cmp semantics.
my = 42;min= 0 # read as: $foo decreases to 0
infix max
Returns the largest of the arguments, as determined by cmp semantics.
my = -42;max= 0 # read as: $foo increases to 0
infix minmax
Returns the Range starting from the lowest to the highest of the values, as determined by the cmp semantics. For instance:
# numeric comparison10 minmax 3; # 3..10# string comparison'10' minmax '3'; # "10".."3"'z' minmax 'k'; # "k".."z"
If the lowest and highest values coincide, the operator returns a Range made by the same value:
1 minmax 1; # 1..1
When applied to Lists, the operator evaluates the lowest and highest values among all available values:
(10,20,30) minmax (0,11,22,33); # 0..33('a','b','z') minmax ('c','d','w'); # "a".."z"
Similarly, when applied to Hashes, it performs a cmp way comparison:
my = points => 30, misses => 10;my = points => 20, misses => 10;cmp ; # Moreminmax ;# ${:misses(10), :points(20)}..${:misses(10), :points(30)}
Conditional operator precedence
infix ?? !!
Also called ternary or conditional operator, $condition ?? $true !! $false
evaluates $condition
and returns the expression right behind ??, in this case $true
if it is True
, otherwise evaluates and returns the expression behind !!, $false
in this case.
infix ff
sub infix:<ff>(Mu , Mu )
Also called the flipflop operator, compares both arguments to $_
(that is, $_ ~~ $a
and $_ ~~ $b
). Evaluates to False
until the left-hand smartmatch is True
, at which point it evaluates to True
until the right-hand smartmatch is 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:
my $excerpt = q:to/END/; Here's some unimportant text. =begin code This code block is what we're after. We'll use 'ff' to get it. =end code More unimportant text. END my @codelines = gather for $excerpt.lines { take $_ if "=begin code" ff "=end code" } # this will print four lines, starting with "=begin code" and ending with # "=end code" say @codelines.join("\n");
After matching the start condition, the operator will then match the same $_
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>
If you only want to test against a start condition and have no stop condition, *
can be used as such.
for <A B C D E>
For the sed
-like version, which does not try $_
on the stop condition after succeeding on the start condition, see fff.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix ^ff
sub infix:<^ff>(Mu , Mu )
Works like ff, except it does not return True
for items matching the start condition (including items also matching the stop condition).
A comparison:
my = <A B C>;say if /A/ ff /C/ for ; # OUTPUT: «ABC»say if /A/ ^ff /C/ for ; # OUTPUT: «BC»
The sed-like version can be found in ^fff
.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix ff^
sub infix:<ff^>(Mu , Mu )
Works like ff, except it does not return True
for items matching the stop condition (including items that first matched the start condition).
my = <A B C>;say if /A/ ff /C/ for ; # OUTPUT: «ABC»say if /A/ ff^ /C/ for ; # OUTPUT: «AB»
The sed-like version can be found in fff^.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix ^ff^
sub infix:<^ff^>(Mu , Mu )
Works like ff, except it does not return True
for items matching either the stop or start condition (or both).
my = <A B C>;say if /A/ ff /C/ for ; # OUTPUT: «ABC»say if /A/ ^ff^ /C/ for ; # OUTPUT: «B»
The sed-like version can be found in ^fff^
.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix fff
sub infix:<fff>(Mu , Mu )
Performs a sed-like flipflop operation, wherein it returns False
until the left argument smartmatches against $_
, then returns True
until the right argument smartmatches against $_
.
Works similarly to ff, except that it only tries one argument per invocation. That is, if $_
smartmatches the left argument, fff
will not then try to match that same $_
against the right argument.
for <AB C D B E F>
The non-sed-like flipflop (which after successfully matching the left argument against $_
will try that same $_
against the right argument and act accordingly). See ff.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix ^fff
sub infix:<^fff>(Mu , Mu )
Like fff, except it does not return true for matches to the left argument.
my = <A B C>;say if /A/ fff /C/ for ; # OUTPUT: «ABC»say if /A/ ^fff /C/ for ; # OUTPUT: «BC»
For the non-sed version, see ^ff
.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix fff^
sub infix:<fff^>(Mu , Mu )
Like fff, except it does not return true for matches to the right argument.
my = <A B C>;say if /A/ fff /C/ for ; # OUTPUT: «ABC»say if /A/ fff^ /C/ for ; # OUTPUT: «AB»
For the non-sed version, see ff^.
This operator cannot be overloaded, as it's handled specially by the compiler.
infix ^fff^
sub infix:<^fff^>(Mu , Mu )
Like fff, except it does not return true for matches to either the left or right argument.
my = <A B C>;say if /A/ fff /C/ for ; # OUTPUT: «ABC»say if /A/ ^fff^ /C/ for ; # OUTPUT: «B»
For the non-sed version, see ^ff^
.
This operator cannot be overloaded, as it's handled specially by the compiler.
Item assignment precedence
infix =
sub infix:<=>(Mu is rw, Mu )
Called the item assignment operator, it 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 =
is parsed as item assignment or list assignment operator).
infix =>
sub infix:«=>»(, Mu --> Pair)
Pair constructor.
Constructs a Pair object with the left-hand side as the key and the right-hand side as the value.
Note that the =>
operator is syntactically special-cased, in that it allows unquoted identifier on the left-hand side.
my = a => 1;say .key; # OUTPUT: «a»say .value; # OUTPUT: «1»
A Pair within an argument list with an unquoted identifier on the left is interpreted as a named argument.
See the Terms language documentation for more ways to create Pair
objects.
Loose unary precedence
prefix not
multi sub prefix:<not>(Mu --> Bool)
Evaluates its argument in boolean context (and thus collapses Junctions), and negates the result. Please note that not
is easy to misuse. See traps.
prefix so
multi sub prefix:<so>(Mu --> Bool)
Evaluates its argument in boolean context (and thus collapses Junctions), and returns the result.
Comma operator precedence
infix ,
sub infix:<,>(* --> List) is assoc<list>
Constructs a higher-order Cool from its arguments.
my = :god('Þor'), ['is',"mighty"];say ; # OUTPUT: «[god => Þor [is mighty]]»my = :god('Þor'), :is("mighty");say .perl; # OUTPUT: «{:god("Þor"), :is("mighty")}»my = :11a, :22b;say %(, :33x); # OUTPUT: «{a => 11, b => 22, x => 33}»
In the first case it returns a List, in the second case, since the arguments are Pairs, it builds a Hash.
It can also be used for constructing variables from other variables, collating elements of different types, in this case a Hash and a Pair:
my = , :wields("hammer");say ; # OUTPUT: «{god => Þor, is => mighty, wields => hammer}»
The comma is also used syntactically as the separator of arguments in calls.
infix :
Used as an argument separator just like infix ,
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 :
is only allowed after the first argument of a non-method call. In other positions, it's a syntax error.
List infix precedence
infix Z
sub infix:<Z>(** --> Seq) is assoc<chain>
The Zip operator interleaves the lists passed to Z
like a zipper, taking index-corresponding elements from each operand. The returned Seq
contains nested lists, each with a value from every operand in the chain. If one of the operands runs out of elements prematurely, the zip operator will stop.
say (1, 2 Z <a b c> Z <+ ->).perl;# OUTPUT: «((1, "a", "+"), (2, "b", "-")).Seq»for <a b c> Z <1 2 3 4> -> [, ]# OUTPUT: «a:1b:2c:3»
The Z
operator also exists as a metaoperator, in which case the inner lists are replaced by the value from applying the operator to the list:
say 100, 200 Z+ 42, 23; # OUTPUT: «(142 223)»say 1..3 Z~ <a b c> Z~ 'x' xx 3; # OUTPUT: «(1ax 2bx 3cx)»
infix X
Defined as:
multi sub infix:<X>(+lol, :! --> Seq)multi sub infix:<X>(+lol --> Seq)
Creates a cross product from all the lists, ordered so that the rightmost elements vary most rapidly, and returns a Seq
:
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 X
operator also exists as a metaoperator, in which case the inner lists are replaced by the value from applying the operator to the list:
1..3 X~ <a b c> X~ 9# produces (1a9 1b9 1c9 2a9 2b9 2c9 3a9 3b9 3c9)
infix ...
multi sub infix:<...>(**@) is assoc<list>multi sub infix:<...^>(**@) is assoc<list>
The sequence operator, which can be written either as ...
or as …
(with variants ...^
and …^
) will produce (possibly lazy) generic sequences on demand.
The left-hand side will always include the initial elements; it may include a generator too (after the first element or elements). The right-hand side will have an endpoint, which can be Inf
or *
for "infinite" lists (that is, lazy lists whose elements are only produced on demand), an expression which will end the sequence when True
, or other elements such as Junctions.
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 *.
succ or *.
pred, depending on how the end points compare:
say 1 ... 4; # OUTPUT: «(1 2 3 4)»say 4 ... 1; # OUTPUT: «(4 3 2 1)»say 'a' ... 'e'; # OUTPUT: «(a b c d e)»say 'e' ... 'a'; # OUTPUT: «(e d c b a)»
An endpoint of *
(Whatever), Inf
or ∞
generates on demand an infinite sequence, with a default generator of *.succ
say (1 ... *)[^5]; # OUTPUT: «(1 2 3 4 5)»
Custom generators need to be the last element of the list before the '...' operator. This one takes two arguments, and generates the eight first Fibonacci numbers
say (1, 1, -> , ... *)[^8]; # OUTPUT: «(1 1 2 3 5 8 13 21)»# same but shortersay (1, 1, * + * ... *)[^8]; # OUTPUT: «(1 1 2 3 5 8 13 21)»
Of course the generator can also take only one argument.
say 5, ... 40; # OUTPUT: «5 10 20 40»
There must be at least as many initial elements as arguments to the generator.
Without a generator and with 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; # OUTPUT: «(2 4 6 8 10 12)»say 1, 2, 4 ... 32; # OUTPUT: «(1 2 4 8 16 32)»
If the endpoint is not *
, it's smartmatched against each generated element and the sequence is terminated when the smartmatch succeeded. For the ...
operator, the final element is included, for the ...^
operator it's excluded.
This allows you to write
say 1, 1, * + * ...^ *>= 100;
to generate all Fibonacci numbers up to but excluding 100.
The ...
operators consider the initial values as "generated elements" as well, so they are also checked against the endpoint:
my = 4;say 1, 2, 4, 8, 16 ... ;# OUTPUT: «(1 2 4)»
List prefix precedence
infix =
In this context, it acts as the list assignment operator. Its exact semantics are left to the container type on the left-hand side. See Array and 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.
infix :=
Binding operator. Whereas $x = $y
puts the value in $y
into $x
, $x := $y
makes $x
and $y
the same thing.
my = 42;my = ;++;say ;
This will output 42, because $a
and $b
both contained the number 42
, but the containers were different.
my = 42;my := ;++;say ;
This will output 43, since $b
and $a
both represented the same object.
If type constrains on variables or containers are present a type check will be performed at runtime. On failure X::TypeCheck::BindingType
will be thrown.
Please note that :=
is a compile time operator. As such it can not be referred to at runtime and thus can't be used as an argument to metaoperators.
infix ::=
Read-only binding operator, not yet implemented in Rakudo. See infix :=
.
listop ...
Called the yada, yada, yada operator or stub operator, if it's 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 ...
statement is executed, it calls fail, with the default message Stub code executed
.
listop !!!
If it's 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 !!!
statement is executed, it calls die, with the default message Stub code executed
.
listop ???
If it's 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 ???
statement is executed, it calls warn, with the default message Stub code executed
.
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.
say [+] 1, 2, 3; # 1 + 2 + 3 = 6my = (5, 6);say [*] ; # 5 * 6 = 30
Reduction operators have the same associativity as the operators they are based on.
say [-] 4, 3, 2; # 4-3-2 = (4-3)-2 = -1say [**] 4, 3, 2; # 4**3**2 = 4**(3**2) = 262144
Loose AND precedence
infix and
Same as infix &&, except with looser precedence.
Short-circuits so that it returns the first operand that evaluates to False
, otherwise returns the last operand. Note that and
is easy to misuse, see traps.
infix andthen
The andthen
operator returns Empty
upon encountering the first undefined argument, otherwise the last argument. Last argument is returned as-is, without being checked for definedness at all. 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 Callable
, whose count must be 0
or 1
.
A handy use of this operator is to alias a routine's return value to $_
and to do additional manipulation with it, such as printing or returning it to caller. Since the andthen
operator short-circuits, statements on the right-hand side won't get executed, unless left-hand side is defined (tip: Failures are never defined, so you can handle them with this operator).
sub load-dataload-data.first: /good/ andthen say "$_ is good";# OUTPUT: «(good data is good)»load-data() andthen .return; # return loaded data, if it's defineddie "Failed to load data!!";
The above example will print good data is good
only if the subroutine returned any items that match /good/
and will die unless loading data returned a defined value. The aliasing behavior lets us pipe the values across the operator.
The andthen
operator is a close relative of with
statement modifier, and some compilers compile with
to andthen
, meaning these two lines have equivalent behavior:
.say with 42;42 andthen .say;
infix notandthen
The notandthen
operator returns Empty
upon encountering the first defined argument, otherwise the last argument. Last argument is returned as-is, without being checked for definedness at all. 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 Callable
, whose count must be 0
or 1
.
At first glance, notandthen might appear to be the same thing as the orelse operator. The difference is subtle: notandthen returns Empty
when it encounters a defined item (that isn't the last item), whereas orelse returns that item. In other words, notandthen is a means to act when items aren't defined, whereas orelse is a means to obtain the first defined item:
sub all-sensors-downsub first-working-sensorall-sensors-down Nil, Nil, Niland say 'OMG! All sensors are down!'; # OUTPUT:«OMG! All sensors are down!»say first-working-sensor Nil, Nil, Nil; # OUTPUT:«default sensor»all-sensors-down Nil, 42, Niland say 'OMG! All sensors are down!'; # No outputsay first-working-sensor Nil, 42, Nil; # OUTPUT:«42»
The notandthen
operator is a close relative of without
statement modifier, and some compilers compile without
to notandthen
, meaning these two lines have equivalent behavior:
sub good-things'boo'.say without good-things;good-things() notandthen 'boo'.say;
Loose OR precedence
infix or
Same as infix ||
, except with looser precedence.
Returns the first argument that evaluates to True
in boolean context, or otherwise the last argument, it short-circuits. Please note that or
is easy to misuse. See traps.
infix orelse
The orelse
operator is similar to infix //
, except with looser precedence and $_
aliasing.
Returns the first defined argument, or else the last argument. Last argument is returned as-is, without being checked for definedness at all. Short-circuits. The result of the left side is bound to $_
for the right side, or passed as an argument if the right side is a Callable
, whose count must be 0
or 1
.
This operator is useful for handling Failures returned by routines since the expected value is usually defined and Failure never is:
sub meowssub meows-processor1 # return handled Failuresub meows-processor2 # return re-armed Failuresub meows-processor3say ", " # OUTPUT: «Failure, True»given meows-processor1;say ", " # OUTPUT: «Failure, False»given meows-processor2;meows-processor3; # OUTPUT: «something's wrong»meows-processor3; # OUTPUT: «🐱»
infix xor
Same as infix ^^
, except with looser precedence.
Returns the operand that evaluates to True
in boolean context, if and only if the other operand evaluates to False
in boolean context. If both operands evaluate to False
, returns the last argument. If both operands evaluate to True
, returns Nil
.
When chaining, returns the operand that evaluates to True
, if and only if there is one such operand. If more than one operand is true, it short-circuits after evaluating the second and returns Nil
. If all operands are false, returns the last one.
Sequencer precedence
infix ==>
This feed operator takes the result from the left and passes it to the next (right) routine as the last parameter.
my = (1, 2, 3, 4, 5);==> sum() ==> say(); # OUTPUT: «15»
This simple example, above, is the equivalent of writing:
my = (1, 2, 3, 4, 5);say(sum()); # OUTPUT: «15»
Or if using methods:
my = (1, 2, 3, 4, 5);.sum.say; # OUTPUT: «15»
The precedence is very loose so you will need to use parentheses to assign the result or you can even just use another feed operator! In the case of routines/methods that take a single argument or where the first argument is a block, it's often required that you call with parentheses (though this is not required for the very last routine/method).
This "traditional" structure, read bottom-to-top, with the last two lines creating the data structure that is going to be processed
my = <TWO THREE FOUR FIVE SEVEN> »~» " " X~ <FIFTHS SIXTHS EIGHTHS>;my = map , # (3) Converts to unicodegrep , # (2) Checks if it parsesmap( , ); # (1) Adds string to input# @result is [⅖ ⅗ ⅜ ⅘ ⅚ ⅝ ⅞]
Now we use the feed operator (left-to-right) with parentheses, read top-to-bottom
my = (<TWO THREE FOUR FIVE SEVEN> »~» " " X~ <FIFTHS SIXTHS EIGHTHS> # (1) Input==> map( ) # (2) Converts to Unicode name==> grep() # (3) Filters only real names==> map( ); # (4) Converts to unicode);
For illustration, method chaining equivalent, read top-to-bottom, using the same sequence as above
my = ( <TWO THREE FOUR FIVE SEVEN> »~» " " X~ <FIFTHS SIXTHS EIGHTHS>).map( ).grep().map();
Although in this particular case the result is the same, the feed operator ==>
more clearly shows intent with arrow pointing in the direction of the data flow. To assign without the need of parentheses use another feed operator
my ;<people of earth>==> map()==> grep /<[PE]>/==> sort()==> ;
It can be useful to capture a partial result, however, unlike the leftward feed operator, it does require parentheses or a semicolon
my ;<people of earth>==> map()==> my ; # also could wrap in parentheses instead==> grep /<[PE]>/==> sort()==> ;
The feed operator lets you construct method-chaining-like patterns out of routines and the results of methods on unrelated data. In method-chaining, you are restricted to the methods available on the data or the result of previous method call. With feed operators, that restriction is gone. The resulting code could also be seen to be more readable than a series of method calls broken over multiple lines.
Note: In the future, this operator will see some change as it gains the ability to run list operations in parallel. It will enforce that the left operand is enclosable as a closure (that can be cloned and run in a subthread).
infix <==
This leftward feed operator takes the result from the right and passes it to the previous (left) routine as the last parameter. This elucidates the right-to-left dataflow for a series of list manipulating functions.
# Traditional structure, read bottom-to-topmy =sort # (4) Sort, result is <Earth People>grep , # (3) Look for P or Emap , # (2) Capitalize the words<people of earth>; # (1) Start with the input# Feed (right-to-left) with parentheses, read bottom-to-topmy = (sort() # (4) Sort, result is <Earth People><== grep() # (3) Look for P or E<== map() # (2) Capitalize the words<== <people of earth> # (1) Start with the input);# To assign without parentheses, use another feed operatormy<== sort() # (4) Sort, result is <Earth People><== grep() # (3) Look for P or E<== map() # (2) Capitalize the words<== <people of earth>; # (1) Start with the input# It can be useful to capture a partial resultmy<== sort()<== grep()<== my @caps # unlike ==>, there's no need for additional statement<== map()<== <people of earth>;
Unlike the rightward feed operator, the result is not closely mappable to method-chaining. However, compared to the traditional structure above where each argument is separated by a line, the resulting code is more demonstrative than commas. The leftward feed operator also allows you to "break into" the statement and capture an intermediary result which can be extremely useful for debugging or to take that result and create another variation on the final result.
Note: In the future, this operator will see some change as it gains the ability to run list operations in parallel. It will enforce that the right operand is enclosable as a closure (that can be cloned and run in a subthread).
Identity
In general, infix operators can be applied to a single or no element without yielding an error, generally in the context of a reduce operation.
say [-] () # OUTPUT: «0»
The design documents specify that this should return an identity value, and that an identity value must be specified for every operator. In general, the identity element returned should be intuitive. However, here is a table that specifies how it is defined for operator classes in Perl 6, which corresponds to the table in the above definition in the types and operators defined by the language:
Operator class | Identity value |
---|---|
Equality | Bool::True |
Arithmetic + | 0 |
Arithmetic * | 1 |
Comparison | True |
Bitwise | 0 |
Stringy | '' |
Sets | Empty set or equivalent |
Or-like Bool | False |
And-like Bool | True |
For instance, union of an empty list will return an empty set:
say [∪]; # OUTPUT: «set()»
This only applies to operators where empty or 0 is always a valid operand. For instance, applying it to division will yield an exception.
say [%] (); # OUTPUT: «(exit code 1) No zero-arg meaning for infix:<%>