制約は構造を生む
「制約は構造を生む」というのは確か結城浩さんの『数学ガール』の中にあったフレーズだと思うが,私はこの言葉が好きである。 ただし,私の中ではこの言葉に続きがあって,それは「制約は programmable である」というものだ。
「言葉」というのは面白いもので,表現のためのすばらしい手段でありながら,それ自体が表現に制約を加える。 自然言語の場合,その「制約」が硬直化するのを防ぐため自己を改変していく1。 しかしプログラミング言語の場合は「仕様」であり「ルール」であるため自己改変がしづらい面がある。 つまり,どんなプログラミング言語にも「賞味期限」があるのだ。
前にも書いたけど,私は職業プログラマなので,プログラミングが好きでも嫌いでもない。 私から見れば「プログラミングが好き」というのは「鋸が好き」と言ってるのと大差ない。 プログラミング言語も同様で,基本的にはどんな言語にも対応できる自信はあるが,特定の言語が好きというのはない。
それでも「これで何かを作ってみたい」と思う言語はいくつかあって,私の場合はそれが C/C++ や Java そして Go 言語である。 どういうわけかスクリプト言語にはあまり食指は向かなかった。 これはたぶん後付けの理由だけど,スクリプト言語というのはひたすら対象を「記述」しているだけで,あまり「作ってる」実感がない。
先日,ついカッとなって「エラー・ハンドリングについて」という記事を書いたが2,書いてて思い出したのが,まさに「制約は構造を生む」というフレーズだった。
いわゆる「オブジェクト指向言語」が台頭しだした頃, C++ や Java でなかなか馴染めなかったのが「例外処理」である。
「または私は如何にして例外するのを止めて golang を愛するようになったか」で「Java の例外が発生しうるメソッドの呼び出しは分岐を隠蔽・内包している」と指摘されているように,まさにこれは呼び出した関数から見て正体不明の longjump
をかまされるのとほとんど同じであり3,「そんな危ないもん使えるか!」というのが最初の印象だった。
まぁ,もうすっかり馴らされたけどね。
かつての私のように,例外になじめない人は結構いるようで,中には呼び出す関数ひとつひとつを try-catch
で囲ってる人とかもいて,「それって例外で実装する意味あるのか?」って感じである。
で,結局,関数の返値専用のオブジェクトを作って,返ってくるオブジェクトの状態を見てエラー・ハンドリングしたり。
それって CDD (Context-Driven Design) の萌芽かも(笑)
Go 言語のエラー・ハンドリングと「古き良き」例外処理のどちらが優れているのかは一概に言えないと思うが,個人的には Go 言語のやり方に慣れてしまったら例外処理には戻れない4。
今まで触ってみた感触だけど,おそらく Go 言語の肝は return
にあると思う。
Go 言語の return
をどう記述するか(あるいはしないか5)がコードの構造を決める鍵になっている。