2012年4月21日土曜日

ClojureScriptの導入

ハードル高いと言われてしまったので。

Leiningenの導入


まずはbuild toolの導入です。
https://github.com/technomancy/leiningen
からスクリプトをダウンロードしましょう。
  • Linux
    • Installationの"Download the script"
  • Windows
    •  Installationの"the batch file"
 ダウンロードしたスクリプトはleinと名前を付けて、PATHの通ったところまたはダウンロードした場所にPATHを通しましょう。

ターミナルを立ち上げて

lein self-install

が実行出来ればleiningenの導入は完了です。

Projectの作成


ターミナルで

lein new cljstest

と打ちましょう。
cljstestというプロジェクトが作られます。

作られたプロジェクトのディレクトリには、project.cljが存在します。
これを以下のように書き換えて下さい。


詳しい設定の仕方は
https://github.com/emezeske/lein-cljsbuild

編集ができたら

lein deps
lein cljsbuild auto

を実行して下さい。

core.cljsの編集


cljstest/src/cljstestに存在するcore.cljをcore.cljsにリネームし、以下のように編集します。


ファイルを保存すると自動でコンパイルされ、 cljstestにmain.jsが作成されます。
以下のようなhtmlファイルをcljstestに作り、実行してみましょう。


アラートが出れば完成です。

2012年4月16日月曜日

ClojureScript

最近うぇっぶの勉強が足りないと思い、なんか書いてます。
せっかくだから新しいものに手を出していこうと思い、いろいろと挑戦しています。
使っている言語、ライブラリは
  • Scala
    • Unfiltered
    • Scalate
      • Jade
      • CoffeeScript
      • SASS
    • JavaFX
  • ClojureScript
    • Closure Library
  • Jython
    • Pygments
などなど。
便利なライブラリに驚きつつも、覚えなければいけないことが多くてなかなか大変です。
この中でも特に嵌ったものがClojureScript(Closure Library)。
情報が少ないので調べるのにも結構苦労します。
ClojureScript自体はとてもいいものなので、普及のため/覚え書きに基本的なことを書いていきます。

ClojureScript

ClojureScriptはGoogle Closure Libraryに依存しています!(重要)
なので、ClojureとClosure Libraryの両方を使えるようにならなければなりません!
学習コスト高いですね。しかし、言語的に強力なClojureと強大なライブラリ群のClosure Libraryが合わさっているので最強の環境だと思うのですよ!
なので皆さん是非使って私に教えて下さい。

開発環境


ClojureのデファクトなビルドツールとしてLeiningenがあります。
そして、ClojureScriptをビルドするpluginとしてlein-cljsbuildが存在します。
これなしには開発できないレベルで便利です。
lein cljsbuild auto
とやっておくだけで信じられない速度でcompileしてくれます。
是非使いましょう。

emacsを使っている人は、clojurescript-modeというものもあるので入れておくと便利だと思います。

cljs


では、実際のコードをみてポイントを書いていきたいと思います。


ns


nsはClosure Libraryのprovideの役割を果たします。
(ns hoge)で定義された(def geso)は外部からhoge.gesoでアクセス出来ます。

:require


嵌ります。
:asが必須です。
あとUpperCamelだからといってクラス名と勘違いしないで下さい。
あくまでこれはClojureScriptなのです。
このrequireはClosure Libraryのrequireです。
注意して下さい。
:asで付けたaliasはstatic methodチックに呼び出せます。

参照


Clojureでは書き換え可能な参照を作るのにrefやatomを使いますが、これはJavaScriptなのでそんなことをせずにset!で直接varを書き換えることができます。
あとrefを使ってもSTMが使えるわけではないです。

goog.global


windowやdocumentなどのオブジェクトにアクセスしたい時はgoog.globalを使いましょう。
JavaScript Objectのインスタンスを作りたい時もこれを使うことになると思います。

※追記
goog.globalを使わなくてもjs/Stringのようにglobal objectを参照できました。

総括


とりあえずこんなところかな?
もっとたくさん苦労したところがあった気がする・・・・・
まあ、随時記事を書いていこうと思います。

