Perl 6: Coding with Class

This entry will focus on creating and using classes in Perl 6.  Perl 6's class system greatly expands on the approach of Perl 5 in many ways, a few of which are giving a standard new method and providing an approach for easily declaring attributes on a class.

Here is a very simple example of a Perl 6 class:

This example shows a few basic concepts.  First there is the new class keyword.  Named classes can easily be declared in one of two ways.  The example above, with curly braces, is useful when defining more than one class in a file or providing for some code to execute outside of the scope of the class when loading.  Without the curly braces is also legal, however it means that the rest of the file is the class definition.

Additionally, this shows our first attribute, name.  The name attribute is defined as being of type Str.  The twigil '.' in this case indicates that this attribute should have a public accessor.  In this case that accessor is read-only because we did not define it otherwise (see below).

The eat and sleep method were also defined.  The sleep method uses the name attribute on the class in the string that it says.  It can do this without using $self because $. implies the object the method was invoked on.  So, the eat method could have also been rewritten like it is for the sleep method.

Instantiating new objects of type Animal and using their methods is simple:

A more complicated example is below.  In this one two more classes, 'Dog' and 'Tail', have been defined:

The Dog class has a couple new interesting additions.  The first thing to notice is that Dog inherits from Animal via the is keyword on the first line.  The tag attribute is defined as 'rw'.  This means that public accessors for both acquiring and mutating the value of the tag are provided.  The tail attribute has a '!' as a twigil.  This twigil indicates that no public accessors should be defined.  However, an instance of the Dog class delegates to the tail attribute when the wag method is invoked upon it.  This means that when someone calls $a_dog.wag they are really calling wag on $a_dog's $!tail.  Delegation is a very handy way to improve code reuse, Perl 5 developers who use Møøse should be familiar with it.  Finally the tail also has a default value of a new Tail object.

This new class can be easily used like the following example:

However, what if we didn't want to use the simple Tail class for our dog's tail.  We could pass in an object of another class that had a wag method on it like so:

That pretty much wraps up this entry on Perl 6's class system.  The system includes many more powerful features that should be covered at a later date.

Further Reading:

Week 4: Currying

This week we'll be covering the process of partially applying parameters to a subroutine, this is based off of closures which we covered last week.  This allows us to create new subroutines that we can pass around that already have some of their parameters defined.  One of the benefits of this is that we don't have to pass around a parameter list and wait until all the parameters are ready, instead we can apply each parameter as we get it and then execute the subroutine at some later time when we are ready.  Doing this in Perl is actually very simple.

The function above provides us the ability to curry other functions.  Analyzing it shows that all we are doing is creating a new anonymous function that is going to call the function we passed in with the parameters we passed in and the parameters it receives.  Let's see an example of how this would work.

So, let's look at how it all worked.  First, we made a new anonymous function that takes a list of parameters, joins them, and prints them.  Next we curried that list with 3 fruit.  To do this we created a new anonymous subroutine that passed in the three fruit into the first anonymous subroutine.  After that we repeated the process, by currying the new subroutine we created from the last curried we now have a subroutine that calls the subroutine created on line 3 with 2 new fruit, that subroutine calls the subroutine created on line 1.  Once we execute this we will output a list of all the fruit we've given to the function.

We don't have to only curry anonymous functions.  Because we can get the reference of named functions and builtins we can also curry those.

This concludes this week's lesson.  Next week we will move past the building blocks of functional programming and start getting into systems built on top of this functional foundation.  Next week we'll cover dynamic dispatch tables.

As an aside, the name curry didn't come from the tasty South Asian type of dish, unlike the naming of Mix-Ins.  Instead, currying is named after the American Mathematician and Logician Haskell Curry.

Cutting Back

I will probably be cutting back to one larger article a week.  The articles will probably either focus on Perl 6 or functional programming, I doubt I will continue the Moose series during this time.  Moose is great, but the documentation is so approachable I doubt I can really add much to it, at least not until I read The Art of the Metaobject Protocol .

It is awfully early to be doing so but I'm doubling my course load for my masters, while holding a full time job, fixing up my house, and preparing my talk at Strange Loop 2010.  Sorry for anyone who enjoyed the current frequency.

Week 3: Lazy Evaluation

