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.