schemeで「continuation」に挑戦!
以前のポストで紹介したPaul Graham氏のArcによる超短縮ウェブアプリケーションフレームワークはschemeの「continuation」という機能を駆使して構築されているようだ。Schemeにはnoobな私の理解では、continuationはC言語の「GOTOステートメント」のようにプログラムのコントロールをあちこちと自由に飛せるようなものと理解している。
ただ、やはりschemeなのでもっと根本的でパワフルでカッコイイもののようだ。コントロールを飛ばす機能としてはCのGOTO、perlでループなどを中断するときのlabel、あとexceptionなどがあるが、これらはlexical あるいはダイナミックなスコープ(スタックの上の方)内に行き先が制限されている。一方、「continuation」はそういう制限をうけず、どこからどこにでもコントロールを飛すことができるようだ。
これがウェブプログラミングにどう役立つか? イベントドリブンのウェブアプリケーションは普通はコードが細々と断片化されるが、「continuation」を使うと一連のHTTPのやり取りを一つの関数の中で普通の流れのように書けるらしい。つまり、普通このように途切れ途切れなコードが、、
def home-page:
display-home-page() # ログインフォームを表示
def authenticate:
if login()==success
then redirect to the private page
else
display-login-page()
def private-page:
# display private data..
このように書けるらしい:
def all-in-one-with-continuation:
display-home-page() # svr ---(index.html)---> browser
if login()==success # svr <--(login,passwd)-- browser
display-private-page() # svr ---(private.html)-> browser
else
display-login-page()
ここで、login()などの背後にはサーバからブラウザまでのHTTPの往復が隠されているということになる。つまり、一連のウェブ・インタラクションの状態が一つの関数の中で処理される。その関数はひとつの処理が完了すると一歩前へ進み、そこでブロックし、またユーザからのデータが来ると進むとうような進行のしかたをすることになる。こんなことができたらどれだけ、ウェブプログラミングが楽になるか。まるで、魔法のようだ。
このようなcontinuationベースのウェブフレームワークはschemer達がいくつも作っているが、研究用とかデモ用で本当に使えそうな感じのものはまり見付からない。Arcもプロトタイプ的な印象を受ける。さらに、学者やハッカーが屯する「究極のラムダ」(http://lambda-the-ultimate.org/)のようなフォーラムでさえ、「continuationは難しすぎて実用にはどうも」という意見がみられる。なら、リスプnoobieな私が手を出すようなものではない、と思って無視していた。
しかし、自然フローのウェブプログラミングの魅力は頭から離れない。使わなくても一通り理解しておきたいなどと思いトライしてみることにした。
そこで、どのフレームワークを使うか?どうやら、pythonにもgeneratorを転用したcontinuationベースのフレームワークがあるらしい。しかし、この技術はschemeから生れたもの。やはり、類似品でなく御本家から本物を習いたい。そこで、今遊んでみている鶏schemeでcontinuationにトライしてみた。(ちなみにこの言語、ドメインが「www.call-with-current-continuation.org」だ)
正式名の「call-with-current-continuation」でググってみると、wikipediaのページがトップにきた。
http://en.wikipedia.org/wiki/Call-with-current-continuation
能書きを読み飛ばして、実例を見る。二つ目の長い方はどうやら、pythonとかにある「generator」を実装しているようだ。
うーむ。むづかしい。なんとなくわかることは:
1. コンシューマとプロディユーサがそれぞれcall/cc(正式名の略称)によりコントロールをあお互いに飛している
2. for-eachのイタレーションがコンティニュエーションにより中断され、generatorが呼ばれる度に一個値を返しているぐらいだ。
やはり、基本からやった方がよさそうだ。長くなってしまったので今日はここまで。次はcontinuationの簡単なhello worldから始めてみよう。