One of the popular concepts in functional programming is the concept of lazy evaluation.  For code to be lazily evaluated it means that instead of being evaluated at the point when the system reaches it it is instead evaluated at the point that the results are needed.  The concept of lazy evaluation exists in lots of languages; Perl 6 uses them for lists, as does Python, and languages like Haskell, Clojure, and others use them quite frequently.  In fact, at the latest Clojure Cljub meeting one developer was complaining that Clojure was so lazy it was hard for him to tell when it was doing nothing at all.

The benefits of having the ability to lazily evaluate code show up in many cases.  Lazy evaluation can allow developers to represent "infinite streams" because the only portion of the stream that is computed is the portion that the program needs to perform its task.  Without lazy evaluation the program would try and compute all possible values and never complete.  Additionally, things like Moose use this concept to allow a developer to lazily evaluate attribute construction.  This is hugely beneficial because it means that attributes that take a long time to construct will only be constructed when they are needed, instead of on the main object's construction.  DBIx::Class also uses this, the query to the database doesn't happen when 'search' is called on the DBIx::Class object.  Instead, it is called when the first piece of data is retrieved.  This allows DBIx::Class to wait and collect as much information about what the query really needs to be before it executes it, saving precious database time by not making wasteful queries.  A final example would be Object::Trampoline, which can delay the construction of an object and the loading of modules.

So, how do we lazily evaluate code in Perl 5?  We simply wrap it in a subroutine.  Let's say, for example, we wanted to make a stream that generated the set of all natural numbers (N), which is simply all the integers ≥ 0.  We would simply write something like this:

Now, each time we want a new natural number we can call the anonymous subroutine and a new one will be generated.  We could then use this in a while loop:

Another benefit of this approach is that we can now provide streams of numbers logically separated from the looping method (which is a common benefit of iterators).  So, for example, we could use these two streams with the same while loop:

Obviously, we could do considerably more interesting things than this.  MJD's Higher Order Perl talks about creating lazy linked lists in chapter 6.2.

Perl 6 - The Many Faces & Features of Functions

***Update: Carl Mäsak (@carlmasak) corrected some misunderstandings I had regarding the scoping of subroutines and the use of export.***

When I first announced the Functional Perl series on the STL-PM Bill Odom asked if I would be including Perl 6.  I declined at the time stating that there were sufficient difference between Perl 6 and Perl 5 to make the articles too busy.  There aren't a huge amount of differences, but I didn't want to clutter a Perl 5 article with things like method.assuming( x=> 11) or leave it out of a Perl 6 article.  This article isn't an article about functional programming, but it is a talk about functions in Perl 6 so that I can later do functional articles.

Named Functions

Perl 6 sports an incredible amount of power and flexibility without losing a bit of the flexibility one can find in Perl 5.  In fact, one could write a Perl 6 subroutine that looked like this:

Or like this, which gives us type checking:

But constraint checking can even move beyond basic type checking.  Perl 6 can can provide further constraint checking with a where clause on a parameter:

This version only allows us to give interest rates that will increase the future value.  

Perl 6 also allows for functions to be able to declare through traits:

  • if they are safe to automatically cache
  • the precedence (if it is for an operator)
  • tons of other stuff

Additionally, explicitly stating all the implicit traits on a method can make it very verbose, like AppleScript verbose.

Anonymous Functions

 

The Perl 5 way of creating anonymous functions is still valid in Perl6.  However, you now use the method invocation operator ('.') instead of the '->' available in Perl 5.  You can actually skip the method invocation operator since it can be implicit in this case.  So, for example, you can make and use an anonymous subroutine like this:

 

Perl 6 also provides for a lot of new approaches towards creating and using anonymous functions.  In fact, according to Synopsis 4, every block is a closure.  so, for example, you can now write an anonymous function simply by doing this:

If you wish to include a parameter list you can do so with a slightly modified version of that called the "pointy block":

Additionally, If you read my post on Perl 6's Whatever then you already know that you can use Whatever in a statement to close over that statement and create a function to evaluate it later.

A Bump in the Road: Scope

The move isn't completely roses for function happy developers though, there is one little hiccup you might encounter.  This code, which uses a hash as a cache that's closed over in the subroutine will be a little different than the Perl 5 version:

