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 があるんだろうけどね。