flat7th

memo/20130122

created 2013-01-22 modified 2013-01-22 

コールバック プログラミングの、次の話。

python の yield 文おもしろい。

リンク備考
yield 文Pythonリファレンス(3.3)(2系にもここから飛べる)
PEP 255yield文を機能拡張として導入するときの提案文書。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文を有効活用するプログラミング方式を推し進めると、ソフトウェアの再利用性が劇的に向上し、かつ処理速度も向上する、可能性がある。


* 日々のメモ