プログラミングの魔導書 最遅レビュー

http://longgate.co.jp/products.html

今更だけど,実はこんな書籍が発売していました.レビューをするする詐欺をしていて,発売1分前に記事をあげようと思ったら,なんと下宿先のネットワークがメンテナンス不足でネットに繋げなかったという状態で,まぁ言い訳なんですけど,とりあえずレビューです.

  • すっぽすっぽ先生へのインタビュー

多分これが一番ネタになるんじゃないかなと思います.というのもいくつかの言語に触っている人からすると,こういう読み物的なものの方が楽しめたりするような?俺もWalterへのインタビュー記事とか読みたいです(チラッ

  • boost::serialization

我らがOrangeの元になったライブラリです(多分).でも正直言語特有になっちゃってるので,実際は使うシーンが少なかったりもしますが,ちょっとしたものを書く時には便利です.後編で深い話が読めるのを楽しみにしています!

  • Chronoの型システム

Andreiが「Phobosにもこんなの欲しいから誰かコントリビュートして!」みたいなこと以前MLで書いてた気が.Phobosのコミッタになるチャンスですよ!

  • Variadic Template

なんで今までなかったのかと言うやつですね.使ったことない人はこの記事で基本を眺めることが出来ます.でもD言語使うともっと便利です.

  • オーブンレンジクッキング

std.rangeププッみたいになっちゃってますね.誰かOven RangeをPhobosに移植しませんか?

  • Hello,C++ World!

C++の変態っぷりが分かります.D言語ならwritefln("Hello, D World!");でなんのひねりもありません.D言語の素直さが分かりますね.

  • Crawling in the Stream

実は今Phobos向けのストリームに関して色々議論中なので,正直ビンゴな記事でした.iostreamの設計が知れてためになりました.

D言語ならこんな複雑なことしなくても,となるのですがそれを除いても勉強になります.しかし初見では頭がついていきませんでした.

  • Boost.Asio

Asioいいですよね.今Phobosのstd.socketのリプレースを考えていて,Asioさんは参考にさせてもらってたりします.コードも参考になるので,これを機に皆さんAsioを使いましょう.

STL周りとかtemplate周りはためになりました.以前Andreiの某D言語の記事を翻訳した時?だった所がこれによって解決したという.人生何が起こるかわかりません.

  • BoostCon2010体験記

お金が…

ということで,これだけ方向性がバラバラな記事が集まっていれば,何かしらためになることはあると思うので,皆さんPDF版をちゃんと買いましょう.次は俺がD言語の記事を寄(ry

ファンクタとD言語とdmd

Effective STLを読んで,ファンクタの方が速いよ!みたいな記述があったのでD言語で試してみたら,なんか普通に遅かった.そもそもクロージャとかリテラルで書けるD言語にはファンクタなんかいらないというわけですよ!
以下ソース.

import std.stdio, std.date;

void for_each(T, F)(ref T[] lhs, ref T[] rhs, F func)
{
    foreach (e; lhs)
        rhs ~= func(e);
}

struct Plus(int num)
{
    int opCall(int v)
    {
        return v + num;
    }
}

int plus(int num)(int v)
{
    return v + num;
}

void main()
{
    enum N = 10000;

    void test1()
    {
        int[] a = [1, 2, 3], b;

        foreach (i; 0..N)
            for_each(a, b, &plus!10);

        delete b;
    }

    void test2()
    {
        Plus!(10) p;
        int[] a = [1, 2, 3], b;

        foreach (i; 0..N)
            for_each(a, b, p);

        delete b;
    }

    void test3()
    {
        int[] a = [1, 2, 3], b;

        foreach (i; 0..N)
            for_each(a, b, (int v) { return v + 10; });

        delete b;
    }

    //auto r = benchmark!(test1)(1000);
    //auto r = benchmark!(test2)(1000);
    //auto r = benchmark!(test3)(1000);
    //writeln(r);
}

test2のファンクタでpを直接渡してないのは,そういうコードが書けないから.これからもD言語にはファンクタなんかいらないことがわかる(違

Homebrew

http://mxcl.github.com/homebrew/
Twitterで使っている人がいて,今日研究室にMBPが来たのでMacPortsからこっちに乗り換えてみた.まだ数が少ないとはいえ,俺が欲しいパッケージ群は揃っているし軽量だしで,今度からはこれで行くことにした.

注意点

MacPortsとかと違って全部自力で入れるんじゃなくて,使えるものは環境から,というスタイルなんだけど,Mercurialはなんかそうじゃなかった.

% brew install python
% brew install pip
% pip install mercurial

っとやってとりあえずインストール.pipはpythonでのパッケージ管理みたいなもので(なぜかhomebrewのpythonを要求する),そこにMercurialが入るので,/usr/local/binからシンボリックリンクを手動で貼ってやらないと行けない.この辺改善されるのだろうか…

花札シャッフル

この問題を解くことがあったんだけど,その時はRubyで非常にあれなコードだったので,とりあえずD言語で書き直してみた.やっぱりRubyの方がすっきり書けるというか,std.range周りが色々と融通が効かなくてあばば.Rubyの配列のように扱えるeagerな処理も欲しいなぁ…

// Written in the D programming language.

/**
 * Hanafuda shuffle
 *
 * See_Also:
 *  http://www.ehime-u.ac.jp/ICPC/problems/domestic/d2004/A.jp/A.html
 */

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;


alias Tuple!(uint, "first", uint, "second") Pair;


/**
 * Parses formatted input.
 */
Pair parseInput()
{
    auto parsed = map!"to!uint(a)"(readln().split());

    Pair result;

    result.first  = parsed.front; parsed.popFront();
    result.second = parsed.front;

    return result;
}


/**
 * Shuffles hanafuda set.
 */
void shuffle(ref uint[] set)
{
    auto input = parseInput();
    auto point = set.length - input.first + 1;
    auto lower = point - input.second;
    auto pSet  = set[point..$].dup;
    auto cSet  = set[lower..point].dup;

    set[lower..$ - input.second] = pSet;
    set[$ - input.second..$]     = cSet;
}


void main()
{
    while (true) {
        auto input = parseInput();

        if (input.first == 0 && input.second == 0)
            break;

        auto set = array(iota(1, input.first + 1));

        foreach (Unused; 0..input.second)
            shuffle(set);

        writeln(set.back);
    }
}

デストラクタと静的デストラクタ

今std.socketの改善を試みているのだけど,それで嵌ったところ.これのshared static ~this()のGC.collect()をコメントアウトすると,同じWindowsでもErrorが飛んだり飛ばなかったりする.

shared static ~this()
{
    // Avoids FinalizeError. D's GC may call the destructor of objects after static destructors.
    GC.collect();  // ここ

    version(Win32)
    {
        WSACleanup();
    }
}

原因はGCの呼ばれるタイミングが不定なことで,WSACleanupを呼んだ後これに依存している関数をオブジェクトのデストラクタが呼んでしまい,エラーになっていたというオチ.よくよく考えると静的デストラクタでもオブジェクトを操作することは可能なので,なんとなくデストラクタが先に呼ばれると思ってたけど,動作としてはおかしくないかもと思える.ということで,静的デストラクタで環境のクリーンアップとかを行う場合は,こういう点に気をつけないと再現しにくいバグの元となるので,気をつけましょう.
しかしGCに気をつけないと行けないというのも何だかなぁという感じだ.

Shibbolethがサービスになる時代

http://www.secioss.co.jp/
初めて聞いた会社なのだけど,Shibbolethを使った導入や保守などのサービスを開始したらしい.日本でShibbolethと言えば俺なわけだけど(オ,もうそこまで広まったんだなぁと思うと感慨深かったりもする.日本で情報がほとんどないため,導入しようとする人が困らないように必要そうな記事の翻訳や気をつけることを自分のWiki*1にまとめてた甲斐があったのかなぁと.
誤解を招きそうな記述に突っ込みたい所もあるけど,これから頑張って欲しい所.

フェデレーションを構築することにより、クロスドメインシングルサインオンやアクセス制御を行うことができます。

http://www.secioss.co.jp/2010/06/shibboleth.html

んん?

フェデレーションを構築することにより,クロスドメインSSOやアクセス制御を行うことが出来る.

http://wiki.livedoor.jp/repeatedly/d/Shibboleth

気のせいでした.

GenericList(of Class) から一定条件の要素を取り除く

コレクションがないのでこんな感じで.filterの返り値がなぁ…

import std.algorithm, std.stdio;

class Cat
{
  private:
    string name_, type_;

  public:
    this(string name, string type)
    {
        name_ = name;
        type_ = type;
    }

    @safe @property nothrow
    {
        string name() { return name_; }
        void name(string name) { name_ = name; }
    }

    @safe @property nothrow
    {
        string type() { return type_; }
        void type(string type) { type_ = type; }
    }
}

void main()
{
    Cat[] nyans = [
        new Cat("しゅうたん", "アメショ" ),
        new Cat("ろり", "アメショ"),
        new Cat("みずきちゃん", "スコティ"),
        new Cat("マグさん", "ほげ")
    ];

    foreach (nyan; filter!q{a.type != "ほげ"}(nyans))
        writeln(nyan.name, "は", nyan.type);
}