作者: 機械伯爵
日時: 2007/10/2(14:01)
(Pythonでプログラミングを勉強している後輩のところへ、先輩がやってくる)

先輩A「よう、プログラムの勉強、はかどってるか?」

後輩 「はい、昨日はa = a + 1という書き方を覚えました。数学で考えると不思議
ですけど、便利ですよね。これまで僕は、xに関数f0,f1,f2,f3,f4を次々と適用する
ときに、

a = func0(x)
b = func1(a)
c = func2(b)
d = func3(c)
y = func4(d)

とか書いてたんですけど、これで

y = func0(x)
y = func1(y)
y = func2(y)
y = func3(y)
y = func4(y)

と、変数無しで済みますから、得した気分です」

先輩A「(なんで代入より先に関数適用覚えてんだよ……)しかし、むやみな代入
は、参照透過性を損なうからなぁ」

後輩 「なんですか、その参照透過性って?」

先輩A「状態を示す変数の値が次々代入されると、デバッグのときその内容を追って
くとわかりづらいって話だ。それにそれ、もっと簡単に書けるぞ」

後輩 「もしかしてxに直接代入するんですか? だめですよ。xは他でも使うんです」

先輩A「いや、こーいうことだ

y = func4(func3(func2(func1(func0(x)))))

で、いんじゃねの?」

後輩 「……そんなのアリですか?」

先輩A「括弧の中から評価してくのはわかるだろ? んでもって関数は値として使え
るから……」

先輩B「醜いな」

先輩A「なんだ、いきなり。醜いって? シンプルで美しいじゃねーか」

先輩B「括弧の過剰が醜い。記述順序と実行順序が逆なのが醜い。美しい記述とは、
シンプルなばかりでなく、何が起こっているかがわからなければならない。」

先輩A「……ならてめーはどう書くってんだよ」

先輩B「(後輩の方を向いて)君、変数や関数は、具体的にどういうものかね?」

後輩 「(例えば、なんだから考えてないってば)えっと、数値でも文字でもいいです
けど……、xは文字にして、文字を足していく関数にしましょうか」

先輩B「ふむ、Pythonでは文字は不変オブジェクトだから……

x = 'xxx'

class xList(list):
  def mes0(self):
    self.append('aaa')
    return self
  def mes1(self):
    self.append('bbb')
    return self
  def mes2(self):
    self.append('ccc')
    return self
  def mes3(self):
    self.append('ddd')
    return self
  def mes4(self):
    self.append('eee')
    return self

o = xList(x)
o.mes0().mes1().mes2().mes3().mes4()
y = ''.join(o)

……ま、こんなところか?
後輩 「(唖然)」

先輩A「ば、ばかかてめーわっ! なんでこんな簡単なコトするのに、クラスなんぞ
定義する必要があるんだっ!」

先輩B「私の場合は、関数定義も入っていることも忘れてもらっては困る。それを
差し引けば、さして難しくは無いよ」

先輩A「そんなことねーよ。それにコレ、順番はともかく、結局の一文は、綺麗に
まとめたところで、

((((o.mes0()).mes1()).mes2()).mes3()).mes4()

ってコトじゃねーのか? わかりにきーよ」

先輩B「Pythonではメッセージのカスケード文法は無いから、多少見づらく
なるが……

o = xList(x)

for c in 'mes0 mes1 mes2 mes3 mes4'.split():
  xList.__dict__[c](o)

y = ''.join(o)

……こんなとこでどうだ?」

後輩 「あの……一体何がなんだか……」

先輩A「話にならん」

先輩B「メッセージ適用の美しさは、Pythonでは完全に再現できない、ということ
だな」

先輩C「あら、そんなこと無いんじゃない?

y = x
for c in (func0, func1, func2, func3, func4):
  y = c(y)

で、どう?」

後輩 「(絶句)」

先輩A「シンプルじゃない」

先輩B「メッセージ適用じゃない」

先輩C「なによぉ。関数がファーストクラスオブジェクトのPythonにふさわしい
解法じゃない」

後輩 「あ、あのぉ、関数って……」

先輩C「ああ、これ、SchemeとかPythonの特徴で、関数はそのまま、変数やリテラル
みたいなオブジェクトとして使えるの。もちろん、変数に代入したり、タプルに入れ
たりできるのよ」

後輩 「……便利、だと思うんですが……理解にちょっと時間が……」

先輩A「まぁ、オブジェクトよりマシだがな。結局カウンタを使うわけだし、直接
適用のほうが良くねか?」

先輩B「否、メッセージ思考を基本とすれば、様々な場面で役に立つ。オブ脳で考え
るべきだ」

先輩C「わかりやすいのがいいのよ。ね」

 さて、あなたはどうしますか?

※例に挙がってるのはPythonですが、入門者の誘導、という話題で……
 もしよければ、他の言語で似たようなネタ、書いてください(笑)

 /機械伯爵/