Kahua
Kahuaはアプリケーションサービスを構築するための、継続ベースのフレームワークです。
で、サンプルにカウンターを作る話がでてくる。
http://www.kahua.org/cgi-bin/kahua.fcgi/kahua-web/show/doc/hello-kahua#H-1o28l31
リンクをクリックすると、数をどんどん増やすようなアプリケーションにしてみましょうか。やっぱり実用性無さげですが。
そんなもん、session とかで情報を渡しても出来るわ!とか言われそうですが、まぁ簡単なサンプルってことで。
(define-entry (counter)
(define (viewer count)
(page "hello kahua! - counter"
(h1/ "Hello Kahua!")
(h2/ (format "count is ~a" count))
(p/
(a/cont/ (@@/ (cont
(lambda () (viewer (+ count 1)))))
"inc count") " , "
(a/cont/ (@@/ (cont
(lambda () (viewer (- count 1)))))
"dec count")
)))
(viewer 0))
こんな感じでしょうか。http : //.../kahua.cgi/hello/counter とアクセスすることでこのページが表示されます。
a/cont/ というのは「このリンクをたどったとき、指定した継続を実行しろ」とサーバに登録するためのものです。継続の指定は「(@@/ (cont proc))」 と指定することで行います。
つまり、(a/cont/ (@@/ (cont proc)) "...") と記述すると、「"..." というリンクをたどると proc が実行」するような意味になります。
HTML ではリンクは <a href='dokka'> dokka </a> と書きますが、Kahua で (a/cont/ (@@/ (cont proc)) "dokka") と書くことで <a href=「proc を実行してくれるリンク」> dokka </a> と出力されます。
ここで、proc が継続になるわけです。 ↑のコードを見て、 Hop と絡めて、ちょっと妄想。
もしこう書けたら。
(define-service (make-counter x)
(lambda-service ()
(set! x (+ x 1))
x))
(define-page (main)
(let ((c (make-counter 0)))
(<html>
(<body>
(<p> :id "count" "0")
(<button> :onclick (scm2js (set! (document.getElementById "count") c))
:value "押す")))))(define-service (make-counter x)) で、引数を一つとるCGIが設置される。
(define-page (main)) で、main.html が設置されて、その中で make-counter に、AJAXでアクセスできる。
本当は javascript を書くところだけど、 scheme2js で書けちゃう。
- 内部に set! といった副作用があると、 cgi が状態を持つことになるし、継続と相性悪そう。
- objects are a poor man's closures. というけど・・・
で フィールド x を持ってて、 :slot-ref で ajax発生 & x を +1 のほうがいいかもしれない。 - 継続サーバについても調べてみよう。
それができりゃあ苦労はねえんだよってんで、 Kahua があるんだろうけどね。
- これも参考になりそうだ Dalma Workflow Engine https://dalma.dev.java.net/nonav/maven/index.html
- Process Migration @ Wiliki http://www.shiro.dreamhost.com/scheme/wiliki/wiliki.cgi?Gauche%3A%A5%D7%A5%ED%A5%BB%A5%B9%A4%F2%B1%DB%A4%A8%A4%BFlambda%A4%CE%B0%DC%C1%F7&l=jp
- The Continue Server http://www.cs.brown.edu/people/sk/Publications/Papers/Published/sk-continue/paper.pdf
- Dalmaは、仮想スレッドの冬眠という概念を持っているらしい。スレッドよりも、プロセスのほうが開発に便利だろう。define-service make-counter で、サーバプロセス(本物のUnixのプロセス)を生成、/make-counter へのアクセスはリバース・プロキシでこのサーバプロセスへのアクセスになるというのはどうだろう。リバース・プロキシには mod_proxy を使えばいいし。プロセスごとに継続を待てばいいし。
- これはダメなアイディアだった。
- 枝葉末節だが、環境フレームなどの"冬眠"に必要なデータは、tmpfsで管理すると高速でいいかもしれない。