I started programming in Perl in about 1995, a few years before design started on Perl 6. Over the years, I've taken a look at Perl 6 from time to time, but never got hooked. Sometimes it appeared too hard to get a working system running -- assuming you could at all. Other times the language looked so foreign that I wasn't sure what the point was: if it didn't even look like Perl, then it might as well be a different language, so why not go learn a different language that was ready?

Well, that finally changed this summer. The impetus was an interview with Larry Wall wherein, with his unique style, he talked about the language (and a variety of other things) in ways that intrigued me and made me want to see what he'd created. Hearing that a real release of Perl 6 was no more than several months away, and that a working compiler could be installed with a few commands, hooked me the rest of the way.

So I installed radukobrew, ran a few commands, and fired up a perl6 interpreter. Now what? Off to look for documentation and code examples. There's quite a bit of good stuff at perl6.org. It's sparse in areas, but it's plenty to get started with and try to absorb. I miss perldoc , though; reading docs at the command line is so much faster than clicking around for them on the web.

The strange thing about Perl 6, I'm finding, is not having any idea what's the best way to do things. After 20 years of programming Perl, I've gathered a pretty complete set of idioms and practices. If you need to lookup lines in a file, for instance, we know it's faster to load them into a hash than to loop through the file each time. Complex sorts can be sped up with the Schwartzian transform. Files should be opened with the 3-argument open() and followed with "or die()" error-checking. Lots and lots of little things that make you feel like your finished program is about as clean, reliable, and fast as you can make it.

With Perl 6, I don't have any of that yet. To compare lines in a file, should I read them into a hash like Perl 5, or put them in a Set and use the cool new Set operators? I have no idea. A lot more stuff is done under the hood, like error-checking, or can be left up to the compiler to work out the details -- but is that the best way? It's unsettling, not knowing, but kind of exciting at the same time, because there's a lot to explore here. And I get the feeling that, as we develop idioms to take advantage of some of these new operators, they're going to be very powerful.

For instance, say you want to find all the matching lines in two files, in no particular order. In Perl 5, you'd do something like this:

#!/usr/bin/env perl use 5.010; use warnings; use strict; my %filea = map { $_ => 1 } do { open my $fa, '<', 'filea' or die $!; <$fa> }; my %fileb = map { $_ => 1 } do { open my $fb, '<', 'fileb' or die $!; <$fb> }; for( keys %filea ){ print if $fileb{$_}; }

After the standard shebang and use statements, the next two lines load the files into hashes as the keys. In addition to preparing a lookup hash from one file, that gets rid of duplicates in both. Then I loop through the keys of one hash and print them if they're found in the other. Now here's what I can do in Perl 6:

#!/usr/bin/env perl6 use v6; my @a := "filea".IO.lines; my @b := "fileb".IO.lines; .say for keys( @a ∩ @b );

Much cleaner, isn't it? First of all, the use strict; use warnings; are gone, because they're the default in Perl 6. I put the use v6 line in because I think my editor needs it (more on the Emacs mode for Perl 6 in another post). The first two lines read each file into an array, since I don't need them to be in hashes. The file opening and error-checking are done under-the-hood, so I don't have to write them. Then the last line does a set intersection with that cool Unicode symbol (U+2229) which returns all lines that are found in both arrays.

It's much cleaner and shows more clearly what it's doing. I suspect anyone who's studied set theory could guess what this does, even if he's never programmed a day in his life. And there's some cool stuff going on here -- or that could be going on. Because of the way Perl 6 does "lazy lists," the underlying implementation can split jobs up into different tasks that run parallel, then come back to them when it needs their results. So in this case, the filling of @a and @b could be run at the same time. It may even be that the set comparison could start looking for matches before those finish, though that seems less likely. But the point is, if you have time-consuming operations that don't depend on each other, or if functionA() will be passing a list of items to functionB(), these operations may be able to run in parallel and speed things up, without you needing to do any threading or that kind of stuff. Very cool!

On the other hand, I don't know whether that cool stuff will happen in my compiler, or whether it's likely in the compilers and platforms today. So is it really the best way to do it? What's really happening under the hood in that Set comparison? Are my arrays being converted to Sets, and does that eat up time and memory? Could it be fast on one system and dog slow on another? Could it be slow today, but the fastest way at some future date when the compilers do more parallel processing? I don't know. There's a lot to learn here.

So as I learn, I'll share my discoveries, from the perspective of a long-time Perl 5 programmer who's gotten pretty set in his Perl 5 ways, but thinks some aspects of Perl 6 are just too cool to ignore. I haven't been this excited about a new language since, well, 1995. More to come soon.