制約は構造を生む

no extension

「制約は構造を生む」というのは確か結城浩さんの『数学ガール』の中にあったフレーズだと思うが,私はこの言葉が好きである。 ただし,私の中ではこの言葉に続きがあって,それは「制約は 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)がコードの構造を決める鍵になっている。


  1. 逆に言うと自己改変しなくなった言語は緩慢な死を迎える。 ↩︎

  2. 後悔はしていない。 ↩︎

  3. 今はもう存在しないと思うが,初期の C++ の実装のいくつかは例外を longjump で実装していた。 ↩︎

  4. いや,もちろん仕事ならやりますよ。 ↩︎

  5. 記述しないことは記述することの一種である。 ↩︎