読者です 読者をやめる 読者になる 読者になる

プログラミングの新たなるパラダイム

Python

オブジェクト指向は死んだのかどうか、寡聞にして判断しかねるところではありますが、Python3000と関連PEPの最前線にいる人たちが、新たなパラダイムに向かって議論を重ねていることは間違いないありません。この日記で何度か言及している多重ディスパッチ・ライブラリsimplegenericも、そうした努力の成果の一つであると言えます。


多重ディスパッチはPython3000のトピックの一つですが、現在使用できる多重ディスパッチ実装の中で最も強力なものとしてRuleDispatchがあります。これはTurboGearsの中でも使われているので、知らないうちに使っている方も多いと思います。
simplegenericはクラス、インスタンス単位でのディスパッチしか対応していなかったので、やや使いづらい面があったのですが、RuleDispatchは任意の述語(評価関数・式)によってディスパッチを行えるので非常に便利です。また、条件検索の実装がPyrexによって書かれているため、実行速度の点でも利点があります。


あまり良い例ではないのですが、ElementTreeのiterparseとRuleDispatchを使って、フォト蔵APIからインターネットに公開されている写真を取得するプログラムを書いてみると、こんな感じになります。

import dispatch
from cElementTree import iterparse
from urllib2 import urlopen

@dispatch.generic()
def consume(item):
    pass

@consume.when(dispatch.strategy.default)
def consume(item):
    pass

@consume.when("item.tag == 'url' or item.tag == 'photo_title'")
def consume(item):
    print item.tag, item.text

for e, item in iterparse(urlopen('http://api.photozou.jp/rest/search_public?limit=5')):
    consume(item)

「あまりよい例ではない」というのは、このコードでは多重ディスパッチの利点が伝わりにくいと思われるからです。
RuleDispatchのモティベーションは、「18歳以上、もしくは保護者の同意がある18歳未満の者」、「祝日を除く火曜日には、すべての魚肉製品は高齢者に対しては20%オフで販売される」といった。より複雑な述語の記述することにあります。興味のある方は、Phillip J. Ebyが行ったPYCON'05での多重ディスパッチに関するプレゼンテーションの資料を参照してみて下さい。
Python3000は、If-Else式のプログラミング、オブジェクト指向ポリモーフィズムから、さらに先の地点を見据えています。


RuleDispatchは、その他にも、アスペクト指向プログラミングをサポートするための最小限の機能を提供しています。
ある関数の実行前と実行後に、何らかの関数を呼び出す場合は、次のように記述します。

import dispatch

@dispatch.generic()
def greet(value):
    pass

@greet.before("True")
def enter(value):
    print "__enter__"

@greet.after("True")
def after(value):
    print "__after__"

@greet.when("isinstance(value, str)")
def greet(value):
    print "Hello ", value

greet("World")

実行結果は次のようになります。

__enter__
Hello  World
__after__

これもまた、アスペクト指向のプログラミング例によくあるように、何が利点なのかよくわからない例ですね。;-)
おそらく、もっと突き詰めて考えれば、この機能は利用しがいのある機能です。


Pythonを勉強すればするほど、自分の無知を実感します。いつになったらBDFLとその仲間たちに追いつけるのだろうか。