2007-12-02
■ [event][prog] LiveCoding#5に出演しました
土曜日に大阪で行われたイベントLiveCoding#5に、 LiveCoderとして出演してきました。
事前に、LivePromoter(※主催者のことらしい)であるujihisaさんから できるだけマニアックな方がいいというオーダーを受けていたので、 Ruby + Javascript + Scheme + Zu という無茶な構成にしてみました(笑)。 *1 BiwaSchemeで 「ず」のインタプリタを作るというテーマだったのですが、 予想外に手間取ってしまい、パース結果をRubyのCGI経由で取ってくるとこまでしか行きませんでした。 解説のnaoya_tさん、Abeさんごめんなさい(><)
敗因
- Ajaxのクロスドメイン制約を忘れていた
- CGIはサーバに、htmlはローカルに置くつもりだったんですが、どちらかに統一しなければならなかったんですね。
- 会場では、慣れている環境ということで全てローカルに統一しました。
- このせいでWEBrickのリファレンスをLiveに参照することに…^^;
- httpのPOSTを行う関数がBiwaSchemeに存在しないことを忘れていた (GETはあった)
- 直前にあわてて用意したんですが、バグってましたね。
はまったところ
- textareaはinnerHTMLではなく、valueでないと中身が取れない
というわけで
define_libfunc("get-content", 1, 1, function(ar){ return ar[0].innerHTML; });
というライブラリ関数を
return ar[0].value;
のように書き換えようとしたら、観客の皆様に怒られました(笑) ちゃんと
return ar[0].value || ar[0].innerHTML;
みたいにしないといけないですね。(と思ったんですが実はこれでも駄目で、
return ar[0].value || ar[0].innerHTML.unescapeHTML();
が正解。)
- alistを取るAPIにしたつもりだったのに、(cons "src" zu) みたいなペアを渡していた(a"list"なんだから、ペアのリストにしなければならない)
- quasiquoteをquoteにしていた。 '("src" . zu) だと、 '("src" . 'zu) という意味になってしまう
- innerHTMLを使うと、中の「>」や「<」がエスケープされてしまう(終了後数十分してやっと気付いた)。
教訓
- 「ここまでは5分あれば行けるやろ」と思うところまでしか辿りつかない。
- 調理はLiveだとしても、素材の仕込みはちゃんとやっておくべし。
他の人のとか
色んなところで既に書かれていますが、oxy君 のコーディング速度があり得なかったですね(笑)。 TGMのGM認定動画を見たときくらいの衝撃を受けました。 どっちも、操作の早さに注目しがちだけど、本当に凄いのは思考の方であるのも同じですね。
あとFlyMake凄いとか、Flash面白い(開発環境が)とか。
ともあれ、発表者の皆さん、参加者の皆さん、会場を提供してくださったグッデイの 皆さん、そして主催のujihisaさん、どうもお疲れ様でした。
*1 実は「Railsで画像ギャラリーを作る」みたいな普通の案も考えていた
■ [javascript] prototype.jsでラジオボタンの値を取得する
$A($('form_name')['input_name']).find(function(v){return v.checked}).value
長 す ぎ る 。$F('input_name')で取れてほしいなぁ。
参考:
■ [biwascheme] サーバ側のCGIにpostする例
LiveCodingで書いたのを、いろいろ修正してちゃんと動くようにしたやつを以下に置きました。
textareaにZuを書いてボタンを押すと、サーバ側のCGIを使って図をパースします。 あとはパース結果を使ってインタプリタを書くだけですが、 そのソースを載せるにはこのブログの余白は狭すぎるので、あとは読者への宿題とします(常套句)。
ソースを見れば分かりますが、HTML内にはJavascriptは一切書かれていません:-) 通信からイベントハンドラまで、全てSchemeで記述されています。*1
*1 もちろん、各APIはJavascriptで実装されているわけですが
■ [rubiskell] RubyからHaskellを呼び出すライブラリ、Rubiskellを作ってみた
Rubyでは、簡単なことは簡単に、複雑なことはそれなりにできる。
Haskellでは、簡単なことは複雑に、複雑なことは簡単にできる。
[ujihisa (2007)より引用]
だとしたら、複雑な部分をHaskellで書いて、簡単なところをRubyで書けば最強なんじゃね?
require 'rubiskell.rb' FIB = <<EOD fib :: Int -> Int fib 0 = 0 fib 1 = 1 fib n = fib (n-2) + fib (n-1) EOD def fib(n) fib = Haskell.new(FIB) fib[n] end puts "fib 5 is #{fib(5)}."
実行結果:
C:\proj\rubiskell>./sample.rb fib 5 is 5.
というわけでRubiskellは、Rubyスクリプト中にHaskellのコードを埋め込むためのライブラリです。
Haskellがあまり得意でない入出力やユーザーインターフェイスをRubyで補うことにより、 LightWeightで信頼性の高いHaskellプログラミングを手軽に体験できるようになるとかなんとか。
動作原理
単純に、テンポラリファイルを作ってrunghcに*1食わせているだけです。
Haskellプログラム中の型宣言部分をパーズして、自動的に入力・出力をエンコードします。
制限
- 渡せる引数は任意個数の整数および文字列のみです。リストやタプルはまだ実装してません。
- 現在はコマンドライン経由で引数を渡しているため、あまり長い文字列は渡せません。win32-open3というgemを使うとwindowsでもopen3できるようになるらしいので、そのうち標準入出力を使うように直します。
感想
以前からネタだけは考えていたんですが、実装したら意外とあっさり動いてびっくり。
呼出し毎にHaskellインタプリタを呼ぶので、短い計算を何度も行うような用途には向いてないかも知れません。 オセロのCPUの思考ルーチンなど、時間のかかる計算を時間を置いて呼ぶような用途を想定しています。
GHCが使えるなら、最初の実行時にコンパイルしてしまうというのもアリかもなぁ。 あと副作用がないHaskellプログラムなら、一度実行した結果はキャッシュできるとか(Rubyレベルでのメモ化)。
ともかく、僕自身はあまりHaskellに詳しくないので^^; Haskellerな皆様の感想をお待ちしています。 ぜひ一度お試しください。
*1 オプションでhugs等別の処理系も指定可