Thursday, July 5, 2007

Operating with operators

Pugs revision: r16707

Operators are fun. Using them is fun, and creating them is fun. We'll cover both in this post. It will be fairly short, but hopefully you'll find something interesting.

Note, I won't quite be covering Operator precedence. See S03 for details on that note.

Operators. Operators? Operators.

Junctions
Junctions are a nice semantic addition to Perl 6; in short, a junction is a single value that represents multiple values. You essentially operate on top of these in parallel, and they can be quite useful.

Junctions are important enough to where the purpose of the operators |, & and ^ have been delegated to them, rather than being bit-twiddling operations as you'd think at first. With junctions, there are also the special functions any, one, all that are for their list counterparts:
pugs> any(1..5)
(1 | 2 | 3 | 4 | 5)
pugs> one(1..5)
(1 ^ 2 ^ 3 ^ 4 ^ 5)
pugs> all(1..5)
(1 & 2 & 3 & 4 & 5)
pugs>
As you can see from the example, the meaning of the operators should be somewhat evident (now, at least.) How can we use them?
pugs> if 1 == any(1..10) {
....> say "works";
....> }
works
Bool::True
pugs> if 1 == all(1..10) {
....> say "works";
....> }
undef
pugs> if 1 == one(1..10) {
....> say "works";
....> }
works
Bool::True
pugs>
(Note that I am utterly terrible normally at thinking up code examples, if you guys can do any better I'll take all I can get.)


Naturally in the above example, your semantics and list you use will change, but you should get the idea that when you operate over junctions, you're operating over one aggregation of different things. An element in a junction is orthognoal to it's counterparts as order is not relevant.

Junctions are a useful addition. In general, you'll probably more directly deal with composing them from lists than directly per se, however, knowing the idea behind what every junctive operator does is good to know.

Ranges
The range operator, .. is used to denote the set of values from one point to another. From 1 to 10, a to e, etc. etc... You can use them to represent values from positive infinity to negative infinity, a to z, 1 to whatever, ex:
0..*     # 0 to +infinity
*..0 # -infinity to 0
'a'..'e' # a to e
1..10 # one to two
Hopefully, most of these semantics should be obvious even without the comments.

Feed operators
Feeds are a lot like piping. You can take the return values from a function and 'feed' them to another quite seamlessly. For example, the results from map can be fed into your own custom function:
map { $_ % 2 == 0 },(1..10) ==> functor
The distinction between the two feed operators, <== and ==> are simply in which way your data flows.

Symbolic Unary operation
In the case of many operators, when used in an unary form, impose a context on the operation in general. For example, where ~ was normally string contatenation, when used in an unary form, i.e. ~$x you are forcing a string context on your variable. This definition is somewhat strict; an unary context for an operator can do a lot of things.

What're some of the things you can do with this? There is, for example, an 'from 0 to this' operator:
pugs> my $l = 10;
pugs> map { .say },^$l
0
1
2
3
4
5
6
7
8
9
pugs>
You can also use this form to turn a list of numeric values into a list of string values:
pugs> ~1..10
("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")
pugs>
Or, you can also use the equal sign to iterate over an iterator. For example:
[altair@stormwind diveintoperl6]$ cat sayit.pl
say "enter something...";
my $l;
while $l = =$*IN {
say "you entered '"~$l~"'";
}
[altair@stormwind diveintoperl6]$ pugs sayit.pl
enter something...
hello
you entered 'hello'
hi dive into perl6 crowd!
you entered 'hi dive into perl6 crowd!'
[altair@stormwind diveintoperl6]$
A list of all these rules can be found in S03.

Meta operator[s|ing]

Hyper operators
Hyper operators are a way of taking an operator, applying it to each element of it's list, and returning the resultant list. In this sense, it's somewhat similar to map.
A hyper operator is denoted by the operator surrounded by a >> and a <<. There are variations to this however, which we'll shortly see. Here's just an example of taking two lists, adding each of their elements to the corresponding one, and returning it:
pugs> (1,2,3,4,5) >>+<< (5,4,3,2,1)
(6, 6, 6, 6, 6)
pugs>
What about an unary operator? Just use one of the symbols denoting a hyper operator, on the side which the arguments are expected:
pugs> ~<< (1..10)
("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")
pugs>
But what if the two lists are not of the same length? How would you simply increase every element in a list by one? At first it may seem as though you need some sort of 'hackery,' but Perl 6 will sufficiently upgrade it, however, you must 'point' the hyper operator towards the smaller list:
(1,2,3) >>+>> 1 # (2,3,4)
If you simply 'point' your hyper operator towards the short side, perl will take care of the rest. If you don't know which side will be smaller than the other (if at all,) simply make the hyper operators 'point outwards':
@a <<+>> @b
Reduction operators
Reduction operators are a meta operator that are used with a traditional infix operator, and they are used to 'reduce' a list of values into a single one. For example, here's a good one taken from freenode #perl6's channel title:
pugs> [~] <m oo se>
"moose"
pugs>
If you're familiar with Haskell, this is the same:
Prelude> foldr1 (++) ["m","oo","se"]
"moose"
Prelude>
Cross operators
A cross operator is acheived by putting an infix operator inbetween two X's. It uses the infix operator and generates all permutations of the two lists given to it. Ex:
<austin brian> X~X <seipp stanford>
'austinseipp','austinstanford','brianseipp','brianstanford'
It's roughly that simple (note, not yet implemented.)


Creating operators
In Perl 6 you get a lot of the fun power of creating your own operators. What can they do? Well, just about whatever you want.

Operators in Perl 6 are typically defined as multi-subroutines, as you can have different types and contexts they're used in, i.e. you may need to add support for + to work with a class you define. Fairly typical stuff.

How do we define an operator? They are defined in the form of:
multi sub x:<y> (z) { ... }
Where:
  • x is one of infix, prefix, postfix, circumfix or postcircumfix. Essentially, these are the categories your operator fits into.
  • y is your operator. The characters can be any non-whitespace characters, unicode included.
  • z is/are your operands.
Actually, the part following the semicolon in the subroutine name (that's all operators are, special subroutines) can essentially be any form of a hash subscript, i.e. you could do <+> or {'+'}, etc. etc..

Unary operators can be defined either as prefix or postfix, with one operand (naturally.) Binary operators are defined as infix, and bracketing operators (for example, in HTML, the two parts of a comment: <!-- and -->) are defined with circumfix. postcircumfix is used where a postfix is expected.

This is best explained with a couple of good examples. For example, here's the reverse form of the xx operator:
pugs> multi sub infix:<~||~> (Int $n, Str $s) {
....> return $s xx $n;
....> };
pugs> 5 ~||~ "hi"
("hi", "hi", "hi", "hi", "hi")
pugs>
What about a unary operator, that, say, uppercases the string that is prefixed to it?
pugs> multi sub postfix: (Str $s) {
....> $s.uc;
....> };
pugs> "arg"!!!
"ARG"
pugs>
How about a 'plus or minus' operator?
pugs> multi sub prefix:<+/-> (Int $n) {
....> return +$n|-$n;
....> };
pugs> +/-5
(-5 | 5)
pugs>
We could even define our own comment operator:
multi sub circumfix:{'~#','#'} ($s) { return ""; }
~# how incredibly fun it is to conceive operators #
say "hello world";
(Note, the [post]circumfix category for operators doesn't work yet (r16707), but hopefully it should soon.)


Conclusion
This was a short post but a fun one. In previous languages, operators seemed quite boring and trivial, but hopefully Perl 6's new features will show you how to have fun with such a simple primitive. :)

Monday, June 25, 2007

Perl 6: Round 4

Pugs revision: r16657

(To start off: I'm sorry about this taking so long in advance, life caught up.)

I'm pretty sure we're at the act you've probably been waiting to see: Rules and Grammars.

What you may know as perl 5 regular expressions, you now need to know as Perl 6 rules. The change in jargon is not substantial with regards to rules themselves: the new name was simply chosen because 'perl [5] regular expressions' were nowhere near the formal definition of a regular expression.

Grammar's are a new addition. They're basically just "Classes for Rules" (a grammar inherits from the base class Rule) and simply act as a namespace to organize your rules [in general.]

Rules can be tricky. There're a lot of pit falls and whatnot that you can fall into. It's therefore important that you be patient with them; you can build a lot of really useful things with primitive rules, but things have changed. As we go on, I'll try to address these things. For everything else, you will probably want to refer here, here, and here as well.

Important: It's good to note a lot of the things I'll describe here are *not* fully implemented (or even partially implemented) in the way they should be as according to the synopsis' and apocalypses, etc.. This is merely an introduction; full implementation of the rule engine is a milestone for Pugs, however, it is currently not yet completed.
If I show anything that does work (as far as I know,) it'll be in the pugs prompt.

Ready, set, begin.


Rules
As I said earlier, Rules are simply regular expressions in Perl 6. They merit their own keyword, rule and can be used one of several ways (when using rules, you are given back an object in the case of construction of them and their usage.)

The first and simplest way to use a Rule is matching. Matching is simple enough; match a string against a rule and give me the result. Matching is done in the form of:
if($str ~~ m/.../)
(Note: ~~ is the 'smart match operator.' It is analogous to perl 5's =~. See S03 for more.)


Rules in the form of m/.../ immediately match. You can also use the substitution form, s/.../.../ which also immediately matches (and, yes, substitutes.) Finally, using the simple /.../ form will immediately match given that context (i.e. used with the smart match operator. This form can also define a deferred match.)
Here're a few examples of using these forms, up to this point:
pugs> my $str = "hello";
pugs> if $str ~~ m/hello/ {
....> say "affirmative";
....> } else {
....> say "incorrect";
....> }
affirmative
Bool::True
pugs> if $str ~~ s/ll/l/ {
....> say "substitution worked";
....> } else {
....> say "substitution failed";
....> }
substitution worked
Bool::True
pugs> $str
"helo"
pugs>
You may want your rules to be a little more flexible than that, however, by using deferred matches. Using the form rx// you can define a deferred match that can be stuck in a variable, ex:
pugs> my $r = rx/^abcd$/;
The same could be expressed without the rx prefix (in relation to what I said earlier about /.../ and context.)
Without the rx prefix and defining a rule in this manner, you can also prefix the rule with any unary operator (S03) to force that rule to immediately match in a context it wouldn't normally (it will match in with $_.) For example:
my $one = ?/\d*/;                       # boolean context
my $two = ~/^(fun|unfun).*/; # string context
my $three = +/(\d|\s)*/; # numeric context
Another way to define a rule is using the rule block. A rule block can have a name follow it, or it can be anonymous and simply stuck inside a variable like a deferred match. For example:
pugs> rule x { \d+ };
pugs> my $y = rule { (one|two) };
After defining a named/anonymous rule (via any of the methods described above) or a deferred match (without an unary operator prefixing it), you can match them following these examples:
pugs> rule x { \d* };
pugs> my $y = rule { (one|two) };
pugs> my $z = rx/^success: (.*)/;

pugs> 434 ~~ /<x>/ # matches
pugs> "one" ~~ $y # matches
pugs> "success: asdf" ~~ $z # matches

Grammars
Grammars are simply classes for rules. Their declaration is analogous to that of a class; if the grammar keyword is followed by a block:
grammar Dog { ... }
The namespace of the grammar is confined to that block. If that block is absent:
grammar Dog;
It continues until the end of the source file.


The main difference in calling a rule that's defined within a grammar is that you simply have to give the fully qualified name, ex:
grammar Dog {
rule bark { ^ < bark woof ruff > $ }
}

"woof" ~~ /<Dog.bark>/; # True
Like classes, rules can do things like inherit and the like.


Important Detail #1:
I'm going to at this point take some time to tell you something important that is, well, very important: interpolation doesn't exist.

I'll give you a moment to let it sink in.

Whereas in perl 5 you could freely embed scalars and the like into your regexes, you cannot do this any longer in a rule. Rather, they are passed raw to the rule engine, which decides how to deal with them from there. This is because, now, regexes are not strings; they're programs. Wall described this in A05. To quote him:

"The problem with \Q$string\E arises because of the fundamental mistake of using interpolation to build regexes instead of letting the regex control how it treats the variables it references. Regexes aren't strings, they're programs. Or, rather, they're strings only in the sense that any piece of program is a string."

In this fashion, the common misconception is to think of your rule as a string, and therefore letting interpolation come as naturally as it would with any other string. Rather, let the rule engine figure out how to deal with your variables. Now, you will use the general syntax of an assertion with your variable to help the engine determine how things should be treated.

I figure I'd take this time to point something like this out, as it's pretty important. If you really really really need interpolation that badly, you can use the P5 rule modifier to acheive it (see below.)
Continuing...

Special characters & Co.
In perl 6 rules, like perl 5 regexes, you have a lot of special characters you can use inside your rules for specific purposes. Here I am merely going to list some of them and provide examples, this isn't a definitive reference to them.

Metacharacters
The general metacharacters you can have inside a rule itself are as follows:
.         Match any single character, including a newline.
^
Match the beginning of a string.
$
Match the end of a string.
^^
Match the beginning of a line.
$$
Match the end of a line.
|
Match alternate patterns (OR).
&
Match multiple patterns (AND).
\
Escape a metacharacter to get a literal character, or escape a literal character to get a metacharacter.
#
Mark a comment (to the end of the line).
:=
Bind the result of a match to a hypothetical variable.
( . . . ) Group patterns and capture the result.
[ . . . ] Group patterns without capturing.
{ . . . } Execute a closure (Perl 6 code) within a rule.
< . . . > Match an assertion.

These are mostly new, however, interpretation of their meaning should not be hard if you've used Perl 5 regular expressions before. Explanation of these are not really needed, just play around with them (we'll cover more on assertions in a moment, however)


Escape sequences
There are also plenty of escape sequences you can use inside a rule to specify things such as whitespace or group an entire word together. Here's a quick list:
\0[ . . . ]     Match a character given in octal (brackets optional).
\b Match a word boundary.
\B Match when not on a word boundary.
\c[ . . . ] Match a named character or control character.
\C[ . . . ] Match any character except the bracketed named or control character.
\d Match a digit.
\D Match a nondigit.
\e
Match an escape character.
\E
Match anything but an escape character.
\f
Match the form feed character.
\F
Match anything but a form feed.
\n
Match a (logical) newline.
\N
Match anything but a (logical) newline.
\h
Match horizontal whitespace.
\H
Match anything but horizontal whitespace.
\L[ . . . ]
Everything within the brackets is lowercase.
\Q[ . . . ] All metacharacters within the brackets match as literal characters.
\r Match a return.
\R Match anything but a return.
\s
Match any whitespace character.
\S
Match anything but whitespace.
\t
Match a tab.
\T
Match anything but a tab.
\U[ . . . ]
Everything within the brackets is uppercase.
\v
Match vertical whitespace.
\V
Match anything but vertical whitespace.
\w
Match a word character (Unicode alphanumeric plus "_").
\W
Match anything but a word character.
\x[ . . . ]
Match a character given in hexadecimal (brackets optional).
\X[ . . . ] Match anything but the character given in hexadecimal (brackets optional).
Most of these should be fairly self explanatory.

"Extensible metasyntax"
From S05: "Both < and > are metacharacters, and are usually (but not always) used in matched pairs. (Some combinations of metacharacters function as standalone tokens, and these may include angles. These are described below.) Most assertions are considered declarative; procedural assertions will be marked as exceptions."

In general, the first leading character after the angle bracket determines the an assertion's semantics. Here're a few of them:

  • If there is whitespace after the opening bracket, and whitespace before the ending one, the the characters inside are treated 'quote style' and used in a non-capturing group. Ex:

    rx/< hello there how are you >/
    Is equivilant to:
    rx/[hello|there|how|are|you]/

  • A leading ? makes the assertion will cause no capture, given that it matches.
  • A leading $ causes an indirect subrule to be invoked. I'm pretty sure you've seen this before.
  • A leading :: causes an indirect subrule to be invoked, yet symbolically. What this means is you use this syntax:
    <::$var>
    And the contents of $var will be taken out, and what's inside will be treated as a rule name. If you've ever done php, this is analogous to the double dollar sign convention, ex:
    rule z { (\d+) };
    my $name = "z";

    "123" ~~ /<z>/;
    # above is the same as:
    "123" ~~ /<::$name>/;
  • A leading @ makes things act 'array-like.' This:
    "..." ~~ /<@arr>/;

    Is semantically the same as:
    "..." ~~ /[@arr[0] | @arr[1] | @arr[2] | ... ]/;


    However, rather than matching as literal, each element of the array will be treated as a subrule. This can be pretty useful, as you can match your text against an array of different rules.
  • A leading { (also followed by a closing } right before the ending angle bracket) basically allows you to define an in situ closure that is expected to return a rule, which at that point is matched.
  • A leading & treats a subroutine as if it will return a rule. This:
    <&foo()>

    Is the same as:
    <{ foo() }>

    It's pretty much just a shorthand.
  • A leading [ (like the curly bracket, also ending with a ]) indiciates a character class. This class can be negated by instead prefixing your opening bracket with a -. Examples:

    pugs> "a" ~~ /<[a..z]>/  # true
    pugs> "a" ~~ /<-[a..z]>/ # false
    pugs> "1" ~~ /<-[a..z]>/ # true


    There is additional flexibility in that you may 'add' and 'subtract' character classes. For example, to check that a string has no vowels:
    $str ~~ /<[a..z] - [aeiou]>/

  • Leading ! indicates negation (naturally.)

Rule modifiers

Aside from the above, you still have your handy dandy rule modifiers. Their usage is essentially the same, but now they are passed at the front of the rule rather than at the end as it both makes life easier for you and the parser. Here're a few of the modifiers you can use:
:i      Ignore case
:g Match as many times as possible
:s Treat whitespace as 'significant,' i.e. it must occur verbatim
:P5 Use Perl 5's regular expression syntax, rather than Perl 6.
:Nx Works like :g, however, the N specifies exactly how many times it
must match. The general form is :x(N)
:Nth Find the Nth occurance. Useful for substitutions, i.e.
s:5th/lbrary/library/ if you said something wrong in your
sentence. The general form is :nth(N)

In the case of just declaring a deferred rule (rx/.../) or a match (m/.../) these modifiers are placed after the rx/m token and delimited by a colon, i.e. rx:i/.../, m:g/.../, et cetera et cetera. There are plenty more, however, I'm leaving them out as I assume if you need them, you'll find them (sue me.)


Built-in rules
Aside from your rules, there're naturally plenty of built in ones you can use. Here are a few:
<alpha>       Match a Unicode alphabetic character.
<digit> Match a Unicode digit.
<sp> Match a single-space character (the same as \s).
<ws> Match any whitespace (the same as \s+).
<null> Match the null string.
<prior> Match the same thing as the previous match.
Like other rules, you can change their meanings with assertion semantics.


Hypothetical variables
Hypothetical variables are a new feature of Perl 6 rules. In a perl 6 rule, a hypothetical variable allows you to bind a variable within a rule. If your match fails, your hypothetical variables are automatically unbound from what they were (in the case that your match failed after the fact.) However, the variable must be in lexical scope before you may bind to it via a the := operator. This is less complicated than it sounds, here's the example:
my $z;
"I am a person" ~~ m/^$z := (\w+)/;
$z.say; # should print "I"
Fairly simple.


Conclusion
This has been a nice post. Hopefully, your rule-fu has increased. The changes may need a little time to get used to, however, in time all should be good. :) Like I said, a -lot- of this is not implemented, and I have not even breathed upon the technical surface of rules; I'm not exactly the definitive reference on them anyway. This should give you a taste, however.

Perhaps an unofficial 'Round 4b' is in order. We'll see...
Until next time...


Next round: ??
(that means I'm open to recommendations. If none arise, macros seem like a good topic)

Friday, June 8, 2007

Perl 6: Round 3

Pugs revision: r16643

In [our] journey since the last two posts, we've covered a bit of introductory Perl 6 ranging from a scalar to currying functions and other tom foolery. Here, we'll discuss a big part of Perl 6: Object oriented programming.

Anybody who comes from a Perl 5 background probably knew that Object-orientation wasn't exactly first class; I don't even know if you'd define it as 'coach.' Perl 6 now extends this to full object-orientation. -Real- object-orientation, if you wish to think of it in that manner.
That means this will most likely be long ride. So, we should probably get on soon as possible.

Classes
Class declaration comes in two forms:
class Foo;               #rest of file is class definition

class Bar { ... }; #block is class definition
The first can only be used as the first declaration [statement] in the file or string (in the case of eval.)

Attributes
Attributes are known in other cultures as instance variables of a class. They are declared with the has keyword, and declared public with a "." sigil following the primary sigil (see below); this generates accessor methods in the class of the same name. Private attributes that indicate no accessor method are declared with the secondary "!" sigil. Ex:
pugs> class Dog {
....> has $.name is rw = 'bruce';
....> has $.age is rw = 6;
....> has @.legs is rw;
....> has $!brain;
....> }
undef
pugs> my $d = Dog.new();
pugs> $d.name
"bruce"
pugs> $d.age()
6
pugs> $d.age = 7
7
pugs> $d.brain()
*** No such method in class Dog: "&brain"
at line 1, column 1-11
pugs>

Methods
Methods are a lot like subroutines, but with their own keyword method. The obvious difference is they're invoked on objects. In Perl 6, many of the primitive types are objects like Int and String. That is how we invoked methods such as .say(); Ex:
pugs> class Bar {
....> has $.name is rw = 'jack';
....>
....> method h {
....> say "hello world";
....> }
....> method myname {
....> say "my name is "~$.name;
....> }
....> }
pugs> my $me = Bar.new;
pugs> $me.name = 'austin';
pugs> $me.myname;
my name is austin
pugs> $me.h();
hello world
pugs> h($me:);
hello world
The last way is an indirect object call. It acts like a subroutine, with the object seperated from the parameters. The parameters are comma seperated after the colon, i.e.: doit($object: 1,"world");
And of course, the parenthesis are optional.

Inheritance

Classes can inherit from one another using the is keyword. That is, the act of saying a class inherits from another is just a class trait. Ex:
class Hello is World { ... }
class Cool is Awesome is Fun { ... } #multiple inheritence
You can access inherited attributes just like normal:
pugs> class Foo {
....> has $.name = 'jack';
....> }
....>
....> class Bar is Foo {
....> method z {
....> say $.name;
....> }
....> }
pugs> my $x = Bar.new()
pugs> $x.z
jack
Bool::True
pugs>
Roles
A role is a reusable unit of class code. In the way that modules export subroutines and the like for other modules and your code, a role exports methods and attributes into a class. This is like inheritence; inheritence is just a different way to reuse code.

A role define's both attributes and methods, i.e.
pugs> role Hi {
....> has $!status;
....> has $.world = 'earth';
....> method initstatus($s) {
....> $!status = $s;
....> }
....> method printstatus {
....> say $!status;
....> }
....> }
pugs>
They can be pulled into a class as such:
pugs> class Foobar does Hi { ... }
When you use roles with a class, they are treated almost as if you had simply typed in that code right there. With inheritence you only have accessor methods to access your attributes; with role's they can be referenced by their $.name (this applies to private attributes as well.) Ex:
pugs> class Foobar does Hi {
....> has $.name = 'austin';
....> method sayname {
....> say $.name;
....> }
....> }
We pull in the other methods through the role. Continuing:
pugs> my $x = Foobar.new();
pugs> $x.name
"austin"
pugs> $x.world
"earth"
pugs> $x.initstatus("super");
pugs> $x.printstatus;
super
pugs>
Using Roles, it is as if we wrote the code in Hi directly in the declaration of class Foobar. This is reusable, and it can be used to give methods to classes that need similar functionality, but without an inheritence relationship.

An interface is a role that only defines method stubs, and no attributes.

Role Conflicts
Given one class defined over two roles, each with a method of the same name, which method should the class take when it's invoked? Either. In Perl 6, you simply choose one, and you can do it by giving a full name of the method you want to call (the format is Role::method) given the roles your class uses.

Delegation
Delegation lets you act like another object's methods are your own methods. You use the handles keyword to specify what methods will act on what attributes rather than on the object itself. It sounds confusing, but it's easy in practice and gives you some nice reusable code. Ex:
pugs> class backend1 {
....> method hello { say "hi" }
....> }
pugs> class backend2 {
....> method hello { say "hello" }
....> }
pugs> class Foo is backend1 is backend2 {
....> has $.backend handles "hello";
....> }
undef
pugs> my $f = Foo.new();
pugs> $f.backend = backend1.new();
pugs> $f.hello;
hi
pugs>
As you see, if you use the handles keyword with an attribute, by setting that attribute to an object you can delegate methods to that object rather than yours.

Scope (private/public)
In a class, methods are implicitly public. You can make them private simply by appending my to the method keyword.

There is a loophole in private scope like this however; a class can declare it trusts another class to access it's private methods:
pugs> class Bug {
....> trusts Zapper; # probably a bad idea
....> }
Subroutines
Subroutines can be defined in classes just like methods. They cannot be accessed via $object.methodname invocation, and cannot be inherited although you can pull them in by roles.

Submethods
"Submethods are for declaring infrastructural methods that shouldn't be inherited by subclasses, such as initializers." (S12) Ex:
pugs> class A {
....> method foo { say "foo" }
....> }
pugs> class B is A {
....> submethod foo { say "foobar" }
....> }
pugs> class C is B is A { ... }
pugs> my $b = B.new;
pugs> my $c = C.new;
pugs> $b.foo;
foobar
pugs> $c.foo;
foo
pugs>

We can do this thanks to the joys of multiple inheritance via multiple is traits.

Multiple dispatches and Operator overloading
In the last article we discussed multi subroutines that applied to having two subroutines of the same name, with different signatures. multi applies to any code object like a sub, method or submethod. Ex:
pugs> class Foo {
....> multi method hello(Int $i) { say "int:\t"~$i }
....> multi method hello(Str $s) { say "str:\t"~$s }
....> }
pugs> my $f = Foo.new();
pugs> $f.hello(1);
int: 1
pugs> $f.hello("austin");
str: austin
pugs>
Operator overloading make use of multiple dispatch. Operators are just subs with a special syntax that describes how they are used in an expression. You can define an operator as prefix, postfix (unary), or infix (binary.)

Operators are defined with subs in the form of multi sub how:exp.
how is that of the above (prefix postfix and infix), while exp defines the operator to overload, using any method to treat it as a hash subscript, i.e. you could use <+>, <<+>>, {'+'}, etc..
Ex:
pugs> class Foo {
....> has $.age = 10;
....> }
undef
pugs> multi sub *infix:<+> (Foo $a, Foo $b) { $a.getage + $b.getage }
pugs> my $a = Foo.new;
pugs> my $b = Foo.new;
pugs> $a + $b
20
pugs>
The * at the start of the multi-sub definition indicates that it is in global scope; without this, the operation of addition is lexically scoped to the area at which it was defined. Generally, you'll probably want to use *, though. As of pugs r16643, operator overloading in this fashion does not seem to work yet.

Conclusion
This time we looked at a very big part of Perl 6. Just by using simple features like Roles and Delegations in Perl 6, you can achieve some very powerful constructs. You also get all the classic object-oriented features you'd expect from other languages.
Have fun. :)

Next round: Grammars + Rules.

Wednesday, May 30, 2007

Interlude: Functional Programming with a side of Perl 6

This article is a quick tangent away from the Rounds series; an attempt to investigate Functional Programming with Perl 6. There're a lot of new things to look at, so this post will act more as an investigation rather than a lesson.

Note this article is an interlude; things here may (or probably not) have been covered in the previous articles I've posted, up to this point. So if you don't necessarily understand what's going on here, it's fine. You may just have to wait a while before my explanatory post comes out (but then again, you could help yourself.) Anything I've posted here will most likely (hopefully) be explained at some later point, when it need be (for example, we may do things with subs I didn't cover; but remember, I didn't promise to cover all the details.)

Let's begin.

(Also note this now: I'm coming from a Haskell background, so code examples may be posted in Haskell to explain a point.)


Higher Order Functions
Higher order functions are functions that take other functions as arguments, basically. An example of this is the map function. map would have the following type (Haskell):
Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude>
Example of usage could be like this:
Prelude> map even [1..10]
[False,True,False,True,False,True,False,True,False,True]
Prelude>

As you can see, this would return a list of Bool's saying which are even and which are not; if you actually wanted the values, you'd have to use the filter function (filter is similar to map, except it returns a new list based on the old one, filtered by a predicate,) ex:
Prelude> filter even [1..10]
[2,4,6,8,10]
Prelude>

So, as an exercise, let's implement these functions.

In Perl 6, subs can be passed Closure parameters. This means you can treat said parameters as lexically scoped subs. These closure parameters are prefixed with the & sigil. For example:
[altair@stormwind diveintoperl6]$ cat > higher-order.p6
#!/usr/bin/env pugs
use v6;

sub hiordr(&b,$v) {
b $v;
}

hiordr({ say $_; },"asdf");
[altair@stormwind diveintoperl6]$ pugs higher-order.p6
asdf
[altair@stormwind diveintoperl6]$
It's worth noting that, you could rewrite the above call to hiordr as simply hiorder(&say,"asdf");
Obviously though, if you need to do something other than just use one function (such as use a user-defined predicate like we'll see below in filter2's example) or you don't want to define a sub to use, an anonymous block will probably suffice.

So our implementation should, therefore, be reasonably sane given what we know now:

[altair@stormwind diveintoperl6]$ cat map-filter.p6
#!/usr/bin/env pugs
use v6;

sub map2(&b,@l) {
my @r = <>;
for @l -> $v {
@r.push(b $v);
}
return @r;
}

sub filter2(&p,@l) {
my @r = <>;
for @l -> $v {
my $x = p $v;
@r.push($v) if $x;
}
return @r;
}

say map2({ .uc; },<a b c d>).join(' ');
say filter2({ $_ % 2 == 0; },1..10).join(' ');
[altair@stormwind diveintoperl6]$ pugs map-filter.p6
A B C D
2 4 6 8 10
[altair@stormwind diveintoperl6]$

As you can see, not too difficult to implement at all. You now have the power of Higher-order functions: give them a shot every once in a while.

Lists and pattern matching
In Perl 6, lists are just like they are in a language like Haskell (or, well, any language pretty much.) They're even lazy (although don't try my @a = 1...; just yet; the infinite generators in Pugs are not yet implemented.)

In Perl 6, thanks to some of the new semantics, it's a bit easier to express some more functional-style expressions. Thanks to multi subroutines, it's also possible to pattern match your functions so you don't get errs when calling a function with a list that may break down over the course of the computation (in haskell: you get an exhaustive pattern match.)

For example, here is a basic definition of reverse in Haskell, followed by the same definition in Perl 6:

haskell:
rev [] = []
rev (x:xs) = rev xs ++ [x]

perl 6:
multi sub rev () { () }
multi sub rev($x,*@xs) { (rev(|@xs),$x) }


Now, given, the haskell function may be a bit more flexible, for example, you could not use the perl 6 version and do "rev('asdf');' while you could in the haskell version; this is due to the fact that in haskell, data String = [Char], while in Perl 6, a String is it's own type. This could be accomplished however, doing:

my @a = "asdf".split('');
rev(|@a);

This is besides the point, however.

Somewhat tangential: Monads
A lot of people wonder exactly what a monad is (you may not grok this if you're not from a Haskell background.) The word is intriguing and the idea powerful, yet there seems to be a loss of words to describe exactly what they are or do.
Monad's are basically a computation environment. To add onto that, they're a computation environment in which you get to make up the rules of evaluation order. This abstraction is what makes Monad's so delicious; it is easy to abstract away things like boilerplate between your expressions. For more info, you may wish to check out this topic.

Another plus is that a monad is really just a library. This makes them language-agnostic (although Haskell is obviously the leading-man in the area of Monad usage.) There are monads for all sorts of languages (which is why this is 'somewhat tangential': it's not directly related to functional programming per se, but I'm deciding to cover it anyway just due to the principle and idea. Feel free to skip if you like.)

Here we'll just be trying to reduce a Haskell Monad to a Perl 6 Monad. We will use a fairly contrived Monad for the purpose of the explanation. This monad is known as 'Click.' Click is a pretty simple Monad -- actually, it's pretty much identical to Maybe; both in type and usage (the main difference is we aren't handling fail.) Click simply returns either a Silence or a Clicked a where a is essentially any arbitrary type. Using this Monad you can basically have expressions which are 'Silent' or they 'Click.' Let's look at the definition of this Monad:

data Click a = Clicked a | Silence
deriving Show

instance Monad Click where
return = Clicked
Silence >>= _ = Silence
Clicked a >>= f = f a
Easy enough. Here's a function and a few tests to show how exactly this monad works:

noise :: (Num a) => a -> Click a
noise 0 = Silence
noise x = Clicked x

t1 = do
a <- noise 10
b <- noise 5
return (a + b)

t2 = do
a <- noise 10
b <- noise 0
return (a + b)

t3 = do
a <- noise 10
b <- noise 0
c <- noise 5
return (a + c)
Running these:
[altair@stormwind monads]$ ghci

Prelude> :l Click.hs
[1 of 1] Compiling Click ( Click.hs, interpreted )
Ok, modules loaded: Click.
*Click> t1
Clicked 15
*Click> t2
Silence
*Click> t3
Silence
*Click>


Well, it works pretty easily! Thanks to the do notation, our expressions are de-sugared and fed to each other via the bind operator (>>=) automatically; this is why even when you get a Silence in an expression like b <- noise 0 which seems just like a pattern match, your whole expression is Silent: every 'sequential action' is de-sugared down to >>= in essence. That would be why t2 and t3 would be Silent themselves, as given by our Monad instance.

Let's see if we can define a reasonable goal as to what our end result should look like in Perl. Since this is essentially just a 'conversion,' we may need to translate a few notations. This is (hopefully) what our end result with our Monad code in Perl 6 should look like:


my $t1 = monaddo ({ my $a = noise 10; },
{ my $b = noise 5; },
{ return $a + $b; });



I realize, this doesn't look too pretty; but I guess that's just a bi-product. However, looking at it reveals that the do-notation is reletively sound; we're just evaluating a list of expression's and doing a little more under the scenes. Here's a first version of our monaddo notation:
pugs> sub monaddo(&b,*@a) {
....> my $x = b();
....> $x = $_($x) for @a;
....> }
pugs>

And an example of the usage:
pugs> monaddo({ 1; },{ .say; });
1
pugs>

Woo! it works fine. Actually, we can effectively 'axe' the semicolons, since all our expressions in our monadic notation are treated as just blocks.
Quickly into our celebration though, we find things like this do not work:
pugs> monaddo({ my $a = 1 },{my $b = 2 },{ .say});

This is due to the fact that monaddo expects every block in the list of blocks to accept one parameter (excluding the first.) Also, if a variable is declared in one block, it is lexically seperated from the previous block, so sharing data can only be done via the 'inbetween pass.'

Regardless if you may hate me, right now, I think this is enough for this post, and at this point I believe this 'monads-in-perl6' topic is worth it's own post entirely. :)
So we'll stop here (boo hoo,) as I am a very, very fickle person (actually, I need more time to collect my thoughts on this topic; I don't wish to make post this 'all about monads' either, so you'll have to excuse me there.) We'll continue in this venture a little later on; maybe after my initial Rounds series is done, or maybe in 3 years.


(The premature) Conclusion
This was just an investigation post, mainly. With Perl 6 a lot of things are going to be much more expressive, much more easily. The influence of functional programming on my brain seems to have that effect, I've found; might as well apply it to what I'm going to use.
That's what programming is about, isn't it?

Friday, May 25, 2007

Perl 6: Round 2

Pugs revision: r16525

In the last article, I discussed some of the basic tenets of Perl 6. Continuing from here, we will go onto using subroutines and other dilly dallying.

Subroutines have taken a few good changes in Perl 6. There are also things that have been left alone, as we shall see. Let's go ahead and start:

[altair@stormwind diveintoperl6]$ pugs

pugs> sub abcd {
....> True;
....> }
pugs> if (abcd() == True) { say 'yes!'; }
yes!
Bool::True
pugs>

Too trivial, but an example nonetheless (well, it at least shows that the last expression evaluated in a sub is the return by default; but I hope you caught that.)

Before going on, I'll take this time to point out a couple of different ways you can define subroutines. The first and most apparent, is a named subroutine:

pugs> sub cool ($a,$b,$c) {
....> $a ~ $b ~ $c;
....> }
pugs> (cool "ab","cd","ef").say;
abcdef
pugs>

You may also specify the return type in the parameter (remember the type system?) The above could also have been started with:

sub cool ($a,$b,$c --> String)

It's worth noting if you do not define parameters with the read-write trait explicitly (is rw attached to the particular parameter), they will be readonly aliases, i.e. immutable in the context of your sub. Also, if your sub declaration says it takes no parameters, but ones are passed anyway, they are passed in @_:
pugs> sub a {
....> @_.join(' ');
....> }
pugs> a("hi","there","guy")
"hi there guy"
pugs>
You may also define sub's anonymously, by simply saying 'sub' without a name:
pugs> sub {
....> say "hi";
....> }
pugs> my $tea = sub ($a,$b) { $a ~ $b; }
pugs> $tea("a","b")
"ab"
pugs>

The third way is to use 'pointy-blocks.' These are almost synonymous with an anonymous sub declaration, but you can't have traits, and you don't need parenthesis for a parameter list:

pugs> my $s = -> $v { $v**2; }
pugs> $s(10)
100/1
pugs> my $t = -> $d,$e,$f { $f ~ $e ~ $d; }
pugs> $t('x','y','z')
"zyx"
pugs>

Now that that is out of the way, let's continue (tip: the ~ operator is Perl 6's concatenation operator. Yes, that's really it.)

Parameters
Perl 6 subroutines can, of course, take parameters. The way they take them ideally is pretty similar to that of perl 5, i.e.:
pugs> sub a($a,$b) {
....> ($a,$b).join(' ').say;
....> }
pugs> a("asdf","aoeu");
asdf aoeu
pugs> sub b {
....> @_.join(' ').say;
....> }
pugs> b("a","b","c","d");
a b c d
pugs>

And so on and so on. Now, let's continue with some more interesting parts of parameters in Perl 6.

Optional parameters
Generally you will pass your arguments in order to the function; after these ordered, required arguments you may specify several other types of parameters, optional parameters are one of these. Optional parameters simply appear after all required arguments and are post-fixed with the ? symbol. Example:

pugs> sub opt($a,$b,$c?,$d?) {
....> say "a & b are:\t"~ ($a,$b).join(' ');
....> say "c & d are:\t"~ ($c,$d).join(' ');
....> }
pugs> opt("my","name","is","austin");
a & b are: my name
c & d are: is austin
pugs> opt("my","name","is");
a & b are: my name
c & d are: is
pugs> opt("my","name");
a & b are: my name
c & d are:
pugs> opt("my");
*** No compatible multi variant found: "&opt"
at line 1, column 1-10
pugs>

You may also give these optional parameters default values, such as:

pugs> sub opt2($a,$b? = "seipp") {
....> ($a,$b).join(' ');
....> }
pugs> opt2("austin","seipp").say;
austin seipp
pugs> opt2("austin").say;
austin seipp
pugs>


Named Parameters
You can also explicitly associate your parameters with a name, by prefixing it with :. This forces the parameter you mark in question to be passed with a name, rather than being passed by position. Example:
pugs> sub named($a,:$b) {
....> say $a;
....> say $b;
....> }
pugs> named "a", b => "str";
a
str
pugs> named b => "str","a";
a
str
pugs>
Named parameters are always optional, and they must come after optional parameters marked with ?.
Note: you may also do a key-value pair in the form of :key(value); such as:

pugs> named :b('str'),"a";
a
str
pugs>
This option syntax is purely for pleasure, of course.

Variadic Parameters
A variadic parameter in a subroutine declaration allows the sub to take [extra] arguments and roll them up into an array. Using variadic parameters, this Perl 6 subroutine stub:

sub test(Int $a,Int $b,*@rest) { ... }

And this C prototype:

int test(int a, int b, ...);


Are the same semantically; the extra parameters are rolled into @rest in this case. Example:

pugs> sub test($a,$b,*@rest) {
....> say "a & b:\t" ~ ($a,$b).join(' ');
....> say "rest:\t" ~ @rest.join(' ');
....> }
pugs> test("austin","brian","chris","david");
a & b: austin brian
rest: chris david
pugs> test("austin","brian","chris");
a & b: austin brian
rest: chris
pugs> test("austin","brian");
a & b: austin brian
rest:
pugs>

On the note of variadic parameters, you can also do the inverse by flattening an array and passing it to a function, element for parameter, ex:

pugs> sub test($a,$b) { $a ~ " " ~ $b; }
pugs> my @a = <cool refrigerator>;
pugs> test(|@a).say;
cool refrigerator
pugs>

Multi-subs and signatures
In Perl 6, the parameters an argument accepts defines what is called the subroutine signature. Signature's are your function differentiator when you call a sub that is defined twice, over two different sets of parameters. This difference is based on the type annotations you provide in the signature. Multi-subs allow you to basically overload functions in the classic sense; you use the multi keyword on a sub to state it will be defined more than once with different signatures, and when you call it, the appropriate sub will be called based on signatures.

That's a lot of talk, here's an example of what I mean:

pugs> multi multiples (Int $i) {
....> say "int:\t"~$i;
....> }
pugs> multi multiples (String $s) {
....> say "str:\t"~$s;
....> }
pugs> my Int $a = 1;
pugs> my String $b = "asdf";
pugs> multiples($a);
int: 1
pugs> multiples($b);
str: asdf
pugs> multiples(1);
int: 1
pugs> multiples("asdf");
str: asdf
pugs>
Currying
Currying a function allows you to take a function with multiple parameters and reduce it to a function with one parameter (essentially.) This allows you to curry multi-argument subs and use them in operations like map, where the function is expected to take one argument. Example:

pugs> sub curryer($one,$two) {
....> $one**$two;
....> }
pugs> curryer(3,2)
9/1
pugs> my $c = &curryer.assuming(two => 2);
pugs> $c(5)
25/1
pugs>
In this case, $c would be a function that simply took numbers to the power of 2.
Currying is pretty useful as it allows us to define a sub that may take multiple parameters, but map it over a list of values sequentially as if it only took one, i.e.:

pugs> sub tester($first,$second,$third) {
....> say "first = " ~ $first;
....> say "second = " ~ $second;
....> say "third = " ~ $third;
....> }
pugs> map &tester.assuming(second => 5, third => "asdf"), 1..5;
first = 1
second = 5
third = asdf
first = 2
second = 5
third = asdf
first = 3
second = 5
third = asdf
first = 4
second = 5
third = asdf
first = 5
second = 5
third = asdf
pugs>
Nifty, I know.


Wrapped Subroutines
Aside from currying, it is possible to have fun with subroutines in another manner: by defining a function wrapper that is executed when sub is called. Wrappers basically allow you to write fairly polymorphic/generic functions, and wrap them with a specific functionality using full Perl 6. It's important to note though, that this wrap actually modifies the function itself; it doesn't return you an anonymous function in a Scalar or somesuch (we'll get to this in a sec.)

All Routine's have a .wrap method. It expects one argument of type Code (a block of code, essentially.) This parameter may have the special expressions callsame,callwith, nextsame and nextwith within it. These all call the original Routine, but you may specify different parameters, etc..
Example:

pugs> sub wrapexample($a) {
....> say 'in middle; value passed == '~$a;
....> }
pugs> wrapexample "asdf";
in middle; value passed == asdf
pugs> $h = &wrapexample.wrap({say 'beginning'; callwith(42); say 'end';});
pugs> wrapexample "asdf";
beginning
in middle; value passed == 42
end
pugs>
The id returned by a .wrap method can later be used to .unwrap the method. A call to .wrap replaces the previous routine definition with what you supply as your Code block, and you may have multiple wraps. Therefore, it's wise to get the return value of .wrap so you may unwrap it later:
pugs> &wrapexample.unwrap($h);
pugs> wrapexample "asdf";
in middle; value passed == asdf
pugs>
(addendum: so far, .wrap doesn't work like above on pugs r16525; ergo, the above is fabricated, but accurate. It is however documented in S06 and will most likely be implemented sometime in the near future [hopefully.])


Conclusion
Well, in this article I roughly covered subroutines in Perl 6. There're quite a few changes, so you need to adjust to them; none are too daring to accept, however. Next round, I think we'll cover Object-orientation in Perl 6, before moving to Grammars and rules.

Tuesday, May 22, 2007

Perl 6: Round 1

Pugs revision: r16464

Note: Oh, before we get started, a quick word I probably should have addressed in my last post: it'd be good to note by anybody reading this blog, that the face of Perl 6 can change pretty quickly. Code may work one day and not the next. It is therefore important not to focus entirely on the syntax of the code: the scales tilt better in favor of semantics than syntax. But just know, semantics are subject to change as well (although I hope to get the general point across.)
It will, therefore, not be my responsibility to update the code to reflect future changes to Perl 6 and Pugs. What you read here should be taken with a grain of salt and it may not work out of the box for you. For this reason, I'm going to start posting the revision number of my Pugs version at the top of my blogs (such as seen starting with this post; note that if I decide to deal with the v6.pm Perl5 module, I will state so explicitly), so you can get an idea of the 'when and where this worked.' This isn't a solid metric; it is merely suggestive.
Essentially, be warned: frustration may lie within.

So now that such a formality is out of the way (albeit, an important one,) let's go!


Starting off
I'm sure you're as ready as I am to get hacking with Perl 6. Let's start by doing some simple evaluations in Pugs:

[altair@stormwind perl6]$ pugs
______
/\ __ \
\ \ \/\ \ __ __ ______ ______ (P)erl 6
\ \ __//\ \/\ \/\ __ \/\ ___\ (U)ser's
\ \ \/ \ \ \_\ \ \ \/\ \ \___ \ (G)olfing
\ \__\ \ \____/\ \____ \/\_____\ (S)ystem
\/__/ \/___/ \/___/\ \/____/
/\____/ Version: 6.2.13 (r16464)
\/___/ Copyright 2005-2007, The Pugs Contributors
--------------------------------------------------------------------
Web: http://pugscode.org/ Email: perl6-compiler@perl.org

Welcome to Pugs -- Perl6 User's Golfing System
Type :h for help.

Loading Prelude... done.
pugs> "Good to see you, my friend"
"Good to see you, my friend"
pugs> 1
1
pugs> 1 + 2
3
pugs> 2**5
32/1
pugs>

The pugs prompt essentially is to Perl 6 as GHCi is to Haskell: Expressions are evaluated in the prompt and pugs will give you the overall result of your expression. Any arbitrary expression may be entered into the prompt providing it is syntactically and/or semantically correct.

An interesting point to note here is the absence of a semicolon in our statements: an expression sans a semicolon in the pugs prompt will evaluate the expression, and give us the overall value of the expression, i.e. the return value, with or without side effects (such as I/O.) A semicolon in the above statements would result in nothing being outputted: the return value is computed, but not printed to standard output.
This is a good point to know; absence of a semicolon in your expressions will give you the result of the expression as far as pugs itself is concerned, i.e. it may tell you True, undef, or it may even return the 'de-sugared' form of an object. A semicolon at the end essentially just 'mutes' your output a little (as far as this introductory tutorial goes.)


Also note that types in Perl 6 are strictly optional. Like it's predecessors, Perl 6 is dynamically typed; however, a type system does exist now: type annotations to specify what a variable is/holds are strictly optional, however.
In perl 6, there are two distinct different types: Mutable types, and Immutable types (Note: these definitions are fairly lax. For a stricter definition, you should refer to S02.) Mutable types are essentially the type a variable actually is, as opposed to what it contains. These types include Scalar, Array, Hash, Sub, etc. etc.. Immutable types are are the other half: the type a variable may contain. These are types such as Str, Int, Complex, and Bool.

Now, we'll continue. It's only proper to do a 'hello world' in a language when you first start it. Let's do that now:

pugs> say "hello world";
hello world
pugs>


On a side note, one of the newer things about Perl 6 is that many of the builtin functions act a lot like method's of a class; the above example could have been written this way as well:

pugs> "hello world".say;
hello world
pugs>


This will work with just about any builtin function (see: S29.) The syntactical choice is merely personal preference.

At the point when writing anything really significant, we should probably get out of Pugs itself. We can simply write the code in a source file and execute like so:

[altair@stormwind diveintoperl6]$ cat > hello.p6
use v6;

say "hello world";
[altair@stormwind
diveintoperl6]$ pugs hello.p6
hello world
[altair@stormwind
diveintoperl6]$

We will continue to use Pugs in the prompt until we are to the point that we would rather have a script.

Variables in general

In Perl 6, you stand beside your tried and true variable types. You've still got your scalar & co.. There is a difference in Perl 6 though that needs to be addressed now, this difference being sigil invariance. Sigil invariance in Perl 6 means, that while your variable sigil's changed depending on context in Perl 5, they do not in Perl 6. You will always refer to @arr as @arr, i.e.

my @arr = (1,2,3,4,5);
say @arr[1]; #this will output 2


This goes for all the basic variables in Perl 6. (Given, you can create a scalar that's a reference to an array, thus getting the same effect.)

Also, you must always explicitly define your variables in Perl 6 using 'my.' To go without it will produce an error.
(edit 05/25/07: the above is not entirely correct; in perl 6, a 'use strict;' declaration is implied in code and is the default; thanks to Aankhen`` for pointing this out.)

Scalar
A scalar is a variable in the most basic sense. It holds a single value of whatever you want. For example, an integer, a string, a reference, etc. etc..

To be completely honest, there isn't much to say here. So I'll just move forward.

Array
An array is simply a list of Scalar values, to put it bluntly. Array's can hold an arbitrary number of elements of any arbitrary type.

Declaring an array is as simple as a comma delimited list of elements, as such:

@a = (1,2,3,4,5);
@b = ('a','b','c','d','e');


They can also be declared 'word style' using the < > operators:

@a = <1 2 3 4 5>;
@b = <a b c d e>;


These operators in this context act much like the perl 5 construct qw(). They create an array based on the string, token delimited by any amount of whitespace (you may also use these with hashes as we'll see later.) Note that using this style, your array value's will in terms of type, be strings. However, Perl is dynamic, so s'all good baby.

Array's have several functions dedicated to them. Let's play around.

pugs> my @a = ("this","is","my","house");
pugs> @a.pop
"house"
pugs> @a.shift
"this"
pugs> @a.unshift("hi")
3
pugs> @a
("hi", "is", "my")
pugs> @a.push("whoa")
4
pugs> @a
("hi", "is", "my", "whoa")
pugs>


It's important to know these functions cause, what's known in the Haskell world, as a destructive update. The actual array is modified your function (a side effect); you must be aware of this.

Hashes
A hash is essentially the same as it was in Perl 5. A hash is an array of key => value pairs. Rather than using a numerical index into a hash, you can instead use a textual index. Let's see an example:

pugs> my %h = ("five" => 5, "my_name" => "austin seipp", "delta" => 3.14);
pugs> %h{"five"}
5
pugs> my $d = "delta";
pugs> %h{$d}
157/50
pugs> %h<my_name>
"austin seipp"
pugs>


Hash elements are referenced using a key, this key can be passed the traditional way via the { }brackets with the quoted string/variable, or you may use the < > brackets now to achieve the same effect, i.e.:
pugs> %h<delta>
157/50
pugs>

Hashes have several operations of their own. Examples:

pugs> %h.keys
("my_name", "five", "delta")
pugs> %h.elems
3
pugs> %h.values
(157/50, 5, "austin seipp")
pugs> %h.kv
("my_name", "austin seipp", "five", 5, "delta", 157/50)
pugs>



These our are basic variables; be sure to look at S29 for function references and play around with a lot of the built in variable types and their functions.

Control Structures
Perl 6, for the most part, has similar control structures to that of Perl 5. You have your traditional if and while loops, i.e:
pugs> if $a {
....> say "cool!";
....> } else {
....> say "uncool!";
....> }
cool!
Bool::True
pugs> my $b = 1;
pugs> while ($b++ != 10) {
....> say "still even cooler!";
....> }
still even cooler!
still even cooler!
still even cooler!
still even cooler!
still even cooler!
still even cooler!
still even cooler!
still even cooler!
still even cooler!
undef
pugs>

Pretty basic, as you can see. You also have an unless statement, which essentially is just the opposite of if. There are also a couple of (slightly) different control structures; namely for, loop, and given.

For is basically the equivilant to an array iterator control structure (commonly known as foreach in other cultures), example:

pugs> my %h = ("key1" => 1, "key2" => 2, "key3" => 3);
pugs> for %h.kv -> $k,$v {
....> say "Key: " ~ $k ~ "\t Value: " ~$v;
....> }
Key: key1 Value: 1
Key: key2 Value: 2
Key: key3 Value: 3
undef
pugs>

Loop is basically the canonical for in other languages. It is called with the traditional syntax of loop ($i=0;$i<10;$i++) you would generally see in other languages.

However, with no arguments, loop can also be used as a simple infinate loop. Example:

[altair@stormwind diveintoperl6]$ cat > loop.p6
loop {
say "i'm never going to terminate, ever!";
}
[altair@stormwind diveintoperl6]$ pugs loop.p6
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
i'm never going to terminate, ever!
...
^C goingpugs: interrupted
[altair@stormwind diveintoperl6]$


Loops also have means of breaking out of loops, the same way you would use continue; or break; in other languages. These means are the keywords next,redo and last. next and last are essentially the same as continue or break (continue exists in perl 6 too, we'll get to that in a moment.) redo is a little different, essentially it is the same as next, only no counters are iterated and the loop simply starts over in the same state.

Here's another example:

pugs> my $i = 0;
pugs> loop {
....> $i++;
....> last if $i == 10;
....> next if $i == 5;
....> redo if $i == 8;
....> say "iterator: "~$i;
....> }
iterator: 1
iterator: 2
iterator: 3
iterator: 4
iterator: 6
iterator: 7
iterator: 9
undef
pugs>


In this instance, redo essentially does the exact same as next; it is important to note that in this case, our differentiator ($i) is being modified inside the context of loop, so therefore -- as far as this example goes -- redo doesn't really accomplish much. redo is useful however when for example, you want a condition to be held and not continue to the next iteration without that condition being true (for example, you need a sub that is called in your loop to return True in order to continue with the next iteration of the loop.) This condition would most likely be dependent on some sort of a side effect (such as say an external file modification, or even another thread.) Here's a basic example:
[altair@stormwind diveintoperl6]$ cat > redo.p6
#!/usr/src/env pugs
use v6;

sub blocker { ... }

loop (my $i=0;$i<5;$i++) {
say 'iteration: '~$i;
redo unless blocker();
}

my $j = 0;
sub blocker {
($j++ < 3) ?? True !! False;
}
[altair@stormwind diveintoperl6]$


(edit 05/29/07: redo is apparently not fully implemented, as tested on pugs r16525.)

The final control structure I'll describe here is given; essentially, given == switch if ($lang == 'Perl 6'). For anybody who's been wishing for a switch for perl: you've finally got it. Example:

pugs> my $i = "str1";
pugs> given $i {
....> when "str1" {
....> say "we have str1 in our midst";
....> }
....> when "str2" {
....> say "str2 is alive!";
....> }
....> default {
....> say "default case, too bad";
....> }
....> }
we have str1 in our midst
Bool::True
pugs>

It's important to note that, all of the when cases inside of a given have an implicit break on the end. You may fall through to the next structure however, using an explicit continue in your particular when case.

given can be used in a little more advanced manner (notably with rules,) but we'll probably move onto that in later articles.

Conclusion

This article is the first part in a few series I'll be making to introduce people to the language. At the end of these 'Rounds,' we'll get to actually writing production code and a few programs in Perl 6.

Exciting, isn't it?

Monday, May 21, 2007

What is Perl 6?

Since this is an introductory post to this, a blog dedicated to Perl 6, I figure I should establish a few things about what Perl 6 is, before just 'jumping in.' Perl 6 is more than a language, it's a community and a development effort by those willing to be involved.

To start, I'll go ahead and list of a few things from the 'Perl 6 jargon file', so you're not caught by suprise when these are referenced to later:

  1. Apocalpyse: Larry wall, BDFL of the Perl project, designed Perl 6 to be 'the community's rewrite of perl,' where Perl 5 was his rewrite of Perl. To do this, people from all around the globe submit RFC's to the perl6-language mailing list (short form: p6l which is how I'll refer to the list from now on,) talking about what they believe what changes should take place in the language. Wall manually answers these RFCs and describes whether he accepted or rejected the change, and why. An apocalypse is a collection of these RFC's and their answers. Every apocalypse directly relates to a chapter of the Camel book.

    Note, that Apocalypses, after their initial release, can be revised. It is not uncommon for an Apocalypse to soon change after it's publication; if you have code that isn't working, but only 'proved to be correct, yet not tried,' [sic] check the accompanying Apocalypse: the syntax and specifications may very well have changed.
  2. Synopsis: After an Apocalypse, a Synopsis is written. The synopsis essentially sums up the changes taking place described in a single Apocalypse. The name is just what it sounds like. Synopsis are generally more approachable and less lengthy than their accompanying Apocalypse.
  3. Exegesis: The Exegesis are practical explanations and code samples of the changes taking place as described by both the Synopsis and Apocalypse. These are your examples of the specifications the Apocalypses describe.
  4. Pugs: Pugs is an implementation of Perl 6, written in Haskell. Pugs intends to bootstrap the perl 6 compiler by writing it in Haskell. The objective is that once all the pugs milestones are done, that if needed, Pugs will be rewritten in Perl 6, to develop a fully fledged Perl 6 compiler, in Perl 6. You can find more on the wiki entry. Commit access to pugs is handed out quite liberally, and anybody is free to work on whatever they feel needs to be worked on. Just the way Perl 6 is a community effort and a rapidly changing landscape, so is Pugs.

    Note that Pugs is not the only implementation of Perl 6, it is merely the most complete and established. Via the use of the v6.pm module, it's possible to write limited amounts of Perl 6 in Perl 5 (you may think it as either 'perl-on-perl' action or 'perl-on-haskell' action.)
    In my future posts, I will generally stick to Pugs for the implementation, as it is more feature complete and more accurately reflects the current state of Perl 6.
  5. Parrot: Parrot is a virtual machine, designed to run Perl 6. The virtual machine is designed for fast (one of it's primary goals) execution of dynamic languages such as, but not limited to, Perl 6. Multiple languages can run on Parrot (languages for parrot can be constructed via the use of a very interesting compiler-toolchain, designed for Parrot), and the architecture is modern and well done. Parrot is discussed primarily on the perl6-internals mailing list (p6i.)

    Please keep in mind, development of Parrot in relation to the actual Perl 6 language is nigh orthogonal: Parrot's only obligation is to support Perl 6 and it's semantics, but the language designers have no say in how it's done or why. Parrot is, as well, the only virtual machine for Perl 6. Communication between these two branches is done, however, they are two seperate entities by all practical means.

So now that the lingo is out of the way, what's the real deal with Perl 6? How can you get involved?
Getting involved is essentially as simple as joining the mailing lists (and I would recommend joining IRC as well: irc.freenode.org #perl6) and posting. That's it. Perl 6 is a community effort in its entirety: you, the people, say what stays and what goes. Submit your RFCs, comment on others, the power to change the language is yours.


Aside from the community, Perl 6 has changed a lot technically. Niklaus Wirth said that if we add things to a language, we must throw things away. You are still writing perl, and you will still be backwards compatible, but a lot of things are changing from Perl 5 to Perl 6. Things are getting added, things are getting thrown away.

Quick examples are:

  • Sigil invariance. When referencing an array itself (or any other type, for that matter), or an element of the array, you always give it the original sigil you declared it with, i.e. you are going from $arr[1]; to @arr[1];. Note, context in Perl 6 still exists, but sigils do not vary.
    Example:

    pugs> my @a = 1..5;
    pugs> @a[0]
    1
    pugs> $a[0]
    Internal error while running expression:
    ***
    Unexpected "["
    expecting "::"
    Variable "$a" requires predeclaration or explicit package name
    at line 1, column 3
    pugs>
  • Object orientation is full blown now. Classes and object-orientation is greatly improved, as you now have classes, [multiple] inheritence, private/public pieces of data, constructors and destructors; object orientation is much more complete.
  • Regex's no longer exist. You're using Rules, now (this change in lexicon is due to the fact that perl's "regular expressions" are so far off the mark of a traditional, formal regular expression, that they were renamed.) One of the greater things about Rules and Grammar's in the new Perl 6 engine is that Grammars are essentially 'classes for rules,' a grammar just inherits from the Rule class itself.
  • Static types. Perl 5 was a dynamic language, Perl 6 adds static typing capabilities. These are simply strictly optional annotations to your already existing variables to explicitly define your type. Either style of programming can be used.
    It's interesting to note that as you can specify types to a variable, you can specify two kinds: a type refering to what the variable holds (strings, int's, etc.) and a type referring to what the variable actually is; a hash, an array, ex:

    pugs> my Int $i is scalar;
    pugs> $i = 1;
    pugs> say $i
    1
    Bool::True
    pugs>


    This is not limited to the built in types, any may do, including classes.
  • Laziness. Lists and the like are now implicitly lazy, meaning you can do things such as my @a = 1...;
  • Various syntax changes. Parenthesis in a large majority of constructs are strictly optional. Array's may be constructed in a 'stream of words' fashion using the < > operators, rather than qw(). I.e., from my @a = qw(a b c d); you go to my @a = <a b c d>;. Hash values can be referenced the same way, i.e. %hash<some_key>; Prototypes for subs can simply be done via sub name { ... };. There are more various little changes around, but none of these are hugely significant ones.

Those are just a few of the changes. For more, I suggest you read these.

Perl 6 is a big change to an already very popular programming language. One isn't going out the door for another to come in the same day: the adoption will be slow, but it is a needed change and a good one for both the Perl community, and Perl itself. If you would like to contribute, I can only suggest you sign onto IRC/mailing lists, and you speak your voice and do what you think you need, or are able, to do.

It's your language, it should do what you want it to; shouldn't it?

Sunday, May 20, 2007

Welcome!

This is my first post on my blog, Dive into Perl 6. On this blog I hope to document my Perl 6 adventures and provide insight into Perl 6 for those who're new to the language and project.

Stick around, content will come soon.