coffeescript触ってみた

文法ぱっと見ファーストインプレッション

https://sites.google.com/site/sappariwiki/coffeescript/coffeescript-langref
ここを読んでみて、coffeescriptの文法はぱっと見た感じかなり好みだなと思った。かなり良いとこどりの言語。ちなみにぼくはjavascriptもあんまりたくさん書いたことはありません。

関数

関数定義はHaskellに似ているけど、若干違和感がある。Haskellと=の位置が違うからかもしれない。
デフォルト引数は良いね。可変長引数は良いけど、おれの短いjs歴のなかではまだ使いたかったことがない。

内包表記

内包表記はmapでいいじゃんと思いつつも、あるとつい使っちゃう。何がそうさせるのかわからないけど、もしかしたらそれっぽく見えるからってだけかもしれない。ていうかjsってmapもなかったっけ?

範囲演算子

範囲演算子はとても良い。大好き。phppythonにもあるといいのに。

インデント

pythonhaskellと似たようなインデントでブロックを表す言語らしい。個人的にはあまり好きではない。自由に改行できないし、emacsで括弧単位の操作ができないし。

すべては式(できるだけ)

これは良い。もう全部式でいいよ。文とかいらね。ifもforも値を返す。そうでなくっちゃね。

存在演算子

これも良いね。jsのめんどいところをかっこ良くカバーしてる感じがする。

その他

後置のifとかperl出身の僕にはうれしい。なければないでかまわないけど。比較連結式もあればうれしいレベル。なくてもかまわない。

ちょっと書いてみてセカンドインプレッション

ということで最近書いてたjsをcoffeescriptに置き換えてみた。それで思ったこと。

コールバックで渡す無名関数のところがちょっとわかりにくい

関数定義は

hoge = (x, y) ->
    fuga x
    baba y

みたいな感じなわけだけど、無名関数はどうかくんだろうと思って適当に書いてみたら、それであってたみたい。

(x, y) ->
    fuga x
    baba y

でだ、jsってコールバックでがんがん無名関数渡すじゃない?そのときにこの関数定義とインデントでブロックを表すってルールでこんな感じになると思うんだ。

insertRecord = (item_id, value) ->
    db.transaction (tx) ->
        tx.executeSql select_count_traininngs, [],
                      (tx, res) ->
                          dt = new Date()
                          now = dt.toISOString()
                          tx.executeSql insert_traininng,
                                        [res.rows.item(0).cnt + 1, 1, localStorage['user'], item_id, value, now],
                                        (tx, res) -> console.log(res); update(),
                                        (tx, error) -> reportError 'sql', error.message

元のjsはこう

function insertRecord(item_id, value) {
    db.transaction(function(tx) {
        tx.executeSql(select_count_traininngs, [],
                      function(tx, res) {
                          var lastId = res.rows.item(0).cnt;
                          var dt = new Date();
                          var now = dt.toISOString();
                          tx.executeSql(insert_traininng,
                                        [lastId + 1, 1, user, item_id, value, now],
                                        function(tx, res) { console.log(res); update(); },
                                        function(tx, error) { reportError('sql', error.message); });
        });
    });
}

見た目は近いけど、コールバックで無名関数を渡していることが僕にはわかりにくい。2個目以降の'->'のある部分が全部コールバックで無名関数を渡しているんだけど、たとえば db.transaction (tx) -> の部分とか(tx)以降がdb.transactionの引数だってぱっとわかる?慣れの問題かもしれないけど、ちょっと止まっちゃう。(S式みたいに外側に括弧があればわかりやすいのに!)

javascritpのコードが生成されるのでそれを見ながら直せる

なんかあってるか自信の無いところとかは生成されたjsのコードを見ながら確認したり修正したりできる。

TRY COFFEESCRIPTが便利

http://jashkenas.github.com/coffee-script/のTRY COFFEESCRIPTにペーストしながら書いた。emacsのcoffee-modeをいれたんだけどまだあまり使いこなせてない。きっとこいつでもリアルタイムのjs変換したりできるに違いない。

まとめ

今後もjsをしばらくやってくと思うので、coffeescriptを使ってってみようと思う。