alias 引数の template

最近 D を追い切れてなかったのでどっかで騒いでたかもしれませんが、私に見える範囲では(要は私のアンテナにある程度)、 DMD 0.173 で導入された、「テンプレートのalias引数として、ローカル変数やネスト関数が指定可能になりました。」って変更はそんなに注目されてないような。

http://www.kmonos.net/alang/d/changelog.html#new0173

これはものごっつ便利だと思うわけですが。例えば

class TestEnumerable {
    int[] array;
}

みたいなクラス書いて、あー array を foreach でぶん回せるようにしたいなー、でも opApply って書くのめんどいよなー、なんて問題を、

mixin Enumerable!(array);

の一言で解決できるライブラリが作れるわけでして。以下みたいな感じ。

import std.stdio;

template Enumerable(alias A) {
    alias typeof(A[0]) Elem;

    int opApply(int delegate(inout Elem) dg) {
        int result;
        foreach (e; A) {
            result = dg(e);
            if (result) break;
        }
        return result;
    }

    Elem opIndex(int i) {
        return A[i];
    }
}

class TestEnumerable {
    int[] array;
    mixin Enumerable!(array);

    this(int[] a) { array = a; }
}

void main() {
    int[] a = [1, 2, 3];
    TestEnumerable te = new TestEnumerable(a);
    foreach (e; te) {
        writefln("%d", e);
    }
}

Enumerable って名前が不適切すぎるとか、メンバが足りなさすぎるとかはまた今度。

あれ?今見ると、 "alias parameters for local variables and nested functions." なんですね。実はもともとできた?まぁどっちでもいいか。

あとこれは以下で話題にあがってましたが、もちろん tupleof もヤバいですよね。

http://d.hatena.ne.jp/rinset/20061117/1163777788

これって要するに、

class Hoge {
    mixin Serializable;
}

シリアライズ可能なオブジェクトを作ることがたぶん可能なわけでして。私は mixin HasTostring みたいなのを作って使ってみています。これを素でできる静的型付けの言語って Haskell の deriving Show くらいしか知らないわけですが。

最近の D は最初に見始めた時に期待してたよりも、はるかに面白いことになっててすごいなぁ、と思っています。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h