破壊的OOP

関数型とOOPの話の続き。ちょっと議論をしてみたのだけれども、例えばこういうプログラムを考えてみよう。

class Mover1{
  int x;
  public Mover(int x){
    this.x = x;
  }
  public void move(){
    this.x++;
  }
  public int getX(){
    return this.x;
  }
}

さて、このコードを二つの方針で書き直してみる。

class Mover2{
  int x;
  public Mover(int x){
    this.x = x;
  }
  public Mover2 move(){
    this.x++;
    return this;
  }
  public int getX(){
    return this.x;
  }
}
class Mover3{
  int x;
  public Mover(int x){
    this.x = x;
  }
  public Mover3 move(){
    return new Mover3(this.x + 1);
  }
  public int getX(){
    return this.x;
  }
}

さて、なぜこのmoveメソッドをvoidからMoverに変更したのかと言えば、これによって、

Mover m = new Mover(1);
m.move().move().getX();

のように扱えるようになる。このほうが少なくとも便利だよね、という話がまずある。
次に、この二つのクラス、Mover2とMover3のどちらがbetterかという話もしなくてはならない。というか、こっちがメイン。で、例えばJavaであればMover2もMover3も可能だが、破壊的代入をしなければ、Mover2を使うことはできない。すなわち、関数型スタイルであればMover2はなるべく使わないと言う方針になる。どちらが良いのだろうか。
議論の対象となるのは3種類ある。一つ目は設計者としての視点。二つ目はこのクラスを使う側の視点。そして最後に、このクラスを作る側の視点だ。
まず設計者の視点としては、基本的にMover3を使うと言うスタンスを取れば、もしも何らかの事情(オーダーやそのクラス自体の特性)で内部状態を破壊的に持っていなくてはならないという場合にのみ特別にそのクラスを破壊的代入可能クラスとして定義してやり、基本的にはimmutableとしてやるという方針を取ることが出来る。これは、Mover2にするべきかMover3にするべきかという問題を考える手間を、回避することができる。良いsolutionだと思う。
では、使用者としてはどうだろうか。使用者としては、なるべく

Mover m = new Mover(1);
Mover next_m = m.move();

と形式でコーディングすることを心がけるのが良いのでは無いだろうか。これにより、使用者は、内部実装がどちらであっても良いというコーディングとなる。
最後に、クラスを作る側の視点だ。クラスを作る側としては、mutableな方が作りやすい。これは間違いが無い事実だ。あるいはnewをしないことによって動作のコストを抑えることができるだろう。また、内部状態として持っているフィールドを全てコンストラクタで渡せるようにしなくてはならない。そのコンストラクタの一部はprivate指定をしておく必要があるかもしれない。めんどくさい。
全体として、破壊的代入をしない方針と言うのは、一部の作りにくさを犠牲にして、バグを少なくすることを目的としているらしい、と言うことになる。で、OOPをする場合に、その作りにくさ、めんどくささは本当に有利に働くのかなあと言う気は依然としてある。

YAPC::1日目::感想

今更感はあるのですが、とりあえず昼休みにネットにつながるので取り急ぎ昨日の分からまとめてみます。

Pugs系の話

基本的にはAudreyのIntroduction to Pugsなんだけれども、これには遅刻してきちんと聞けていないという致命的ミス。Pugs自体は非常に面白いものなんだけれど・・・

Perl5関連

Module::CompileとかPerl Best Practiceとか。Module::Compileの実装自体は気持ち悪いということはよくわかった。何その拡張子がpmcって。
Perl Best Practiceについては、非常に勉強になった。基本は、正しいコーディングを続けよう、ということ。そのために手を抜くことはあってはならない。これは、Perlに限らない話だし、あるいはPerl5のような言語だと特に気をつける必要があるだろう。

web関連

mightyvとかPlaggerとかmixiとかそういう話。テクニック的な問題の解説とか。かなり具体的な技術の話であったりとか。

Ruby関連

ノーコメント

総括

まあ、Pugsの話はやっぱり興味がありますね。

進捗

さて、CPUのほうですが、行き詰った感がありますな。大して変更をしていないのに、偶に結果が明らかにおかしくなることがあったりするので調べてみると、どうやらSRAM周りらしい。かといってSRAMが悪いとしても、毎回必ず同じ形でバグっていると言うのは考えにくいし、それにしてはバグりかたが綺麗なので、それ以外に問題はあるようだ。
FPUに問題があるかという話もあったのだけれども、基本的に問題はなさげ。一点だけというバグならまだしも、やっぱり綺麗にオブジェクトが消えていたりするのはFPUなのか?という感じがしている。
そうなると、だんだん疑う部分が無くなって来るのだけれど・・・・
制御でバグがある場合は、もう少し違う形になるだろうし、RS232Cでのバグという感じでもない。じゃあ、どこが悪いんだろう・・・

YAPC::二日目::感想

よく考えたら、タイトルのネーミングはYAPC::感想::二日目の方が良さげ。変えないけれど。
さて、今日は午前中(とはいっても10時半くらいからだけれど)は2階に。午後は4回に移動して、最後にまた2階に戻ると言う感じ。感想は、全て書くのは大変なのでちょっとだけ。

Perl6 Update(Damian Conway)

とりわけて新しいことは無かったような気はする。何でもできすぎるPerl6だけれども、やっぱり遅いんだろうなあ・・・・

Learning Haskell(Audrey Tang)

型理論とかそのあたりは、知識もあったしスライドも日本語訳されているので、英語でも全然分かった。というか、Lightning Talkもそうだけれども、Audreyの英語はものすごく聞き取りやすい。Lightning Talkは、休まずに話し続けていたけれども、てっきり英1のリスニングのテープを聴いているかというくらいの錯覚に陥った。

Keynote(Larry Wall)

Larryの話を存分に聞けるセッションは、やっぱり良い。素晴らしい。特に技術的な話は一切無くて、その精神と言うものに触れると言うのは良い。結局Perlってそういうものだよね、と思わせてもらえた。

総括

やっぱり英語って言うのは辛いものがあって、実際の話自体には通訳がほとんどつかないというのに苦労した。一応ゆっくりしゃべってくれているんだろうけれども・・・
後、メガネを忘れてしまったせいで、スライドの文字が読めない部分があったりして。高橋メソッドのものは、非常に助かった。
Pla君とともに行くことにしていたので今回はボランティアとか出来なかったですが、事前に言っていただければ今度はお手伝いをやらせていただきます。それ以外にも今回はCPU実験が終わっていないと言う問題もあってゆっくり出来ず、懇親会にもいけなかったとかいろいろと余裕の無さから十分に楽しむ準備が出来ていなかったというのが残念で仕方が無いなあ。それでも楽しむことが出来たのは、ひとえにプレゼンターや、スタッフ、ボランティアの方々のおかげだと思います。ありがとうございました。