Name

Yet Another Perl 6 Operator: Repeat Operators

Version

Maintainer: Adriano Ferreira <ferreira@cpan.org>
Date: 20 Sep 2007
Last Modified: 21 Sep 2007
Number: 3
Version: 6
Status: Published

Perl 6 has two repeat operators: one for replicating a string/buffer and the other for replicating lists.

String repeat 'x' takes a string as the left argument and the number of times to replicate as the right argument.

$string x $count

my $s = 'a' x 3; # 'aaa'
my $empty = 'foo' x 0; # ''
my $n = 2; my $dots = '.' x ($n - 3); # '' because ($n-3)<1

The parentheses in the last line of code were necessary because 'x' has the same precedence as '*', which means that '.' x $n - 3 is interpreted as ( '.' x $n ) - 3 , which is probably not what we'd want.

This operator makes it easy to build strings with repeated chunks of text. For example, a 40-chars-wide row with a title followed by hyphens to fill out the row.

my $title = 'Title ';
my $row = $title ~ '-' x (40-$title.chars);
say $row;

This piece of code prints

Title ---------------------------------------

Saying that the left argument of 'x' must be a string is not the whole truth. Perl 6 evaluates this argument in string context, which means that objects with sensible stringfication will magically turn into strings and your code will just work.

class Marker { 
   has $.text;
   method Str { $.text }
}

Marker.new( text => '*' ) x 4; # '****'

The list repeat operator, 'xx', is used to replicate lists. Its left argument is evaluated in list context and it returns the result of the repetition as a new list (if used in ordinary list context).

@list xx $count

(1)     xx 2 # (1, 1)
<a b>   xx 3 # ('a', 'b', 'a', 'b', 'a', 'b')
(1,2,3) xx 0 # ()

Here's an example of how we could use this to make a rule, which in this case is nothing but a string containing the numbers 0 through 9 repeated four times.

cat(('0'..'9') xx 4) # '0123456789012...

The repeat count can also be '*' , which makes the result an infinite list. Since Perl 6 lists are lazy by default, this also just works.

my @ones = (1) xx *;

The repeat operators should be familiar to Perl 5 developers, but with a twist. In Perl 5, there was only one repeat operator 'x' for both tasks. This could lead to weird surprises like the fact that 1 x 3 and (1) x 3 are not at all the same. This change in Perl 6 was motivated by one of the Perl 6 design principles, "different things must have different syntaxes". So $any x $count is always a string and 1 xx 3 and (1) xx 3 are both lists.

$Revision: 51 $