Article sep2006.tar

Perl 6 is Coming!

Randal L. Schwartz As I write this, I've just spent a week at Yet Another Perl Conference (North America) 2006, held this year in Chicago. This is the first YAPC I've been able to attend since 2001, because the intervening conferences have been either in Canada (inconvenient to attend) or during the week of a Geekcruise (with the cruises taking priority for me).

This YAPC event started with three days of very packed tracks, along with some important keynotes by people like Larry Wall and Damian Conway. We finished up with two days of tutorials provided by Stonehenge (including your humble author) and Damian, at a substantially cut rate for some lucky 80 students.

The Perl developers also came together for a hack-a-thon overlapping the two tutorial days. Lots of progress was made in figuring out where everyone was at, where they wanted to head, and even who was doing what.

One of the things everyone asked was "where is Perl 6?" After all, it's about six years since the project was officially kicked off. Well, I'm happy to say that it's a lot further along than I remembered when I last looked, and a lot of momentum was created at YAPC (and will continue at OSCON by the time you read this).

As part of the transition to Perl 6, my business partner brian d foy created the beginnings of Learning Perl for Perl 6, which we presented together during the main session tracks. We still have a long way to go, but it was comforting to know that every example we showed runs today. Yes, today.

We tested the examples with pugs, which is described as "an implementation of Perl 6, written in Haskell. It aims to implement the full Perl 6 specification, as detailed in the Synopses." Pugs was launched in February of 2005 as a "weekend project" to see if the functional-programming parts of Perl 6 could be implemented by translating them to Haskell (a functional programming language). But once that was complete, Audrey Tang decided not to stop there: she inspired others to help her keep fleshing out even the non-functional parts as well.

Today, Pugs stands as the most complete Perl 6 implementation (although others are on the way) and as a test bed for tests and working out design details. Although Pugs may not be anything that will ship when people download "Perl 6.0" eventually, it's been an incredible aid and motivator to test various ideas at all levels of the Perl 6 project.

For details about Pugs, you can visit http://pugscode.org. Following the instructions there, you will eventually get a pugs command somewhere in your path, with which you can actually execute a substantial portion of the Perl 6 that has been specified so far. For example, after installing Pugs, I can say:

$ pugs -e 'print "Hello, world!\n";' 
Hello, world! 
            
Hey, look at that! Perl 6 is just like Perl 5! The familiar:

print "Hello, world!\n"; 
works exactly the same. However, the overhead of starting Pugs means we probably want to launch it interactively if we want to play around. To do that, we simply invoke the command:

$ pugs 
and after a splash screen and some initialization, we see:

pugs>
to which we can type:

pugs> print "Hello, world!\n"; 
Hello, world! 
Bool::True 
pugs>
Ahh, there's the message again. But notice also the "Bool::True". In Perl 6, boolean is a first-class type, and the print function is returning true, letting us know that the print was successful.

This means we don't actually need to print values... we can just type them in:

pugs> 2 + 3 
5 
pugs> 2 < 3 
Bool::True 
pugs> 2 > 3 
Bool::False 
pugs> my $x = 2; for (1..100) { $x = 2 * $x; } $x 
2535301200456458802993406410752 
    
Wait a second. Look at that last one. I typed in some rather ordinary perl5-ish code, but got a large integer back! Yes, big integers, floats, and rationals are all built into the language. How about 100 factorial:

pugs> my $f = 1; for (1..100) { $f = $f * $_ } $f 
93326215443944152681699238856266700490715968264381621468592963 \
  895217599993229915608941463976156518286253697920827223758251 \
  185210916864000000000000000000000000
Cool! But again, that's a common thing. I really just wanted to multiply a list of values. The "reduce" meta-operator can do that directly:

pugs> [*] 1..50 
30414093201713378043612608166064768844377641568960512000000000000
    
There. Take a list of 1 through 50 and multiply them together.

Everything that was possible with Perl 5 is still possible with Perl 6. However, in accordance with the Perl design rule of "make the common things easy, and the hard things possible", even more things have been moved from the "possible" to the "easy" category, such as the list reduce operator above.

However, some of the syntax has changed a bit:

pugs> my @x = ('a'..'e'); @x[2]; 
"c"
Yes, the standard syntax for accessing a single element of an array is now @arrayname[$index], instead of shifting to a dollar sigil. While this will take some time for us old Perl hackers to relearn, I think it's a good move in the long run, eliminating a common beginner mistake I've seen from over the years. Similarly, the hash access always stays as a percent sigil:

pugs> my %h = ('fred', 'flintstone', 'barney', 'rubble'); %h{'fred'}; 
"flintstone"
    
Even the qw() operator was optimized in Perl 6:

pugs> my %h = <fred flintstone barney rubble>; %h{<fred>}; 
"flintstone"
Note the angle brackets representing qw here. But that last element access appears a bit too nested for Larry's taste, so it can be optimized even further:

pugs> my %h = <fred flintstone barney rubble>; %h<fred>; 
"flintstone"
Hash slices are determined by the general shape of the index in Perl 6, so if we make that a list, we get a list back:

pugs> my %h = <fred flintstone barney rubble>; %h<fred barney>; 
("flintstone", "rubble") 
Similarly, with an array slice, we can even make a literal slice:

pugs> <a b c d e>[1..3] 
("b", "c", "d") 
We can force numeric (scalar) context using the + prefix, similar to the Perl 5 scalar operator:

pugs> +<a b c d e>[1..3] 
3
Here we see that we have three items in the resulting list. And here, we take the original 3-item sublist and return just the last item from that:

pugs> <a b c d e>[1..3][-1] 
"d"
Cool. No more parens required for literal slice. Subroutines can work like they have in Perl 5:

pugs> sub p5add { return @_[0] + @_[1] } p5add(3, 4) 
7
Or, we can define named parameters like most other modern languages:

pugs> sub p6add($x, $y) { return $x + $y } p6add(5, 6) 
11 
The foreach is still around from Perl 5, renamed to for as we saw earlier:

pugs> for (1..10) { print "$_\n" } print "\n"; 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
Bool::True 
But let's get rid of that annoying newline by introducing say, a new friend that will simplify most of my output statements:

pugs> for (1..10) { say "one is $_" } say "done"
one is 1 
one is 2 
one is 3 
one is 4 
one is 5 
one is 6 
one is 7 
one is 8 
one is 9 
one is 10 
done 
Bool::True 
    
Again, an example of the common things getting even easier.

The C-style 3-part for has become loop, with a name that's de-optimized slightly because it should be used less frequently. For example, printing the powers of 2 under 1000:

pugs> my $x; loop ($x = 1; $x < 1000; $x *= 2) { say $x } "finally $x"
1 
2 
4 
8 
16 
32 
64 
128 
256 
512 
"finally 1024"
And that's just scratching the surface, but I've run out of space.

In summary, Perl 6 is coming along nicely, with Pugs as a valuable proof-of-concept implementation and test bed, and we have a lot of hard-working dedicated people bringing it all together (although they could always use a bit more help). So, be the first in your cubicle row to download Pugs and get your feet wet with Perl 6. Until next time, enjoy!

Randal L. Schwartz is a two-decade veteran of the software industry -- skilled in software design, system administration, security, technical writing, and training. He has coauthored the "must-have" standards: Programming Perl, Learning Perl, Learning Perl for Win32 Systems, and Effective Perl Programming. He's also a frequent contributor to the Perl newsgroups, and has moderated comp.lang.perl.announce since its inception. Since 1985, Randal has owned and operated Stonehenge Consulting Services, Inc.