つれづれ

その427 (Webでいろいろ書き始めて11年目になります)

最近なんとなく思う「老いると言うこと」

経験したり、思考したりしたことに対して、圧倒的に出力が追いつかないもどかしさというか。

出力しようとするエネルギーや持続力の不足なのか、そもそも出力が間に合わないというのが錯覚で、実は咀嚼(処理)が間に合っていないのか。

つまりは、いろいろお出かけしたり、考えたり、思ったりするのですが、blog にしたためるのがまったくもって間に合わない(更新頻度が昔の方が早かった)ということなのです。

その428 (パシフィック・リム

パシフィック・リムみてまいりましたぞ!

見る前は、ハリウッドな先入観から、SFロボットクリーチャーアクションのようなものかな、と思っていたのです。ロボットものエッセンスが強い感じのものですね。

が、みてみれば、想像以上に怪獣映画でびっくり。これは SFX じゃなくって「特撮」だぁ、とゾクゾクゾクッとしてしまいました。どことなく漂うB級臭がたまりません。特撮好きには超お奨め!見ながら思った感想は「なんでお正月公開じゃないの!?」というものってくらい、怪獣映画でしたよ。

カイジュウは、本当に怪獣で、おそらく全部CGI だと思うのだけれど、まるで人が入っている着ぐるみみたいで、そのデザインの特徴といい、真に怪獣だったのです。これはハリウットの文化、というか文法とちがうもので、文化の伝搬を感じたり。一方で、主人公のロボや軍やヒーローが危機に立ち向かうという構図は、まさにハリウッド映画な文法で、ここらへんの融合は「あんパン」的で、なかなかおいしいものだなぁと。

内容はいろいろ詰め込んでいて、もうすこし続編を作る勝算のある映画だったら、もっとじっくりいろいろ物語を書き込めたのかな、と思います。日本おお正月映画ってことで、1,2,3 くらいでやってくれればとかとか。でもそれでも十分面白い。

と、同時に、日本の怪獣映画が、このようなスタンスになれなかったのがとても残念におもえました。

この映画をみて一番感動したのが、わたしには、日本の特撮の文化というかミームというか、コミュニティをコミュニティたらしめる大事な者が確かにそこにあったように思えたこと。

今後、このままいけば、日本はかつてのアメリカの「コミックコード」と同じ過ちにより、文化を衰退させていくことでしょうが、衰退してしまっても、わたしたちが好むこの文化を伝承して発展させてくれる人たちが、日本の外にもあるという安心感。

怪獣映画好きにはお奨めですよ。

その429

ところで、パシフィック・リムの基地のコンソールの部品として

があったような気がするのですが。

その430

referential transparency の 訳語について。「参照透過性」 と 「参照透明性」がありますが、個人的には「参照透明性」の方が好きですが、世の中としては「参照透過性」の方が一般的。

でも、「すごいHaskellたのしく学ぼう」だと「参照透明性」になっているので、満足です。

その431

http://tech-sketch.jp/2013/08/parallel-functional-programming-1.htmlさんの解説。

http://tech-sketch.jp/2013/08/parallel-functional-programming-1.html

分岐と繰り返しと逐次処理を駆使して命令文を実行する「手続き型(オブジェクト指向)プログラミング」のスタイルとは、問題解決へのアプローチが全く異なるのです。

OOPは手続きパラダイムってことになっていて、それはどうなのかという話と、「関数が第一級オブジェクトになっている!凄い!」的なあたりが、3,40年くらい周回遅れで これだから Java は...とか思ってしまうわたしが居ます。*1

ちょっと前の、総称がついたときの「これからは オブジェクト指向 じゃなくってジェネリクス指向」を思い出させるデジャブです。

どうして Java文化圏(の一部)って、自分に出来なかったことは OOP じゃないものって言ってしまえるのかしらね。昔はもっと頻繁に「俺がガンダムオブジェクト指向だ」的なものを感じることが多かったので、なんとなく Java は嫌いでした。

その432

参照透明性についてですが、これを大事にする理由は、「副作用がないからカプセルを開けなくても動作に信頼が持てる」とか「並列やほぅ」とかではなく、より高い抽象レベルが得られることだと思います。もちろん「カプセル開けない」や「並列」も確かにメリットなのですが、なんというか、おまけというか副作用的というか、「OOのメリットは再利用性の向上」と同じような臭いを感じます。*2


参照透明性は 時間概念 を抽象の外に追い出します。これはレベルの高い抽象化なので、それだけで「みかけの複雑さを減らす」「型チェックの守備範囲の拡大する」というメリットがあります。この武器は強力だなぁ、と思います。

参照透明性の大切さを説く文脈において、よく手続きパラダイムがやり玉にあがるのは、「手続き」がずばり抽象の軸を時間概念に置いているからでしょうか。手続きは、逆立ちしてもこれを捨象しきることは出来ませんので、対比としてわかりやすいかも。

では OO は? というと、副作用の源になるかもな「値」と「関数(プロシージャ)」が、とも OOP では 「オブジェクト」になってます。副作用のないオブジェクトを作れるかというと、値としてのオブジェクトでは、これは容易です。アルゴリズムとしてのオブジェクトですと、これはコンストラクタにて与えられた情報以外を処理に使わないということになります。出来はするけど、難しいですね。

オブジェクトはコルーチンの一種であるため、たとえ「フィールド」をイミュータブルにできても、参照透明性は保証されません。複数の「コルーチン」が相互に作用し合うというモデル自体が、参照透明にやさしくなさそうです。

なので、将来 OO が淘汰されるという言には、正直そうかも、と思います。*3

ところで、我々はどうやったって時間概念の内側に住んでいるので、これを完全に捨象するのが可能かというといろいろ難しいのですが、だから「状態」とか「時間概念」とかのの捨て場所になれるモナドが素敵ということになるのかしら。

ここらへんのネタは興味はあるのですが正直 詳しくはないので、明後日のことを言ってるかも。要勉強ですね。ガンバ > わたし

その433

岩合さんの写真展が2つ同時に開催中です。ひとつは、渋谷ヒカリエ で開催中の「ねこ」。もう一つは恵比寿の東京都写真美術館で開催中の「ネコライオン」です。


片方の半券を持って行くと片方が半額になります。「ねこ」の方が25日までと、もうすぐ終わってしまうので、気になる方はお早めに。

「ねこ」の方もおもしろかったのですが、個人的には「ネコライオン」が良かったです。これは、おなじ(ような)事をしている 猫 と ライオン の組写真が 延々と続くもの。対比するからこそ見えてくる猫とライオンの類似点や相違点が大変面白い写真展でした。

「ねこ」も「ネコライオン」も同名の写真集がでています。写真集でも この対比はそれなりに楽しめますが、やはり写真展での、独立したパネルに焼かれた写真が組まれている様子でみたいと思います。

その434

一方の「ねこ」の方ですが、こちらはカップルや家族連れも多く、わいわいとした雰囲気の写真展です。かなり混みますので、じっくり写真をみるのはちょっとつらいかな。

しかしこちらの写真展は、写真一枚一枚をじっくり見るのも良いのですが、それよりは全体の雰囲気というかまわりじゅう猫に囲まれた、視界が猫にあふれかえった感じに多幸感が満たされるというのがうれしいな、と思います。

壁(セパレータ)の上空にはジャンプしている猫のタペストリが飾られ、入り組んだ写真展順路がまるで路地裏をあるいているようで、角の先に見える猫の写真に「猫との遭遇」を予感させたり、壁だけじゃなく、空間に置かれたキューブ状のオブジェに張られた猫の写真たちとか、本当に猫の国に迷い込んだよう。

本当はこの展示のしかたを含めて写真に納めてきたいところなのですが、撮影は禁止なので残念。複製をされてしまう、というのはよろしくないというのはわかるのですが、写真展とか美術展で、その全体の展示のしかたが素敵なものに出会うと、なんとも右手の人差し指が、くいっ、くいっ、と空を切ってしまうのです。

その435

カメラマニア的な視点では、写真集ではシャープでクリアに感じた写真でも、大きく引き延ばされたパネルを見ると、けっこうノイジーで細部の描写が甘いな、と感じたこと。本当に写真集の写真では気がつかなかったので、ちょっとびっくりしたと同時に、フィルム時代の写真展でも135判フィルムに対して 同じ事をよく思ったなぁ、と。

岩合さんがつかってるのは E-5 ですので、現行のオリンパスの m4/3機 はこれよりもっとクリアな絵が出てきますが、逆に言えば、135判のような使い方ですと十分すぎるということなのかしら。

蛇足ですが、もちろんノイズがのっていようが、岩合さんの写真の良さは失われないのです。

逆に、もちろん大きく引き延ばしたときの緻密な描写と薄いピントこそが、作品の良さを構成している写真もあるのです。こちらは写真集や広告でみた写真でも十分素敵とおもっていたけれども、実際のプリントをみてそのすばらしさに雲泥の差を感じてしまい、思わずため息が漏れてしまうというか。で、13万円とか値段ついてると、買って帰ろうか真剣に悩んでしまうのですよね(そして飾るスペースがないという現実の前に 財布が救われる)。

言うほど写真展に行かないわたしですので、あんまり偉そうなことは言えないのですが(^^;

でも、やっぱりモニター上でも写真集の中でもない 写真はいいものですよ。

その436

http://codeiq.hatenablog.com/entry/2013/08/07/162935

うーん。説明したいことに対して、お題のチョイスが悪いように感じます。

FizzBuzz というお題が、このような説明に致命的なまでに向いていないと思います。だから、丁寧につくられているわりに揚げ足の取りどころがいっぱいで、「揚げ足を取らないで意をくみ取ってくれる」人には有益でも、そうでない人にはなんだかなー、という印象を受けるというか。

ぶっちゃけ空気読まずに発言すれば、たかがFizzBuzzごときになんでこんな複雑なことしてるの?って思いますよね。

こういう無駄に複雑化させるプログラムが、もし本当のプログラムだとしたら、バグの温床であり、技術的負債の塊です。そもそも複雑なことをシンプルに・・というのが抽象化技術を用いる目的であって、その抽象化技術である OO を適用したらその逆になっちゃった、とか、ブラックユーモアです。

もちろん空気を読めば、FizzBuzz は出汁につかっただけで、本当は実務で出会うような規模の問題に対するアプローチの仕方を解説するのが目的だから、そこに突っ込むのは野暮ってものです。これは、本当はおっきな物の構造を、FizzBuzz サイズにミニチュアライズして、手にとっていろいろ眺めて勉強できるようにしたジオラマですから、等身大のFizzBuzz を支えるに適した構造でないのは当然のこと。

でも、だからこそ、FizzBuzz を選ぶのは、ちょっと上手くないなぁ、とも思うのです。

たとえば、


図1は、現在ある問題がどのように(どのようなオブジェクトで)構成されているのか、そのままをモデルにしたものです。
問題をソフトウェアで解決するには、問題そのものをソフトウェアで表現しなくてはなりません。ここでいきなりデザインパターンのような技法を持ち込むと、モデルを歪めてしまう可能性があります。何らかの指針をベースとしてクラスの表現に置き換えていくのが望ましいでしょう。筆者は『エリック・エヴァンスのドメイン駆動設計』の考え方を元に、次のような指針を用いています。

  • モデル駆動設計を重視する(問題空間のモデルをソフトウェアにそのまま表現すること)
  • 可変性のためのテクニックは、必要が生じた場合に導入する

優先順位としてモデル駆動設計の方を重視しますので、図1のモデルをできるだけそのままの形でソフトウェアに落としこんでいきます。

http://codeiq.hatenablog.com/entry/2013/08/07/162935

この図、フローチャートと比べた場合、アルゴリズムの大事な部分をわざわざ消し去って劣化させた物になっています。FizzBuzz の問題 の肝の一つに、3 と 5 の公倍数の存在があると思います。そこがちょっといやらしい部分です。

このモデルの場合、公倍数は独立したマッチ条件にするモデルを採用していますが、そのモデルが正しく動くために必要な「評価は上から順に行われる」「条件にマッチしたら他の条件は試さない」という二つの仕様について、フローチャートならば誤解なく書かれるはずのところを、わざわざ省かれて曖昧にしたものと同等になっています。*4

もちろんこれは揚げ足とりなのですが、けれども「手続き」に対しての優位性を語る背景で、「手続き」モデラーにメジャーな(そして他からは disられてる)フローチャートよりも劣った(=抽象的なわけでなく、ただ曖昧な)「モデル」を提示するのは、果たして良いことだろうかと思いました。つまり「モデル」と呼ぶのはちょっと足りないかな、と。

そしてこの曖昧にした部分が、実は本文で示す拡張性にたいして、拡張に対して閉じていて、修正に対して開いちゃうアキレス腱になりかねないたちの悪さよ。


なんだか空気が読めない事ばかり言って恐縮なのですが、けれども、(等身大の構造として)お粗末なものを 「OOP とはこういうものだ」の例として説明されてしまいますと、それが「喩え」とか「模型」とか「ミニチュア」とかではなく、そのものだと思ってしまった場合によくない副作用が生じますので、わたしはこれはちょっと OO じゃないし、モデルでもないと弾言しちゃいましょう。

(こう言っている人も居るって状態がいいな、と思ったのです / はてブを読んでてちょっと不安になりました)

その437

現在ある問題がどのように(どのようなオブジェクトで)構成されているのか、そのままをモデルにしたものです。
問題をソフトウェアで解決するには、問題そのものをソフトウェアで表現しなくてはなりません。ここでいきなりデザインパターンのような技法を持ち込むと、モデルを歪めてしまう可能性があります。

について。ここもちょっとだけ「ん?」と引っかがったとこでした。

わたしの趣味として、「現実をそのままモデリング」というのは嫌いです。昔 disったエントリーも書きました。名詞抽出法はOOAD の 黒歴史です。でも、そのままモデリングを大事にする宗旨があるも認識していますし、だから「ん?」と思ったのは、それと DDD の組み合わせがなんとも奇妙に感じられた、という点です。はて、DDDって「現実そのままモデリング」だったけな?

この方の言われるアプローチが、どうも DDD の言う Hans on Modelers に反しているように感じられもするのです。

モデル駆動設計においては、モデルが効率的な実装を支えながら、ドメインについての主要な知識を抽象化します。両輪がそろうことが大切です。モデルが現実の「そのまま」であることは、DDD的ではないと思っています。

そう感じさせるのは、単に FizzBuzz という例が 例として不適なためかもしれません。あのモデル(図1) とモデリングの結果生み出されたがコードがもしリアルであるなら、それは お世辞にも DDD 的とは言えないなぁ、とむしろModelersが実践的でないために生まれた モデルと実装の分断の結果に見えます、と感じるからかも。


* * *


ちょっと蛇足。

素直に読めば「それはそうだよ(DDDに基づいてって断ったじゃん)。ただ、現実をそのまま捉えたモデルが、モデル駆動設計の「開始地点」としては必要だし有意義と考えているんだ」という話かなって思いました。

ただ、FizzBuzz を例にとった今回の話は「効率的な実装」をまったく支えてないよね、という背景が、「あれ?間違ってない」と感じさせたというお話で。

その438

ところで 「オブジェクト指向FizzBuzz」 って、ガチで考えるとどういうものになるでしょうか。

いろいろ難しいのですが、とりあえず OO的なFizzBuzzコード、と聞いてまず頭に浮かぶのはこんな感じ。

[1::100].collect( lambda x : x.asFizzBuzz() )

コレクションクロージャメソッドと、要素による自己解決の組み合わせが好き。これはカモノハシ本のN-Queens に刷り込まれてますにゃあ (*´ω`*) 。たぶん、これがOO的だと思うのですが、ですが、肝心の FizzしてBuzz するアルゴリズムの部分が無いコードなわけで(^^;。

OOP でシンプル過ぎるアルゴリズムの場合、メソッドの中身は OOP とか関係ない次元になりがちです。手続き型とか、関数型とかとか。 たとえばもし、

// expand: で既存のクラスにメソッドを足すよ、と思いねぇ

Integer expand: #asFizzBuzz {
   match (self.mod(3), self.mod(5)) with
      (0, 0) -> "FizzBuzz"
    | (0, _) -> "Fizz"
    | (_, 0) -> "Buzz"
    | (_, _) -> self.asString()
}

こんな言語が欲しい..(´・ω・`) パターンマッチかわいいよパターンマッチ――じゃなかった、という風な言語があったならば、そこは 関数型チックと感じるでしょうし、Java 的な言語で書けばいかにも手続き言語的と感じるだろうと思います。

FizzBuzz問題と OO が対峙するとき、肝心の部分は他のパラダイムとしか言い様のないコードになってしまうので、これは鬼門だなぁ、と思うのです。

もともと FizzBuzz は 「順次」「選択」「分岐」の三大制御構造をちゃん使えるかをテストするのが目的な、それのためのコンパクトな問題ですしね。

その439

さきほどの PHP FizzBuzz の肝は、判定アルゴリズムへの拡張に対して「開いて」いるように設計している部分なのだと思います。そういった設計は大事で、だからこのチュートリアルが悪いとか間違っているとかは思いません。

ですが、さっきちょこっと触れたとおり FizzBuzz は、3と5の公倍数の取り扱いの問題があるために、おのおののアルゴリズム間の絡み方自体が アルゴリズムとしての肝になるため、こういった例を説明するためのモデルケースとしては向いていません。つまり、説明で「開いてるでしょ!」と言うほど綺麗には開けていないのですよね。

これはもう、書きたいお題に対して、例のチョイスが致命的によくなかったと。わたしはそう思います。

しかし、FizzBuzz問題のこの性質こそが FizzBuzz問題を面白くしています。

例えば、OO脳でいかにもやりたくなる、Integer と String に asFizz と azBuzz を追加して map 関数にかけるという手

Integer expand: #asFizz { if self.mod(3) = 0 then {"Fizz"] else {self} }
Integer expand: #asBuzz { if self.mod(5) = 0 then {"Fizz"] else {self} }
String expand: #asFizz {self}
String expand: #asBuzz {self}

[1::100].collect( lambda x: x.asFizz().asBuzz() )

が破綻するのも asFizz と asBuzz が互いに無関係でいられないためです。

これが通れば、コレクションクロージャメソッドにポリモーフィズムにカスケードメッセージと、かなり OO らしくなるのですけどね...。残念。

その440

というふうな、今回いろいろ書かせていただいた2例をみて思うのは、わたしのような OOP はたとえ手続きパラダイムで十分な規模でも使えると嬉しい パラダイム・・・という趣旨の人間(=Rubyを嬉しいと感じるような人種)とは、別の世界の OOP だなぁ、ということ。

また、わたしの書いたものは、空気が読めていない意見でしかありません。「勝手に蛇足」と言い換えてもOKです。自分でも書きながら、「これはちょっと穿ちすぎだなぁ」と思いました。(で、書かなきゃ良かった、と後悔したり、いろいろ表現をいじくったりしています)

OOPFizzBuzz」は、表題から受ける印象とは異なり、FizzBuzz を 出汁につかった、PHP での典型的なOO的設計や開発プロセスの説明です。

わたしのは、OO者があれを本当に FizzBuzz に対してやると思われたら堪らない、という話ですが、タイトルと内容の齟齬については、本文の最初に載せられた 問題文を読めばすぐわかることです。

「関数脳」は、OOP は手続きパラダイムと イコールじゃないよ、舐めんな!と、反射的に思ったという話で、でも Java8 を語る上では、そういってしまうのが一番わかりやすいのかな?とも思います。

ヒーローの変身中や口上中にバールのようなもので殴りつけるようなことをしておいて、悪者と開き直れずにこういう風にいいわけしちゃうあたり、なんとも小心者すぎで、小物感があふれてますね(^^;

*1:分岐と繰り返しはそもそも OO的じゃないとおもうのです。Smalltalk の #ifTrue:ifFalse: とか、コレクションクロージャメソッドとか、既に「手続き」の守備範囲じゃないですにゃー

*2:特に前者をデバッグのシチュをユースケースに「ドヤ!中覗かんでもええで」とする解説は、そもそもバグを疑っているシーンじゃ「中開けなくても良い」はこじつけよね、と思います

*3:わたしにとって OO とは責務分散協調系のことで、これが失われればOOとしてのアイデンティティを失うと思うから

*4:パターンマッチとして捉えた場合は、パターンの衝突や網羅性が 曖昧で、やっぱり「足りない」感じですね