私はClojure自体は慣れていたのですが、JavaScriptは初心者レベルだしClosure Libraryは触ったことがないしでとても大変でした。
ClojureScriptを書くとしてもJavaScriptがゆるふわなところには振り回されると思うので覚悟しておいて下さい。

2012年3月31日土曜日

play.api.libs.iteratee

明日はPlay Framework 2.0 ソースコードリーディングの会でIterateeのところを任されたのでちょっと使ってみたり。

Iteratee

適当な説明

  • Enumerator -> ストリーム
  • Iteratee -> ストリームに対する処理
  • Enumeratee -> ストリームの各要素に対する処理
以上!




scalaz.iterateeとの比較

Scalazのと比較すると簡単に思える不思議。

Scalaz
  • Scalazではモナド変換子版がベース。
  • IterateeにEnumeratee,Enumeratorを適用する。
  • 型クラスを利用した実装で提供される関数は多い。
  • だが型にうるさい。
  • 明示的に型を指定しなければいけないこともしばしば。

Play
  • Playでは結果がPromiseで返る。
  • EnumeratorにIteratee,Enumerateeを適用する。
  • 内部で使うことが目的なので提供される関数は少ない。
  • まあfoldあれば事足りるよね。
  • 推論が効く!Scalazのより楽だ!

結論:Scalazの方が高機能、Playの方はシンプル

ページ内文字列カウントスクリプト

ワンライナー!


処理を適用していく感じが関数型言語チックでとても書きやすいです。

2012年2月27日月曜日

Trampoline

トランポリンをご存知でしょうか。
相互再帰を最適化するものです。
私はプログラミングClojureを読んではじめて知りました。

相互再帰を最適化すると言っても、既存のものを最適化することは出来ません。
最適化のためには関数をトランポリンを使ったものにしなくてはなりません。

さて、そのトランポリンですが、実はScalazには用意されているのです!

多分6.0.4から入った・・・と思う。
私がStack Overflowで質問したからですね!フフン!

まぁ、たぶん質問しなくても入ってたと思いますが・・・・

なぜTrampolineが入ったのか

以下推測

それは、IOモナドの最適化のためだと思われます。

以前のIOモナドは、>>=で連結していくと評価時にIOの呼び出しが深くなってしまい、StackOverflowErrorを起こしていました。

そこで、トランポリンを導入することで最適化がされました。

命名規則をみると、Scalaz7から輸入されたようです。

なので、IOが問題になっていなかったら、Scalaz6では入っていなかったかも・・・?

使い方

プログラミングClojureの例を参考に偶数、奇数を調べる関数を書いてみる。

まずはトランポリンを使わずに


どれくらいでスタックがあふれるか調べる。


6桁で落ちるとは・・・・

トランポリン版


実行するにはrunメソッドを呼びます。


これは全く落ちない。
あと多分速い。

※追記
遅かった・・・・

結論

プログラミングClojureにあるとおり、なるべく最適なアルゴリズム、自己再帰で書きましょう。
IOモナドのような特殊なケースはあまりないと思います。

さて、このTrampoline、じつはtype aliasです。
type Trampoline [+A] = Free[Function0, A]
と定義されており、Freeがもっと一般化されたなにかであることがわかります。

Freeについてはいつか調べるor誰か調べてくれる・・・はず・・・・・

2012年2月17日金曜日

type Self


に対し、りりかるろじかるさんが反応をくれたので書いてみます。

最初に、これが何の役に立つかですが、


と定義したとき、


となります。

ポイントは、
  • Barからfを呼び出すとBarが返る。
  • Barからgを呼び出すとOption[Bar]が返る。
  • fの返り値からhを呼び出せる。
といったところでしょうか。

つまり、スーパークラスでサブクラスの値を返すことができるということです。

しかし、これにはサブクラスがいちいちSelfを定義しなければいけないので楽したいですよね。
そこで、りりろじさんに考えて頂いた方法を書いていきます。

this.type

this.typeを使って定義すると、


となります。

Bar.this.typeが要求されているところでBarを渡すとコンパイルエラーがでます。
なので、asInstanceOfを使って定義します。


