Hop の仕組み
Hop, a Language for Programming the Web 2.0をわかりやすく説明しようと思う。
サーバ側の現在時刻を、Ajaxで受け取って、動的に表示するHTMLを書くことを考える。
普通のやりかた
私たちの手元にあるのは、HTTPサーバと、CGIと、Javascriptと、Ajaxだ。
- HTTPサーバを立てる。
- CGIを Bigloo (Scheme処理系) で書いて設置。例えばURLは、http://hoge.com/serverdate.cgi
- HTMLを書く。Ajax なら、 prototype.js を使おう。こんな感じ。
<html> <head> <script src="prototype.js" type="text/javascript"></script> <script type="text/javascript"><!-- function ajax() { var url = 'http://hoge.com/serverdate.cgi'; var myAjax = new Ajax.Request( url, { method: 'get', onComplete: showResponse }); } function showResponse(originalRequest) { //alert returned XML alert(originalRequest.responseText); } // --></script> </head> <body> <button onclick="ajax()" value="Server time"/> </body> </html>
できあがり。
Hopを使うと、この作業を自動化できる。
(define-service (server-date) (current-date)) (<HTML> (<BUTTON> :onclick ~(with-hop ($server-date) (lambda (h) (alert h))) "Server time"))
と書いてやると、
- Hop はそれ自体がHTTPサーバ。
- define-service で、自動で CGI を設置してくれる。
- HTMLは、タグをS式で書ける。~(...) は特別扱いされ、Scheme2js で Javascript にコンパイルされる。alert は javascript の関数だ。lambda(h) は function (h) になる。
- with-hop は、new Ajax.Request ... のラッパーである。
無名サービス
πを返す CGI を、
(define-service (pi) (* 4 (atan 1)))
などと設置したり。
だが、無名関数がSchemeにあることから連想して、無名CGIを考えてみよう。
それが $ 記法で、
(<HTML> (<BODY> (<BUTTON> :onclick ~(alert $(* 4 (atan 1))) "Click me to see an approximation of PI")))
と書くと、$(...)が特別扱いされて、無名CGIが設置される。これはようするに、名づけるのをHopに任せるだけ。勝手に名前を"4-57604278"とでも付けて設置してくれる。
コンパイルされると、
:onclick ~(with-hop ($4-57604278) (lambda (h) (alert h)))
とでもなるんだろう。