Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
552 lines (368 sloc) 16.3 KB

Operators are very short names for often used routines. They have special calling syntax, and can be manipulated by other operators.

Returning to the table tennis example, suppose you want to plot the number of sets that each player won in a tournament. This example uses the numbers from the previous chapter, and makes a very simple text output by just printing a number of X characters to represent horizontal bars.


The line

already contains three different operators: =, => and ,.

The = operator is the assignment operator -- it takes the values from the right-hand side, and stores them in the variable on the left-hand side, here @scores.

The => operator (the fat arrow) constructs Pair objects. A Pair stores a key and a value; the key is on the left-hand side of the => operator, the value on the right. It also has a specialty: if the key on the left is a bare identifier, it is taken to be a string. So one could also write the example above as

Finally, the , operator constructs a Parcel, which is a sequence of objects. In this case the objects are pairs.

All of the three operators above are infix operators, which means they stand in between two terms. A term can be a literal like 8 or 'Dave', or a combination of other terms and operators.

The previous chapter already used other types of operators, too. It contained the statement %games{$p1}++; which uses the postcircumfix operator {...}. It stands behind (post) a term, and consists of two symbols (an opening and a closing curly bracket) which enclose (circumfix) another term. Behind this postcircumfix operator is an ordinary postfix operator with name ++, which increments the value it qualifies. No whitespace is allowed between a term and its postfix or postcircumfix operators.

Yet another operator type is the prefix operator, which stands in front of a term. An example is the - operator, which negates the following numeric value, as in my $x = -4.

But the - operator can also mean subtraction, so say 5 - 4 will print a 1. To distinguish the prefix operator - from the infix operator -, the Perl 6 parser always keeps track of whether it expects an infix operator or a term. A term can have zero or more prefix operators, so you can actually write say 4 + -5. After the + (an infix operator), the compiler expects a term, thus the - is interpreted as a prefix operator to the term 5.

The next line containing new features is

It begins harmlessly with a variable declaration my $label-area-width and an assignment to it. Next comes a simple numeric addition, 1 + .... The right side of the + operator is more complicated.

In Perl 6 there is an infix max operator which returns the greater of two values, so 2 max 3 returns 3. Square brackets around an infix operator indicate that it is applied to a list piece by piece. So [max] 1, 5, 3, 7 is the same as 1 max 5 max 3 max 7 and evaluates to 7.

Likewise, you can write [+] to get the sum of a list of values, [*] for the product, and use [<=] to check if a list is ordered by ascending values.

After the [max] you see the expression @scores».key».chars. Just like @variable.method calls a method on @variable, @array».method calls a method for each item in @array, and returns the list of the return values.

» is called a hyper operator. It is a unicode character that can be entered on most computers Ubuntu 10.4: In System/Preferences/Keyboard/Layouts/Options/Compose Key position select on of the keys to be the "Compose" key. Then press Compose-key and the "greater than" key twice. If your operating system does not make it easy to write it you can also write it using two angle brackets (>>).

So @scores».key is a list of all the keys of the pair objects in @scores, and @scores».key».chars is a list of the length of all keys in @scores.

The expression [max] @scores».key».chars gives the largest of these values. It is the same as

The square brackets are called the reduction meta operator: it transforms the enclosed infix operator into an operator that expects a list (a listop), and carries out the operation between each two consecutive list items.

For plotting the names of the players and bar charts, the program needs to know how much space to allocate for the player names. Adding 1 to it leaves space for a single blank space between the name of the longest player and the left edge of the bars.

With this line the program determines the maximum score. The drawing area has the width $screen-width - $label-area-width, so for each score we can print

amount of X characters. This expression uses the infix operators - and / for numerical calculations.

Now all the necessary informations are in place and the chart can be printed:

These lines loop over the items in @scores, binding them to the special variable $_ one at a time. For each such item, the program uses the printf built-in function to print both the name of the player and a bar.

It is similar to printf functions of the C and Perl 5 programming languages. It takes a format string, which specifies how to print the following parameters. If $label-area-width is 8, the format string is "%- 8s%s\n", which means a string ('s') filled to 8 spaces (' 8') and left-justified ('-'), followed by another string and a newline.

The first string is the name of the player, the second is the bar.

The bar is generated with the infix x operator, the repetition operator. It takes a string on the left-hand side and a number on the right-hand side, and sticks the strings together as many times as the number specifies. So 'ab' x 3 returns the string 'ababab'. .value returns the value of the current pair, ($unit * .value) multiplies that values with $unit, and 'X' x ($unit * .value) returns as that many X characters.

A Word on Precedence

The explanations of the example above have one implication, which was not yet explicitly mentioned. In the line

