most general object

「なんか目の周りが老けたねえ」と言われた.「てめーのせいだよ!」と言い返せないチキンです.


ふと気になって,C++のTemplateについて調べてみた.

条件によっては実行されないコードがあるときに,そのコードに記述されているメソッドが実装されている必要があるかないのか,急に不安になったのだ.こういうのは仕様を読むよりも,実際に試した方が早い.

#include <cstdio>

using namespace std;

template <typename T>
void func(T &t)
{
  if (t.hoge()) {
    t.huga();
  }
}


class Class1 {
public:
  bool hoge() {
    return true;
  }
  void huga() {
    puts("huga");
  }
};

class Class2 {
public:
  bool hoge() {
    return false;
  }
};


int _tmain(int argc, _TCHAR* argv[])
{
  Class1 c1;
  Class2 c2;

  func(c1);
  func(c2);

  return 0;
}

さて,このときfunc(c2)はOKなんだろうか.

T.hogeの値で処理が変わるため,T.hugaは実際には呼び出されないことがある.コンパイルできても良いような気もする.


結果は×だった.

まあ,実際にこういうのに手を出し始めると,gotoとかは対処しきれないだろうから,こういう実装もありかもしれない.また,コンパイルすることを考えると,C++のセマンティクスではこういうのはhogeもhugaも実装していないといかないというのも,納得できる結論だ.*1

さて,Rubyでどうするか.


別の話だが,C++のTemplateは良くできている.「とどのつまりマクロ」という性質もあって,大変に直感的でわかりやすい.少なくともGeneric Programmingという観点からは.エラーメッセージも,VC7(VS2003)のは「'huga' : 'Class2'のメンバではありません」と出てわかりやすかった.

こうしてみると,C#Genericsの実装は,手抜き以外の何者でも無いような気がする..NETのCLIが変な縛りをかけているのかもしれないけれども.



パーサを書く.ごりごり書く.ocamlyaccすると16 shift reduce conflictsとか出るが,気にしないで書く.書き始めてしまえば,なんのことはない.サクサク*2進められる.もちろん,なんのことはないようにたっぷり時間を使って,いろいろ工夫したからだけど.

しかし,この追い詰められないと手を付けられない性格はなんとかしないと.そのうち,本当に困りそうだ.いや,今でも困ってるんだけど(←単位が足りない).

3分考えて3時間かかって問題を解くよりも,30分考えて30分で問題を解け,とは良く言ったものだ.しかし,僕の場合は3時間考えて30分で問題を解く様な感じか.結局かわんないし.しかも,その3時間のうち,少なくとも最後の2時間くらいは面倒くさがってるだけで,無駄な気がする.


困ったものだ.


OCamlMakefileで,

FIXTURE = ...
TEST = ...

RESULT = ...
SOURCES = $(FIXTURE) $(TEST)
PACKS = OUnit

include "OCamlMakefile"

とか書けば,OUnitも適切に処理してくれることを知った.これは便利だ.


ユニットテストと結合コードをなんとか上手く管理するMakefileの書き方はないものだろうか.Makefileを二つ用意すれば,簡単にできそうだけど.そうするとFIXTUREを二回書くことになってしまって嫌だしなあ.includeするという方法もあるけど,たかがMakefileが3つもできるのもなあ.

OCamlMakefileをハックして「make test」とかを上手く処理できるようにするというのが,一番正攻法だと思うけれども,それは面倒くさい気がする.なるほどこうしてバッドノウハウは生まれていくのか・・・(本当かよ)


まあ,この辺はリリースできるようなコードになってから考え直そう.


shift reduce conflictは全て潰した!

リファクタリングしてると,α変換とか自動でやってくれるマクロが欲しくなる.コンストラクタの引数をごにょごにょ変えたりするのも.javaとかC#とかのメジャーな言語だと,メジャーな開発環境が対応してくれているが,OCamlはマイナーなので,なかなかそうはいかない.

あうー


もう,鬼のように頼りきってるRubyソースコード完全解説だが,読書会のログを見るとやけにHaskellの話題が多いのが気になる.すげー面白そうだ.

*1:ていうか,こんなんC++のTemplateのメカニズムを考えれば,自明だな・・・もうちょっと考えてれば,試す必要もなかったか

*2:おお!sakusakuにリンクされた!