A Foolish Manifesto

fREWdiculous!

July 2009, DFW.p6m

Today we had another P6M meeting. There were seven of us despite the fact that three of the regulars were gone at a birthday party, so that was fairly heartening.

As you may already know from the Iron Man Feed, s1n did a talk on .WALK, which is a selector based system for introspecting the methods of a class. One really interesting thing about it is that it (apparently?) isn’t actually for dealing with inherited/overridden methods as much as it is for manually tweaking the multiple dispatch that Perl 6 supports.

Just to be clear, multiple dispatch is how Perl 6 chooses what method to run based on the parameters (and invocant) of a method. So you can do something like this:

1
2
3
4
class Frew {
   method foo($self: Int $foo, Str $bar) { ... }
   method foo($self: Str $baz) { ... }
}

And when you call the method it will call the right one based on the params passed to the method. You can even dispatch based on the value of the parameter.

Cool stuff!

  • 0 Comments
  • Filed under: Uncategorized
  • Dallas.p6m: June

    This month’s Dallas.p6m was bigger than before! We had my coworkers Geoff, Neil, and Wes, myself, Graham Barr, Jason Switzer (s1n,) Patrick Michaud, and John Dlugosz. We got a domain hooked up (dallas.p6m.org, which doesn’t point at anything yet,) discussed interesting stories about rakudo optimization (and often lack thereof,) and sometimes delved into perl5 stuff.

    s1n decided to mention that we need to start doing our feature expositions, which is where someone picks a feature in perl 6, does some research, does a talk on it, and then we write some code which is based on it. s1n is going to talk about .WALK, which allows you to look at the Abstract Syntax Tree. I’m pretty excited about that.

    Patrick explained to us how it seems that most traits are becoming declarators. That is, in class foo is bar, class is a declarator, and bar is the trait. Of course the migration isn’t a big deal because defining a declarator is similar to defining a subroutine.

    We also discussed Rakudo’s Unicode support. Patrick mentioned that they are looking for a “golf mode” character which will enable unicode characters for things like >= .

    We also discussed some of the Rakudo release strategy. It’s very similar (for obvious reasons) to Parrot’s release strategy. It’s exciting that they will continue to release regularly (monthly.)

    I can’t recall any other details regarding the meeting. I know we talked about more though. I should start taking notes…

  • 0 Comments
  • Filed under: Uncategorized
  • Contributing to Open Source

    I’ve used Open Source for a little over ten years now. I’ve been sufficiently indoctrinated that Open Source (Free Software) is both morally and technically the right choice. That’s not what this post is about. If you disagree with those premises, that’s fine. The idea here is that I use all kinds of Free Software all the time. I use Vim for a text editor. I use zsh as a shell. Firefox is my browser. This blog runs on Wordpress. The webserver we use at work is Apache. And the of course all of our code depends on Perl and numerous libraries.

    We don’t pay for any of that software! Not a dime! And that’s fine, but nothing comes for free.

    So far I’ve worked on three open source projects. The first was TOME, a book sharing system we used at school. Next I wrote some of the spec tests for Perl 6. And then most recently I’ve been doing some things for DBIx::Class.

    One of the excellent things about the DBIx::Class developer community is that they really do their best to help you to work on the source.yourself. Recently they (or more specifically ribasushi) helped me add the full sorting capabilities to the SQL Server parts of DBIx::Class. More lately I’ve been adding things for the paging capabilities, which is great because paging with SQL Server is horrendous.

    Anyway, the most important part of all of this is that I am part of something that will help me and other people. Furthermore, it really wasn’t that hard to add the code. They showed me where to add it, did a little code review to help me clean it up, and that was it! If only more communities were like that the Open Source world might be even more vibrant.

  • 0 Comments
  • Filed under: Uncategorized
  • Perl 5 to Perl 6 Rewrite

    My coworker Wes asked me if there could be a nice refactor for the following function which checks CAS Numbers to ensure their validity. After struggling for 30 minutes I gave up trying to make it a little bit nicer with reduce.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    sub cas_old {
      my $cas = shift;
      if ($cas =~ /\d{1,8}-\d\d-\d/) {
        my @ary = grep { $_ ne '-' } split(//, $cas);
        my $check = pop @ary;
        my $count = @ary;
        my $sum;
        for (@ary){
          $sum += $_ * $count--;
        }
        return $sum % 10 == $check;
      }
      return;
    }

    Let’s take a look at this and figure it out. The crunchy bit is the for loop, so I’ll go through that. Basically we are summing each item times a weight that is inversely proportional to it’s location in the list. Or to be more explicit, let’s do an example on the board (7732-18-5.) 5 is the check digit.

    $_ $count $_ * $count $sum
    7 6 42 42
    7 5 35 77
    3 4 12 89
    2 3 6 95
    1 2 2 97
    8 1 8 105

    So basically we are making a special summation. The thing that’s unusual is that we have a decrementing counter along with it. If I had the control structure which I am about to show you in my mind already the solution might have jumped out sooner.

    So I asked about it in #perl6 and it turns out there is a very nice Perl 6 version. It takes advantage of the mystical hyperoperator (>>infix op<<); that is, it takes two lists and performs an operation on each element together. Think SIMD. It also uses reduce ([infix op]) which I have mentioned before. Check it out!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sub cas(Str $cas) {
        if $cas ~~ /(\d ** 1..8)\-(\d\d)\-(\d)/ {
            my @digits = $0~$1.split '';
            my $check = $2;
            return ([+] @digits.reverse
               >>*<<
               (1..@digits)) % 10 == $check;
        }
        return Bool::False;
    }

    This does the same thing as above. Or to put it in English, we take our digits, reverse them, and then multiply each digit (hyperoperator, >>*<<) by the respective integer in the other list, that is, 1 to the size of the list. We then sum (reduce, [+]) that new list, and get the modulus 10 of it.

    Very elegant, no?

    Update: Turns out there is also a very elegant version in p5, according to mst. Check it out!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    sub cas_old {
      use List::Util 'sum';
      my $cas = shift;
      if ($cas =~ /(\d{1,8})-(\d\d)-(\d)/) {
        my @digits = split(//, $1.$2);
        my $count = @digits;
        my $check = $3;
        return (sum map $_ * $digits[-$_],
           1 .. $count) % 10 == $check;
      }
      return;
    }

    It’s very similar to the p6 version, just using fewer generalized operators, so you should be able to follow it fairly well.

  • 0 Comments
  • Filed under: perl
  • Dallas.p6m: May 2009

    We had the second Dallas.p6m on May 12, 2009. Along with me there were two of my coworkers, s1n, Graham Barr, and Patrick Michaud. We discussed a lot of things. One of which was the difference between subs and methods in Perl6. And the fact that you can’t imply self. This should explain it:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    class A {

       sub foo {
          say 'foo';
       }

       method bar($o:) {

          # much to s1n's chagrin, you can't
          # have baz() imply self.baz.  These
          # are his options

          say 'bar';
          self.baz;
          $o.baz;

          # great for when you have a lot
          # of object methods close by

          given self { .baz; }

          # this is the same as above but it's
          # not scoped.  Good for short methods

          $_ = self;
          .baz;
         
          # not really recommended as it
          # doesn't seem to be for anything
          # but attributes.
          $.baz;
       }

       method baz {
          say 'baz';
       }
    }

    my $a = A.new;
    A::foo;
    #A::bar; # dies

    #$a.foo; # dies
    $a.bar;
    A.bar;
    # note: there may be a distinction between
    # class and instance methods, but for now
    # you use the same method for both

    I also asked Patrick if he thought that Perl 5 in Perl 6 would really happen and if so how. He said it would happen, but probably not soon. There are really three options. The first is to embed Perl 5 in Parrot. This is really the “best” option as it would have 100% compatibility (except weird XS stuff,) and I think Patrick said that it had been prototyped, so that’s encouraging. The next option would be to reimplement most of Perl 5 in Perl 6. This would never get close to 100% but it would still be an option. The last option would be to have major parts of CPAN reimplemented in Perl 6, thus making compatibility far less important. Important CPAN modules would be DBI, a good templating system, a web framework (in progress), and some form of GUI toolkit.

    Somehow we got into a discussion about Mojo, the framework Graham uses at $work. It is modeled after Rails and is supposed to be simple to port to Perl 6. The most important thing about it, as far as I can tell, is that it has no dependencies. Graham made it sound like a lightweight framework, but I guess he just meant the no deps thing. CGI-Application (what I use) totals to 7k lines. Mojo, on the other hand, totals to 50k. Not exactly lightweight, but low dependencies is an interesting goal.

    And then two thirds of us are going to YAPC::NA, so we talked about that some. Very exciting things coming up!

  • 0 Comments
  • Filed under: perl
  • Perl6 Excitement

    “I estimate that Rakudo starts up nearly 40% faster now than it did when I started on Sunday night. We can get it faster yet.” –chromatic

  • 2 Comments
  • Filed under: perl
  • Git Workflow for Rakudo

    I just posted a workflow for Git on the Rakudo Wiki. Hopefully it works well and helps people use Git and work on Rakudo. Enjoy!

  • 0 Comments
  • Filed under: Uncategorized
  • Ghetto: Your Solution for Workarounds™

    I like to make playlists. But I also reorganize my music something like once or twice a year. Because of that my playlists get broken as they are really just lists of filenames. This past summer I wrote some code in ruby that would find files with the same basename but ignore the directory structure, and reconstruct playlists from that. It worked perfectly except every now and then I would get a live version or two. This works because I have an sqlite database of all of my music thanks to amaroK.

    Well, I decided that I would update the script so that I wouldn’t have those issues with live versions. I decided that I would have an intermediate filetype, which I would basically keep around forever. Announcing the FRU media playlist filetype! Actually not that exciting. Anyway, here are a couple scripts:

    m3u2fru.pl6:

    fru2m3u.pl6:

    But the more important part, is the Ghetto module. Currently rakudo does not have any way to get the output of a command, but it can read from files, so we can fake it:

    Obviously this is slow, bad in that it could possibly overwrite files, etc. It’s ghetto. But the idea is that later when we actually can do something like this without a ghetto solution it won’t be hard to fix your code.

    I also thought it was fun to do a pipe-based solution. The way I had it set up before was something like this:

    1
    ./plup.rb old.m3u new.m3u

    That’s alright, but I would usually look at the output to make sure it was right. Now I do this:

    1
    cat old.m3u | ./m3u2fru.pl6 | ./fru2m3u.pl6 > new.m3u

    Sure it’s longer, but I can easily see the output at any point in the process. Furthermore, since I am using zsh (maybe bash can do this too, not sure) I can do this:

    1
    cat old.m3u | ./m3u2fru.pl6 >new.fru | ./fru2m3u.pl6 > new.m3u

    So I can keep the intermediate results for next time!

  • 0 Comments
  • Filed under: Uncategorized
  • Apparently Patrick Michaud, pumpking of rakudo, read my post yesterday and he came up with an even better solition!

    I’d read his post if I were you, but here was the code he got it down to (after adding the R meta op :-) ):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        my %op_dispatch_table = {
            '+'    => { .push(.pop + .pop)  },
            '-'    => { .push(.pop R- .pop) },
            '*'    => { .push(.pop * .pop)  },
            '/'    => { .push(.pop R/ .pop) },
            'sqrt' => { .push(.pop.sqrt)    },
        };
     
        sub evaluate (%odt, $expr) {
            my @stack;
            my @tokens = $expr.split(/\s+/);
            for @tokens {
                when /\d+/     { @stack.push($_); }
                when ?%odt{$_} { %odt{$_}(@stack); }
                default        { die "Unrecognized token '$_'; aborting"; }
            }
            @stack.pop;
        }
     
        say "Result: { evaluate(%op_dispatch_table, @*ARGS[0]) }";

    Brilliant!

  • 2 Comments
  • Filed under: Uncategorized
  • Making Rakudo more interactive

    This doesn’t really make rakudo interactive, it just gives you history, but that’s pretty nice!

    1
    ledit ./perl6

    ledit is in apt, so if you have ubuntu you can just install it with sudo aptitude install ledit. Very nice!

  • 1 Comment
  • Filed under: Uncategorized