That is because subroutines are now also scoped and are implicitly given the same scope as provided by 'my'.  This is a simple matter though, we simply give the subroutine the 'our' scope.  Here is the equivalent example in Perl 6:

A Tangent: Control Structures

This is a bit of a tangent, but I find it interesting.  Do you remember when I said that any block is a closure?  That counts for things you probably didn't consider, things like the blocks on if, while, and for statements.  These are all now closures too.  In fact, Perl 6 allows us to iterate over lists n-at-a-time because of this.  The for loop will now pass us as many values as we provide as parameters in our block. Here is an example:

Of course, this example will complain when we reach 100, so we can do this:

The above example allows us to pass in 1-3 parameters, as many as are available.  In this case though Mu is assigned to values that aren't passed in, which stringifies to "Mu()".  We probably don't want that, so we'll just use defaults:

Summary

Perl 6 gives functions, named or otherwise, a wide variety of new syntactic features.  It also really promotes the role of closures and anonymous functions, which is a welcome addition.  Perl 6 is also bakes in new features, like memoization and currying.

Given all of that, I hope people understand why I'll be trying to keep Perl 5 and Perl 6 articles apart.

Further Reading

Week 2: Closures

This week we will be covering closures.  Closures are another basic concept of functional programming.  They are based right on top of anonymous functions so if you haven't read last week's article it would behoove you to do so.

Closures are subroutines that "close over" variables thereby storing them in the scope of the subroutine to be accessed later.  Values stored in variables that exist within the scope of a function are guaranteed to exist as long as the function does.  This allows a developer to create subroutines that do many useful things, including provide state and encapsulate values.

In Perl a subroutine can access variables defined anywhere lexically above it, even once the scope that it is in is left.  This allows us to access otherwise lost data.

Whereas if we change this example to simply:

This code will fail at compilation time because $value isn't defined in the outer scope.

This is not unique to named functions, anonymous functions provide the same functionality:

We can use closures to create new subroutines that have some state stored in them.  For example, here is a subroutine that returns a subroutine that takes numbers to the power of the variable that was closed over.

It is important to note in the example above that each time power_of_generator is called the new anonymous subroutine returned has a new value to $power and cannot interfere with any other subroutines value of $power.

Another useful ability that closures have is that they can safely encapsulate data, more safely than many of the OOP approaches in Perl.

It is important to note in the example above that $name cannot be accessed outside of the scope of the outer curly brackets.  As such, there is no way to set $name to a value that is not title cased.  This is because the only way to set name is through set_name() which will not accept a value that isn't title cased.

The example above only provides the ability to store one name in a running program.  If we wanted to safely store multiple names we could do so by wrapping the $name and accompanying subs into a larger sub.

This concludes our discussion on closures.  Next week we will move on to currying and a discussion on 'higher order' subroutines.

 

Perl 6 - Whatever

***UPDATE: Carl Mäsak (@carlmasak) was kind enough to let me know that Whatever is simply a term. ***

The specifications for Perl 6 define the Whatever term, which is just an asterisk (*).  The Whatever term basically means "I don't care, you decide."  This breaks down to some slightly different meanings in different contexts.

As a Parameter

The Whatever term can be used by passing it as a parameter in a function, e.g. `bless( *, |%my_Data)`.  In the case where it is a parameter passed into the method it is telling the method, "I don't know or care, so whatever you think is best."  This may seem strange, but this is actually very similar to default values in other languages (and Perl 6), but is more powerful.  

This is more powerful than default values you see in other languages for two reasons. The first reason is that the Whatever term can appear anywhere in the parameter list.  This means that API designers don't have to guess their most commonly defaulted parameters and then put them at the end, they can put them in the order that makes the most sense. The second reason is that Whatever can be more powerful than a default.  Since methods receive your Whatever they can hold on to it and do a little bit of reasoning to determine what it is you probably want before it replaces your Whatever.  This is unlike defaults which are set at the top of the function.  Here is an example usage with bless:

In this case bless will return back an object of type Any because bless decides to use the type of the object that called this. 

Of course, it is important to know how this works.  When you pass in '*' as a parameter to a method the method gets back an object of type Whatever.  This effectively signals to the called method that it can do whatever it wants with that parameter.

In a statement

When you provide the Whatever term inside of a statement that statement is closed over, replacing your Whatever term with a variable that will be passed in to the new anonymous function.  So, for example, were you to provide:

