Monday, April 16, 2007

Deus Ex Automatis, Part V(a)

Now (finally!) for some code. I've had a bit of a hard time getting this to format correctly, so if there are problems, pop me an email, and I'll try again.

I have two reasons for presenting examples in Perl 6. Reason number one: Perl 6 is reasonably easy for native English speakers to read, even if you're not a hacker. Reason number two: it's fun.

Hopefully it also does something useful, such as compiling without errors.
class Rule {
has Int $.neighbors = 2;
has %.lookup =
( '11'=>'0', '10'=>'1', '01'=>'1', '00'=>'0' );
}
This code isn't particularly useful by itself, but if you wanted to try it, just copy and past that code into Pugs, a Perl 6 implementation, and call it like so:
pugs> my Rule $rule .= new();
pugs> say "Rule has $rule.neighbors() neighbors."
Rule has 2 neighbors.
Note that both $.neighbors and %.lookup have not one, but two punctuation marks at the beginning of the word. The first is a sigil. The sigil designates $.neighbor to be a scalar, and %.lookup to be a hash (e.g. lookup table). The second character (both have a period) tells the class to create accessors for each. So we can do things like "$rule.neighbors()"

One of the most satisfying parts of writing code in Perl 6, is that my spell checker doesn't raise a red flag (or underline) for most the code I write.

The code above is totally static, and could really have used just a built-in data structure. Perhaps a more useful rule could accept any number of neighbors (as an argument) and a rule number as are often used in constructing simpler cellular automata. That could be done like so:

class Rule {
has Int $.number is ro;
has Int $.neighbors is ro;
has Bool %.lookup is rw;

submethod BUILD (:$.number, :$.neighbors) {
for ( 0 .. (2 ** $.neighbors -1) ) -> $key {
my $format = "\%0" ~ $.neighbors ~ "b";
%.lookup{sprintf($format,$key)} =
?($.number +& (1 ~ 0 x $key) );
}
}
}

Perl 6 gives us a built-in pretty way to overload the "new" method in a class with "submethod BUILD". What we've done here is add a method that unpacks the Wolfram-style rule into a lookup table when you create a rule.

As an exercise for the reader, here's how to make the same rule we've been talking about all along:
pugs> my Rule $rule .= new(:neighbors(2), :number(6));
Why?

Labels: , ,






<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]