memo/20130122
created 2013-01-22 modified 2013-01-22
コールバック プログラミングの、次の話。
python の yield 文おもしろい。
リンク | 備考 |
---|---|
yield 文 | Pythonリファレンス(3.3)(2系にもここから飛べる) |
PEP 255 | yield文を機能拡張として導入するときの提案文書。18-May-2001 |
シンプルな例、を引用。フィボナッチ数列を順に返すプログラムだね。
def fib(): a, b = 0, 1 while 1: yield b a, b = b, a+b
yeild は return みたいなものなんだけど、returnじゃない。関数全体はイテレータを生成して返す。 yield は、イテレーションの1個の値を追加する。
こういうことだと理解した。
呼ばれた側が、呼び側に何らかの影響を及ぼすような値を、次々に返す、ていうプログラムを作りたい場合の話。
古来は、グローバルな状態マシンに記憶しつつコールバックで実現するのが普通で、それは今(?)でも典型的な実装なのだけど、分からない人には分かりにくい。わかりやすいのはスレッドを使ってしまうことだけど、スレッドは使えない環境があるし、遅い。
返却値をリストにして返す方式で、何も考えないと全部作ってからドカンと返す実装になって、現実的じゃない。
そこで、イテレータ(リストから値を順に取り出せる)を返すことにする、と。で、呼び側が .next() とやったら1個取れればいいので、そのつど「呼ばれた側」がレジュームして次の1個を格納する方式なら、スレッドを使わなくて済む。スレッドみたいに、どこで割り込まれるか分からない、なんていう厄介な事を考慮する必要がないし、割り込まれる場所が明確なので、ロック・アンロックを作り込む必要がない。
と。そんなところかな。
この概念いいね。
この話で私が大事だと思う事は、プログラマが「ここで割り込んでね」と思うところでだけ割り込まれる仕組みである、ということ。
昔々の格言で、
割り込みが1回発生するとプログラマの白髪が1本増えるてのがあって、スレッドにもその考えが当てはまる。
んでも、コールバックってのは、割り込みがどこで起こるかがプログラマにとって明確だから、上記に該当しない。ただし、コールバックの概念はちょっと中上級者向け。
私は、この話って充分「計算機科学の問題の一つ」だと思っている。
yield 文てのは、この問題に一石を投じるものだね。
2001年から公開されてた話だなんて、全然知らなかったよ…アンテナ低いぞ、俺。
リンク先の文書で コンシューマ-ジェネレータ(のプログラムパターン) て言葉がある。
そう、確かに、この概念は「パイプライン方式のプログラミング」=「有向グラフ接続方式のシステム開発」に有効だね。
何度も書いたりつぶやいたりしてるけど、「Unixパイプ」はソフトウェア再利用のもっとも成功した例の一つ。しかもマルチコアにとても親和性がある。だから、yield文を有効活用するプログラミング方式を推し進めると、ソフトウェアの再利用性が劇的に向上し、かつ処理速度も向上する、可能性がある。
【* 日々のメモ】