The right-hand side of the assignment produces a list (because of the , operator) that is made of pairs (because of =>), and the result is then assigned to the array variable. But you could think of other ways that Perl 6 interprets this program. If you pass this line to the Perl 5 interpreter, it parses it as

and thus stores only one item in the variable @scores, the rest is parsed as a listand discarded, because it is not stored in any variable.

The ways in which this statement is parsed in Perl 6 is governed by precedence rules. For example, they state that the infix => operator binds its arguments tighter than the infix , operator, which in turn binds tighter than the = assignment operatorThere are actually two assignment operators with different precedence. When the right-hand side is a scalar, the item assignment operator with tight precedence is used, otherwise the loose-precedence list assignment operator is used. This allows the two expressions $a = 1, $b = 2 and @a = 1, 2 to both mean something sensible: assignment to two variables in a list, and assignment of a two-item list to a single variable.

The precedence rules for Perl 6 allow many commonly used idioms to be expressed naturally and without any parentheses, or even without thinking about precedence. If you want to force a different way of parsing, parentheses can be used around an expression. Then this parenthesis group has the tightest possible precedence.

    TODO: list of precedence levels?

Comparisons and Smart Matching

There are several ways to compare objects in Perl. You can test for value equivalence using the === infix operator. For immutable objectsObjects whose value can not be changed; a literal value. For instance, the literal 7 will always and forever be just a 7., this is an ordinary value comparison. "hello" === "hello" is true because both strings are immutable and have the same value.

For mutable objects, === compares their identities. Two objects only share the same identity if, in fact, they are the same object. In the following example, the two arrays @a and @b, while they contain the same values, are two separate array objects which have different identities and are thus not equivalent under ===.

The eqv operator returns True only if two objects are of the same type, and of the same structure. With the variables defined above, @a eqv @b is true because @a and @b contain the same values each. On the other hand '2' eqv 2 returns False, because the left argument is a string, the right an integer and so they are not of the same type.

TODO clarify "same structure"

Numeric Comparisons

You can ask if two objects have the same numeric value with the == infix operator. If one of the objects is not numeric, Perl will do its best to make it numeric before doing the comparison. If there is no good way to convert an object to a number, the default of 0 is assumed.

The operators <, <=, >= and > can be used to compare the relative size of numbers, != returns True if the two objects differ in their numerical value.

When you use an array or list as a number, it evaluates to the number of items in that list.

String Comparisons

Just like == converts its arguments to numbers before comparing, eq as an infix operator compares for string equality, and converts its arguments to strings if necessary.

Other operators compare strings lexicographically

For example 'a' lt 'b' is true, and likewise 'a' lt 'aa'.

Three-way Comparison

The three-way comparison operators take two operands, and return Order::Increase if the left is smaller, Order::Same when both are equal, and Order::Decrease if the right operand is smallerOrder::Increase, Order::Same, and Order::Decrease are enumerations (enums) which are further explained in subtypes. For numbers that operator is spelled <=>, and for strings leg (from lesser, equal, greater). The infix cmp operator is a type sensitive three-way comparison operator, and compares numbers like <=>, string like leg, and for example pairs first by key, and then by values if the keys are identical.

A typical use case for three-way comparison is sorting. The sort method in lists can take a block or function that takes two values, compares them, and returns a value less than, equal to or, greater than 0. The sort method then orders the values according to that return value.

The default comparison is case sensitive; by comparing not the values, but their upper case variant, the example above sorts case insensitively.

Smart Matching

The various comparison operators that we have seen so far all coerce their arguments to certain types before comparing them. This is useful if you wish to be very specific about what kind of comparison you want and are unsure of the types of the things that are being compared. Perl 6 also provides another operator that allows you to perform comparisons that just Do The Right Thing. It's ~~, the smart match operator.

The smart match operator always decides what kind of comparision to do based upon the type of the value on the right hand side. In the three examples above, it would do a numeric, a string and a range comparision respectively. While we've already seen operators to do numeric and string comparisons -- == and eq -- there is no operator for comparing ranges. This is part of the power of smart matching: more complex types can define interesting and useful ways to compare themselves to other things.


Hey! The above document had some coding errors, which are explained below:

Around line 1:

Unknown directive: =head0

Around line 144:

Deleting unknown formatting code N<>

Around line 259:

Deleting unknown formatting code N<>

Around line 262:

Deleting unknown formatting code N<>

Around line 291:

=end for without matching =begin. (Stack: [empty])

Around line 297:

Deleting unknown formatting code N<>

Around line 465:

Deleting unknown formatting code N<>

Jump to Line
Something went wrong with that request. Please try again.