2012年8月26日日曜日

ClojureScript

最近はClojureScriptばかり書いてます。
Clojureを書いてるとJavaを意識しなければいけないことがありますが、ClojureScriptも同じでJavaScriptを意識しなければなりません。
とはいってもJavaScriptを書くよりも遥かに快適なので是非広まって欲しいものです。

今日までにClojureScriptを書いてきて、わかったことを少しまとめようと思います。

clojure.browser


Google Closure Libraryのラッパーで、domやevent、netなどのライブラリがあります。
domとeventを触りましたが、ものすごく中途半端です。
結局goog.domやgoog.eventの関数が必要になるので、 まだまだ発展途上と言えるでしょう。

Closure Libraryの関数はJavaScriptのArrayやObjectを扱うものが多く、ClojureScriptのデータ型を渡すときに少々不便だったりします。
clojure.browserはそういった不満を解消するものとなってほしいです。


ちょっと便利な関数
  • clojure.browser.dom/ensure-element
    • keywordを渡すとgetElementとして、 stringを渡すとhtmlToDocumentFragmentとして動きます
  • clojure.browser.dom/log
    • Console#logです
    • *print-fn*にset!するのが一般的?

ClojureとJavaScript


JavaScriptの世界で生きていくためにはClojureの標準ライブラリの関数だけでは生きていけません。
なので、ClojureScriptにはClojureとJavaScriptの間を取り持つ関数が存在します。
しかし、ドキュメントが少なすぎて存在があまり知られていないように感じます。かなしい。

js-objとarrayは特に重要です。
それぞれObjectとArrayを生成する関数です。
主にClosure Libraryの関数を呼び出す為に使います。
js-keysやjs-deleteなんかも覚えておきましょう。

JavaScriptを直接実行するjs*なんかもありますが、最終手段とするべきでしょう。

array-seqも便利です。
JavaScriptのArray的データ型(NodeList, FileListなど)をClojureScriptのデータ型に変換するものです。
(extend-type Hoge ISeqable (-seq [hoge] (array-seq hoge)))
としておくとClojureScriptのコレクション関連の関数が使えて便利になります。

外部ライブラリ


ちゃんとClojureScriptのライブラリだって存在します。
  • core.match
    • パターンマッチを提供してくれるライブラリ、便利。
  • core.logic
    • JavaScriptで論理プログラミングが出来るよ!やったね!
    • しかしバグあるしあまり期待しないほうがいい。

読まなければいけないもの



ClojureScriptやりましょうず!

2012年8月8日水曜日

手続きと抽象化とScalaz

夏休みです。
コード書きましょう。

現在、UnfilteredとJavaFX使ってなんか創ってます。

Unfiltered


コード例

だいたいこんな感じ。

私はAsynchronousにHttpクライアント使ってほげほげしたいので、async版を使います。

※このコードではHttpクライアント使ってないけど例なのでキニシナイ。

私のプロジェクトではこのサーバーを
  • アプリケーションとして起動
  • JavaFXの裏で起動
という2通りの方法が欲しいのです。

JavaFX


SwingはオワコンなのでJavaFX使いましょう。

コード例

クライアントを起動する前にサーバーを起動したいのですが、いろいろと問題があり、通常のrunメソッドによる起動は出来ません。

そこで、runメソッドで行われているstart, stop, destroyを直接呼ぶことにします。


抽象化


重複したところを考えます。

まずはサーバーを組み立てるところ。
ポートも自由に設定したい。


次にnio.Httpのところ。
shutdownは自動でやって欲しい。
幸い、unfiltered.netty.HttpとApplication.launchはThreadをwaitしてくれるのでローンパターン的にします。
util.control.Exceptionを使うと、try - catch - finallyを生で書く必要がないことがわかりますね!
ナチュラルにScalaz使っていますが、>>>はandThenです。


サーバーの方は十分綺麗になりました。
クライアントのサーバーの起動、終了の部分もローンパターンで書けます。


綺麗になりました。

Scalaz


さて、ここまでが私的Scalaプログラミングですが、まあ、普通過ぎて面白くないですね。
そこで、IOモナドを用いて実装してみます。


まずはサーバーのコード。


SafeAppはIOモナドを暗黙的に実行するためのもので、runcをオーバーライドする事でアプリケーションを構築します。

IO#bracketはtry - finallyのようなもので、リソースを扱うときに使います。

次にクライアント。


アンダーバーが付いた関数は、前の結果を捨てるという意味があります。
Haskellの習慣ですね。



はいおしまい。

IOモナドは便利なのですが、UnfilteredやJavaFXがIOモナド用いた設計をしているわけではないので、少しばかり面倒なところがあります。

告知


第二回スタートScalazやります、多分。