You would find $foo holds something like:

Which you could then use like this:

You can also use it for a method call, like this:

In this case $x basically holds something like:

Specific Uses

The Whatever term has some very specific uses when it is provided in some cases:

Further Reading

If you would like to read more on the Whatever term you should look through Synopsis 2-Bits and Pieces where this is defined.

Basic Moose Week 1: Creating a Class

*** Update:  Thanks to Kent Fredric (@kentnl) for catching my mistake on his MooseX::Has::Sugar***

Perl5's object system is impressive in its simplicity.  From that simplicity it gains an incredible flexibility which both matches Perl and allows for amazing things.  However, it is easy to find patterns created from the spartan nature of the system.  This last point has caused many people to design new object interfaces on top of Perl's object system.  The most robust and popular of these is Moose.  This first tutorial will show you a simple way to create classes using Moose.

Moose allows the user to easily declare the attributes that are provided on a class along with metadata about those attributes.  This metadata defines many important aspects of the attribute, such as what type of attribute it is, what the permissions are on the attribute, the default value of the attribute, and many other things.  Here is an example of a simple class called employee:

This class definition does several things, so let's break it down.  First we use Moose, this exports some spiffy 'keywords' like has.  Additionally, it very sneakily uses the strict and warnings pragma in our package which is very convenient.  Next we use the has keyword to define an attribute called pay.  We define this attribute as being both readable and writable through its accessor and we say that the accessor should only accept numbers.  Next, we create another attribute called manager, which has an accessor that both allows reading and writing and only accepts Employee objects.  How does it know that Employees are objects?  Well, Moose has a list of things that it considers types.  If the type is already defined then it uses that type, otherwise it assumes it is a class.

That seems like that could be dangerous though.  For example, what if you typo'd 'Num' to be 'num' or 'NUm' or if you spelled out 'number'?  In these cases Moose would assume that 'num', 'NUm', or 'number' were names of classes and only accept values that were of that class.  Don't worry though, someone has already seen and solved that problem, the solution we will use for this is a combination of MooseX::Has::Sugar and MooseX::Types.  MooseX::Has::Sugar provides us with several predefined 'keywords' that we can use and if we typo we'll get compile time errors.  Additionally, it defines rw and ro (the value for is that indicates readonly) in such a way that we no longer have to provide the 'is =>' portion.  MooseX::Types allows us to predeclare types and organize them into libraries.  Now our class definition looks like this:

This looks much better.  By the way, there are many options to MooseX::Has::Sugar and MooseX::Types so you would really benefit from reading that over.

Let's try and use this class in a script:

Now, if we look at that script we see some very interesting things.  We never explicitly created a new, manager, or salary method but they are all there.  This is because Moose created each of these for us to use.  In fact, it is imperative that when you are using Moose you do not create your own new method, that is very dangerous.

Of course, Moose provides many other meta attributes to define the attributes of your class, some of which are:

  • required - whether calls to new() must include this attribute, can be 1 or 0
  • default - the default value of this attribute or a reference to a sub that will return the default value, it is better to use builder though (see below)
  • lazy - whether this attribute will be built when the object is built or whether Moose will wait until it is first used
  • …and more we'll cover in following weeks

We'll rewrite our class by adding some attributes and adding these meta attributes to all the attributes, but this time we won't use MooseX::Has::Sugar or MooseX::Types:

Builder vs. Default

I mentioned above that you can set the default value of an attribute with default however it is better to use builder.  The builder option takes the name of a subroutine that will return a value for the attribute instead of a subref or actual value.  The benefit of this is that if you inherit from a base class that uses a builder you can easily override the default value by overriding the sub that builds the value, with default it is not so simple.

Caveat

There is one important caveat to mention.  Neither Moose nor any of its extensions are magical and, in fact, none of them actually create new keywords.  Instead, all of these modules are importing methods into your package just like any other tool.  This means that they happen in the same order as you would expect function calls to happen.  It also means you can write them any way you want, however this is a place where following the standard benefits everyone.

Dirty Little Secret

As much as I like the idea of MooseX::Has::Sugar and MooseX::Types I should probably mention that I actually rarely use them.  However, they seem like a good tool to start off with.

Further Reading