なんかエラー出てる・・・・
うーん、これはどういうことでしょう?
gの返り値をOption[this.type]と明示的に書いても変わりません。
むむむむむ・・・・・えらいひと、教えて下さい。

型パラメータ

Genericsまんせー
ということで書いてみる。


おお、ちゃんと動きますね。

この型パラメータ版とtype Self版で比べてみると、
  • 型パラメータ有無
  • どちらも、型の情報がなくなると意味がない
  • 継承元がtype Selfを書くか、型パラメータに型を書くか
などあります。

型パラメータを使ったほうが楽に書けそうですが、type Selfを使うと楽になることもあります。


このように、複数のtraitでSelfを使う場合はこの書き方が有利なようです。


他にもっといい方法があったら是非教えてくださいねー!

2012年2月11日土曜日

Scalaでポイントフリースタイル

関数合成の話がTLであったので書いてみる。

最近だとゆろよろさんの記事が面白い。
http://d.hatena.ne.jp/yuroyoro/20120203/1328248662
http://d.hatena.ne.jp/yuroyoro/20120206/1328513534

Category

とりあえずCategoryから。

Categoryとか知らない人は
https://github.com/quassia88/introduction-to-category-theory-in-scala-jp/wiki
を見て、なんとなく分かってみてください。

この圏論入門の記事だとCategoryのインスタンスはFunctionしか書いてなくて、抽象化をしていることがわかりにくいですが、ScalazではCategoryのインスタンスにFunction, PartialFunction, Kleisliがあります。

※コード例はScalaz7


idが恒等関数、composeが合成関数です。

>>>, <<<というシンタックスもあります。


Arrow

究極的には関数合成だけでプログラムを書くこともできますが、>>>だけではなかなか難しいところがあります。

そこで登場するものが***と&&&。
この2つは関数を並列に合成します。

***はA => BとC => Dから(A, C) => (B, D)を返します。
&&&はA => BとA => CからA => (B, C)を返します。



関数合成を意識して、n番目のフィボナッチ数を得る関数を書いてみます。


|>はパイプ演算子と言われるもので、値を関数に適用するものです。

並列合成の使いどころは、ある値を複数回使うときです。

ScalazではTupleでfoldが使えるので別々に計算したものを簡単にまとめることが出来ます。

Scalaでも、Let's point free!

2012年2月5日日曜日

ClojureとFXMLとRuby

この前Clojureで試したのですが、fx:idが使えず微妙な感じでしたが、解決方法を見つけました!

JavaFXではfx:scriptタグというのがありますよね?

このタグにJavaScriptのコードを書いているサンプルコードをよく見ますが、実はこれ、
JavaScript以外でも動くのですよ!

いや、まずJavaScriptが動いているという時点でなにか疑問を持たなければいけなかったのですが。

fx:script

この機能はJSR-223で実現されています。
恐らく。

この機能標準ライブラリにあることを最近知りました。
わざわざダウンロードしていたのは何だったのか・・・・・

fx:scriptを使うためには、言語を指定します。

この時に、FXMLLoaderはgetEngineByNameを使ってスクリプトを実行するためのScriptEngineを取得します。

なので、JSR-223に対応している言語ならば動くのですよ!

とりあえず、安定して動きそうなJRubyを試してみました。


実行



なぜか重いけど動く・・・!

eventはグローバルな変数で、アクションを起こしたい時はこいつを渡しておけばいいようです。

JRubyではgetは書かなくていいし、setも=を使って書けるしなかなか楽ですね。

fx:id

さて、これでfx:idの値を参照してみます。


実行



動いたー!

Clojureで試す

なぜ最初からClojureで動かさなかったのか、それは動かなかったからです。

で動かしてみましょう、ぬるぽが出るはずです。

そこで、"clojure jsr 223"でぐぐってみるとこんなプロジェクトが。
http://code.google.com/p/clojure-jsr223/

そう、clojure標準ではJSR-223に対応していなかったのです。

なのでこのライブラリをdependenciesに追加すれば動くようになります。


fx:scriptを後ろに置いたのは、labelが見えないと怒られるからです。


これにてこの問題は解決です。

メジャーなScript言語はJavaFXで動くので、是非試してみて下さい。