Rakudo * でクイックソート

Rakudo * リリース

http://rakudo.org/announce/rakudo-star/2010.07

 去る7月29日に、"実用的な" Perl 6 の処理系である Rakudo * (Rakudo Star) がリリースされた。上記記事にもあるように、 Rakudo * はこれまでに公開された Perl 6 の処理系の中で、最も多くの仕様を実装している。しかし、まだまだいくつもの実装されていない仕様があり、これらについては今後実装しながら月に1回程度のペースでこまめにリリースする予定のようだ。次のリリース予定は8月24日となっている。

Rakudo * のインストール

 なにはともあれ、まずはインストール。http://github.com/rakudo/star/downloadsにデータがあるのでダウンロードする。 Windows ユーザは rakudo-star.2010.07.msi を、 Unix/Linux ユーザは rakudo-star.2010.07.tar.gz を。

 Windows へのインストールは容易だ。 rakudo-star.2010.07.msi を実行するだけ。 C:\Rakudo に必要なものがインストールされる。 C:\Rakudo\bin\perl6.exe をたたけば Perl 6 のコードを実行できる。

 Unix/Linux へのインストールは、 rakudo-star.2010.07.tar.gz を解凍して、中にある README に書かれている通りに実行すれば良い。

$ perl Configure.pl --gen-parrot
$ make
$ make install

Rakudo * でクイックソート

 せっかくインストールしたのだから、遊ばない手はない。「最初のプログラムは "Hello World!" ではなく、クイックソートにすべき」というid:pi8027の主張にしたがって、 Perl 6 でクイックソートを実装してみた。

#!/usr/bin/perl
use v6;

say quicksort(@*ARGS);

multi sub quicksort (@a where {+@a <= 1}) { @a }
multi sub quicksort (@a) {
    my $p = @a.shift;
    my @l, my @r;
    for @a -> $e {
        $e <= $p ?? @l.push($e) !! @r.push($e);
    }
    quicksort(@l) ~ $p ~ quicksort(@r);
}

(コードを gist.github にもあげてみた)
https://gist.github.com/0542862e4c53e6c7af50

 実行すると以下のように動く。

$ perl6 quicksort.pl 2 7 4 9 3
23479

コードの解説

 Perl 6 で新しいところ、変わったところをメインに説明する(Perl 5.10 や 5.12 にも入っているものもあるかも)。

バージョン指定
use v6;

 use v6; で実行する環境を Perl 6 の処理系に束縛できる。 Perl 5 系で実行すると以下のようなエラーが出力される。

$ perl quicksort.pl 2 7 4 9 3
Perl v6.0.0 required--this is only v5.8.9, stopped at quicksort.pl line 2.
BEGIN failed--compilation aborted at quicksort.pl line 2.
改行つき標準出力
say quicksort(@*ARGS);

 従来の print はそのまま使えるが、 Perl 6 では say を用いることで末尾に改行を付加してくれる。

配列の要素数取得
+@a <= 1

 従来は配列をスカラに代入することで取得できた。 Perl 6 では、 @array.elems() もしくは +@array で取得できる。

引数の値の束縛
sub quicksort (@a where {+@a <= 1}) { @a }

 where を用いることで引数の値が条件を満たすときのみ関数を呼ぶように制限できる。上記のコードならば、 @a の要素数が 1 以下ならば関数が呼ばれる。そうでなければ、以下のようなエラーが出力される。

$ perl6 testp6.pl
Constraint type check failed for parameter '@a'
  in 'test' at line 6:testp6.pl
  in main program body at line 4:testp6.pl
マルチディスパッチ(オーバーロード)
multi sub quicksort (@a where {+@a <= 1}) { @a }
multi sub quicksort (@a) {

 multi を用いることで同名の関数を複数定義できる。上記コードでは、 @a の要素数が 1 以下ならば上の quicksort が、そうでなければ下の quicksort が呼ばれる。

for の書き方
    for @a -> $e {

 配列の各要素に対する処理は上記コードのように記述する。 -> の右側は 2 つ以上でも可。 foreach は廃止された。また、 (初期処理;継続条件;継続時処理) というループは for ではなく loop を用いる。

三項演算子
        $e <= $p ?? @l.push($e) !! @r.push($e);

 従来は ? と : だったものが、 ?? と !! に変わっただけ。

文字列連結
    quicksort(@l) ~ $p ~ quicksort(@r);

 従来は . だったものが、 ~ に変わっただけ。

以上

 クイックソートを例に Perl 6 の新しい文法などを軽く説明した。他にもスマートマッチ(Perl 5.10くらいから使えるらしい)や複数行コメント、 whatever star など魅力的な機能はたくさんある。引き続き Rakudo * で遊んでいきたい。速度などの問題が残っているので、実用はまだ少し先になりそうだ。