2011/10/28

nilは悪か?

こんにちは、@tomoodaです。今回はnilのオレオレな勝手な話をタレ流します。

nil、言語によってはnullだったりNoneだったりもします。 ヌルポとか言われて嫌われています。 nullを発明したのはホーアさんですが、そのホーアさんまで「10億ドルの失敗」と言っているほどです。 そうなると、判官びいきなオレとしては、少しぐらいは弁明してあげたくなります。 ちなみにオレのミドルネームは善九郎で、九郎の部分は義経さんにあやかってだそうです。ツ

さて、nilは何のためにあるのでしょう? どんな時に使われるのでしょう? 多いのは、変数の初期値です。 nilを入れられる型の変数を初期化なしで宣言したらnilになる言語が多いですね。 また、失敗をあらわす返り値に使われることがあります。 便利じゃん?

じゃあ、nilの何が悪いのでしょうか?それは、期待外れだからです。 Vector型の変数で足し算しようとしたら、実はnilで足し算できずに例外が発生してしまうからです。 Image型の変数だから幅を調べようとしたらnilだからヌルポとか言われてしまうからです。 以前、型は値の集合であり、値が満たすべき性質をまとめたものだ、という話をしました。 まさにここでも同じことです。 Vector型の値は足し算ができるという性質を表明しています。 だから、Vector型の変数に足し算してみたくなったのです。 なのに足し算ができないなんて、詐欺じゃないか! Image型の値の横幅も同じです。 できると宣言されたことが、実際には出来ない。 だから皆が怒るのです。

nilが嫌われるもう1つの理由は、何もできないからです。 足し算もできないし、幅もありません。 SQLでは=で比較してもTRUE/FALSEで答えてもらえないのです。 ダメダメじゃん… 弁明の余地はないんでしょうか?

あります。ツ

nilがダメな第一の理由は、「期待外れだから」でした。 だから、「期待しなければいい」が解決策です。 期待外れだという例は、Vector型の変数なのに足し算できないから。 Image型の変数なのに幅がないから、でした。 え?Vector型?Image型? じゃあ、型が宣言されていなければいいんじゃん?

動的型付けの出番ですよ〜ツ

動的型付け言語のSmalltalkではどうでしょう? 変数の初期値はnilです。 nilは足し算できません。 だから何? 辞書とか、ソケットとか、配列とか、文字列とか、ビューとかコントローラとか、足し算できないオブジェクトなんて、他にも星の数ほどありますよー。ツ nilは幅を答えられません。 別に気にしなくていいよ。 整数とか、集合とか、時刻とか、幅がないオブジェクトなんて、他にも星の数ほどあるもんねー。ツ Smalltalkで問題になるのは、送りたいメッセージを受け取って、期待したことをしてくれるかどうかです。 nilかどうかなんて些細なことなんです。 VectorはVectorのできること、nilはnilのできることをすればいいのです。

じゃあSmalltalkのnilは何ができるのでしょう? 他にもデキナイ子がいるからといって、何もデキナくてもいいわけじゃありません。

nilはね、自分がnilだということを知っているのですよ。 nilであることを知っているから、nilかどうかという条件分岐ができます。 nilに、ifNil:というメッセージをクロージャといっしょに渡すことができます。 ifNil:というメッセージは、もしメッセージを受けたのがnilなら引数として渡したクロージャを評価する、というものです。 でも、nilのifNil:というメソッドには条件分岐なんか書いてありません。 だって、自分はnilだと自覚してますから。 無条件に実行しちゃえば、結果として条件分岐できちゃうのですよ。 すごいでしょ?条件分岐しなくても条件分岐できちゃう。計算能力が湧いて出てきちゃうのですよ。 これが、覚醒したnilの能力(チカラ)なのです。ツ

他にも、自分はNumberじゃないと知っていたりとか、自分の名前を文字列にしたりとか、それをストリームに書き出したりとか、意外と多芸なのですよ。 そしてこれが2番目の問題点の「何もできない」への回答です。

Smalltalkのnilは、UndefinedObjectというクラスの、立派なファーストクラスなオブジェクトです。 UndefinedObjectはObjectのサブクラスだから、Objectよりも賢いのですよ。 オブジェクト指向言語でオブジェクトより賢いなんて、王者の風格じゃないですか! ツ

というわけで、nilは確かに厄介なヤツですが、その厄介さがどこから出てきているかと言うと、実は静的型付けと、その言語におけるnilの役割に関する事柄だという話をしました。 念のために書いておきますが、静的型付けが悪いなんて言ってません。 型がした約束を免除されるnilと静的型付けの相性が悪いのです。 型がした約束を免除されないnilは静的型付けでも相性いいですよ。 HaskellMaybeモナドのNothingはハズレ的な使われ方の時はnil的な感じですが、型の約束をちゃんと守っているから害はありません。 同様に、動的型付けなら約束を破る必要がハナからないので、やはり害はありません。 いや、ありませんは言いすぎかな? ちょっとあるかも。 ま、いいじゃん。ツ

というわけで、皆の嫌われ者のnilだけど、害がないように使ってあげてくださいね。ツ

1 件のコメント:

  1. このブログをホストしてくれているbloggerサービスは、エントリごとのアクセス統計が取れます。それを見てウシウシしていたのですが、このエントリだけアクセス統計があがってきません。きっと、アクセスログ中のURLをパーズする時、最後のコンポーネントが"nil"になり、「ケッ、このログエントリはパーズできねえぜ!無視無視!」とか言ってカウントしていないのだと妄想しています。やっぱnilは悪なのでしょうか?ツ

    返信削除