Channels ▼
RSS

Web Development

Use Perl 6 Now


January, 2006: Use Perl 6 Now

brian has been a Perl user since 1994. He is founder of the first Perl Users Group, NY.pm, and Perl Mongers, the Perl advocacy organization. He has been teaching Perl through Stonehenge Consulting for the past five years, and has been a featured speaker at The Perl Conference, Perl University, YAPC, COMDEX, and Builder.com. Contact brian at comdog@panix.com.


During the last Perl Whirl Geekcruise (http://www.geekcruise.com), I got to sit in on a Perl 6 talk by Allison Randal. Larry Wall was in the audience too, so often the talk would disgress, in a really interesting way, to what Perl 6 should do in a particular case. Most of the time, Allison wrote a Perl 6 script she sent through Pugs to see what it did do. That is, Perl 6 was out of the realm of theoretical and into the realm of "Let's see what happens."

Pugs (http://www.pugscode.org/) is the "Perl6 Users Golfing System" that Autrijus Tang started in early 2005 as a hobby project and later turned into a full-fledged reference implementation of Perl 6. Its been so successful that the thinkers behind Perl 6 use it to figure out what to do. The speed of development has been blistering, with both Perl and Haskell hackers getting in on the action.

Autrijus selected Haskell, a functional programming language, as the underpinnings for Pugs. He's not aiming to make it into the final Perl 6 interpreter (which will be in Perl 6 itself), but until that's available, Pugs is what we have, and its what you can play with today to write real Perl 6 programs.

So let's write some Perl 6 code. I'll need Pugs, so I need to get that. The first thing I need is the Glasgow Haskell Compiler (GHC). Debian, Gentoo, FreeBSD and probably other popular systems have a "pugs" port. On Windows, you can get the PxPerl binaries. On Mac OS X, my platform of choice, it is a bit more involved. I won't make you sit through details since "How to Install Pugs on Mac OS X 10.4 in 22 Easy Steps" (http://christian.web42.com/en/archives/000023.html) un-ironically tells you how to do just that. If you read that first, you can finish this article while everything is still compiling. In fact, if you don't have everything already installed, I suggest you start the process before you go to bed. By the time you wake up, the compilation of the various pieces should almost be done.

Now that I have everything set up, I want to run the first program I make in any langauge to test that everything runs. Just like in Perl 5, programs are just text files. I create my first Perl 6 program:

       #!env pugs

       say "Hello World";

I run that like any other program. In Perl 6, say() replaces print() with the added bonus of adding a newline for me.

       $ ./hello.p6
       Hello World

But that's not enough for me. Perl 6 is supposed to make everything an object, so I should get the same warm fuzzies that Smalltalk and Ruby give me. Let's see if I can treat a literal string as an object (which you can't do in Java, for instance, because it's not an object language). Perl 6 also replaces the arrow method call with the dot method call.

       #!env pugs

       "Hello World".say

And it works! I get the same output that I got before. Let's take it a bit further. I want to split the string into characters, join the characters with colons, and print the result. I can do that with a method chain.

       #!env pugs

       "Hello World".split('').join(':').say

I run this program like I did before and get the output that I expect. This is definitely cool.

       $ pugs hello3.p6
       H:e:l:l:o: :W:o:r:l:d

Perl 6 has some new operators, so I want to give those a try too. The string concatenation operator found itself all of a sudden without a character when the dot moved over to the object side of the house, so Perl 6 pressed into service the tilde, ~, which was feeling a bit underused.

       #!env pugs

       say "Hello" ~ " " ~ "World";

I can also write that in the more direct form.

       #!env pugs

       ("Hello" ~ " " ~ "World").say

How about some of the nifty new Perl 6 features? How do those work? I'm especially interested in the hyper-operators that can work with two lists at the same time.

       #!env pugs

       my @one = 1..5;
       my @two = 8 xx 5;

       my @sum = @one >>+<< @two;

       @sum.join( ', ' ).say;

In this program, I declare the array @one and assign it the range of 1 to 5. That's the same thing in Perl 5. I don't have to use strict because its on by default. That's why I also lexically declare the variables: pugs complains otherwise. Next, I use the new xx operator. That's like the old x operator, although it explicitly replicates lists, so pugs doesn't have to figure it out based on context. Next comes the line with @sum. On the right hand side, I use the >>+<< hyper-operator with arrays on either side of it. It takes the first thing from the first list and the the first thing from the second list and performs the operation in the middle, in this case the addition. That becomes the first element of the output. Then it does it for the second items, and so on. That's a lot easier than the equivalent Perl 5 map, and much shorter than writing a loop to do it. Once I have the sums in @sums, I join them and send that string to the output.

       $ pugs add_lists.p6
       9, 10, 11, 12, 13

Another feature I'm looking forward to are junctions. I think of these as comparison operators from a much more intelligent universe. In reality, they are from Damian Conway (see Quantum::Superpositions for the Perl 5), so its virtually from a much more intelligent universe.

       #!env pugs

       my $num  = @ARGS[0];
       my @nums = 5 .. 9;

       if( $num == any( @nums ) )
               {
               "$num is in @nums[]".say
               }
       else
               {
               "$num is not in @nums[]".say
               }

I take the first argument from the command line arguments special array, which is now @ARGS. I also keep the @ sigil even though I'm asking for a single element of the array. In Perl 6, I know I have an array when I see that @. It doesn't change depending on what I'm doing. In the if(), I compare the value in $num to the any junction. If the value in $num is in, well, any of the values I gave to any, the result is true. No matter which way the statement branches, I print (um, I say) a message. Inside the string, I have to use the empty brackets, [], to get the array to interpolate. Without anything between the brackets I get the whole array. That's kind of annoying right now, but I think I'll like that after a while once I have to start putting unescaped e-mail addresses into strings.

Along with that, Perl 6 has another nifty, ternary comparison operator. Ever since I've been programming (and that's really not all that long compared to most of you, probably, so that makes it even worse), I've wondered why I had to do two separate comparisons to discover if a value was between two others. In Perl 6 I do it all at once.

       #!env pugs

       if( 5 < @ARGS[0] < 10 )
               {
               "@ARGS[0] is between 5 and 10".say
               }
       else
               {
               "@ARGS[0] is not between 5 and 10".say
               }

I run this for a few values and it just works.

       $ pugs between.p6 4
       4 is not between 5 and 10
       $ pugs between.p6 6
       6 is between 5 and 10
       $ pugs between.p6 5
       5 is not between 5 and 10

I'll give you one more example, and then you have to go out on your own. I thought about stopping the article here, and that would have been easy, but there is at least one more operater that I'm going to like using.

Let's say that I want to give my previous program a default value if I did not give a value on the command line. Let me show you how annoying that is in Perl 5, just to remind you:

       my $num = defined $ARGV[0] ? $ARGV[0] : "default";

I have to test for definedness because 0 might be a valid value, although its a value for boolean tests. Perl 6 introduces the // operator that's a short circuit operator testing for definedness instead of truth.

       my $num = @ARGS[0] // 'default';

I use that in my last comparison program.

       #!env pugs

       my $num = @ARGS[0] // 7;

       if( 5 < $num < 10 )
               {
               "$num is between 5 and 10".say
               }
       else
               {
               "$num is not between 5 and 10".say
               }

When I give this program some arguments, it acts just like before. When I give it 0, it doesn't choose the default value, but when I don't give it an argument, it properly selects the default argument.

       $ pugs between2.p6 8
       8 is between 5 and 10
       $ pugs between2.p6 0
       0 is not between 5 and 10
       $ pugs between2.p6
       7 is between 5 and 10

That's it. You can start using Perl 6 now. You probably don't want to build a business around it or trust millions of dollars to what it might do, but you can start learning it. Pugs has most of Perl 6 implemented in some fashion, and if you find something that's not done, just wait a couple of days.

TPJ


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 
Dr. Dobb's TV