その言語の特徴やメソッドチェーンする対象によって傾向があると思います。
自分自身を変化させるような場合はmutableなオブジェクト、自分自身は変化させずにそのままにする場合はimmutableなオブジェクトと言ったりします。この用語に合わせてmutableなメソッドチェーン、immutabelなメソッドチェーンとして説明します。なお、mutabelなオブジェクトには両方あり得ますが、immutableなオブジェクトはimmutableなメソッドしかありません。
###メリットとデメリット
メリットとデメリットをまずは見ていきましょう。
####mutableなメソッドチェーン
利点
- オブジェクトの生成が無いため、速い
- メモリの消費量が少ない
- メモリ管理が不要
欠点
- 副作用があるため、何をしているかを把握しないと危険
####immutableなメソッドチェーン
利点
- レシーバを変更されるといった副作用が無いため、安全
欠点
- オブジェクトを逐一生成するため、遅い
- 途中に作成されたオブジェクトの分だけメモリが消費されていく
- メモリ管理が複雑になるため、GCが無いと難しい
上を見るとわかるように対比になっています。基本的には、「パフォーマンス」を取るか、「安全性」を取るかです。また、GCが無い言語でimmutableなメソッドチェーンを作るには工夫がいります。途中でメモリの動的確保により生成したオブジェクトがある場合、そのままではメモリ解放することができなくなってしまうからです。
###どのような場合に多いのか
上を踏まえて、対象となるオブジェクトや言語によって傾向があります。(言語は偏っていますし、私感です)
####mutableなメソッドチェーン
- IOオブジェクト … 読み込みや書き込みは必ず副作用を伴う物ですので、レシーバは必ず変更されます。そのため、わざわざ新しいIOオブジェクトを作るメリットがありません。C++のstd::iostream、RubyのIO等。
- C++ … GCがないためimmutableで作ること自体が難しいです。また、C++では安全性よりパフォーマンスを重視しており、使用する人もいかに速くできるかに関心があります。遅いimmutableは敬遠される傾向になります。
- 昔のJava … 昔のJavaは全体的に遅いと言うこともあり、速くできるところは速く使用としていた傾向があります。
####immutableなメソッドチェーン
- ストリーム(リスト)オブジェクト … 関数型で見られるような処理ができるパターンです。ストリーム(リスト)を抽出、射影、並び替えなどを次々行います。JavaのStream、C#のLINQ、RubyのEnumerable等。
- 今のJava … 最近のJavaに追加されたクラスはimmutableな場合が多い傾向にあります。パフォーマンスもよくなったため、速度よりも安全を取るという選択です。
- Ruby … Rubyのオブジェクト自体はmutableなものが多いですが、ほとんどの場合で、新たに生成したオブジェクトを返すメソッドが用意されています。それらとは違い、副作用を伴うメソッドは破壊的メソッドとよんでなるべく区別できるようにしています。それら破壊的メソッドはnilを返す事もあるようにして、わざとメソッドチェーンをしにくくしています。自然と破壊的メソッドではないimmutableなメソッドチェーンを使うように洗脳する恐ろしい言語です。
###まとめ
昔はマシンも貧弱であり、パフォーマンスが重視されていたため、mutableな傾向が強かったと思います。しかし、近年は、マシン速度が向上し、関数型プログラミングの流行に伴い、immutableな実装が主流ではないかと思います。速度と安全は二律背反であり、どちらがか正解という物ではありません。用途や目的などに合わせて選ぶと良いかと思います。
2016/07/02 22:34
2016/07/02 22:52
2016/07/04 17:10