2012年12月21日金曜日

Konst

この記事はScalaz Advent Calendarの20日目の記事です。

ScalaにはFunction.constという常に一定の値を返す関数があります。


この関数を型レベルで表したものがScalazにKonstとして定義されています。

Konst


NaturalTransformationを例にKonstを使ってみます。


あまり使わなさそうですね!
私としてはまだScalaz6にあったPartialApplyの方が便利な気がするのですが。
まあ、型推論がうまくいかなかったり、Unapplyが新しく入ったりしたことが原因にあるのでしょうね。

2012年12月18日火曜日

Scalazのかきかた


というわけで、Scalaz Advent Calendarの18日目の記事です。

Scalazには多くの型クラスとそのインスタンスが定義されており、それを扱うために、多くの記法が存在します。
この記事では簡単で冗長な記法から、複雑で簡素な記法まで紹介していきます。

インスタンスの取得


implicit valueとして定義されている型クラスのインスタンスは、implicit parameterにより取得が可能です。

そのインスタンスの取得にも様々方法があります。

implicitly

Scala標準ライブラリに定義されている、implicit valueを取得する関数です。


TypeClass

また、Scalazの型クラスにはインスタンスの取得のための関数、TypeClass.applyを使用することができます。


関数呼び出し


ある型クラスの関数を使用するとき、先ほどのようにインスタンスから直接呼び出すことができます。


Ops

しかし、明示的に型クラスのインスタンスを取得するのは冗長です。
Scalazではimplicit conversionを用いて、型クラスのインスタンスをもつオブジェクトに対して暗黙の型変換を提供します。


暗黙型変換の他にも、単一のオブジェクトを対象としない型クラスの関数がインポートされます。


関数定義


関数を定義するとき、implicit parameterを指定する方法が2つあります。

implicit

1つはimplicitを使う方法です。


Context Bounds

もう1つ、Context Boundsというものが存在します。


インスタンスを明示的に扱わない場合はContex Boundsで定義した方が良いでしょう。


Syntax


大抵の場合の場合はOpsとContex Boundsで短いコードが得られますが、これらを使っても冗長になる場合があります。


Scalaでは返り値の型を指定してもimplicit valueを決定することは出来ないので明示的に型を書く必要があります。
このような場合、Syntaxを使うことで明示的に型を指定する必要がなくなります。


まとめ


短く簡素なコードになるほど、複雑な仕組みが使われていきます。
大抵のものはContex BoundsとOpsで短いコードになるので、積極的に使っていきましょう。
型クラスのインスタンスから直接関数を呼ぶのも良いですが、Syntaxをimportした方が簡素になる場合があることも頭に入れておくと良いでしょう。

2012年12月17日月曜日

JavaFX & Web Start with Clojure

This article is the 5th of JavaFX Advent Calendar and a sequel of Tic-tac-toe with Clojure.

Tic-tac-toe

Since the logic of the game have been made, we only need to implement at the drawing.

Application


As the basis for JavaFX, inherit javafx.application.Application to the main class.

In order to compile the class files of Java, we use the gen-class.

In the main method calls Application.launch.

In the start method implements tic-tac-toe.game.Canvas and register the handler in each panel.

doto is useful when using the GUI library in Clojure.
We can run continuously some methods under the instance.
It is like the instance_eval in Ruby.

Such an interface as EventHandler is obtained an instance by using reify.

Web Start


First, make a standalone jar file with lein2 uberjar.

Then create a jnlp file.

The all-permissions are needed to run Clojure.

We must make a signature, because it requires all-permissions.

You can make the keystore by keytool, and sign the jar using jarsigner.

keytool -genkey -keystore foo -alias bar
jarsigner -keystore foo target/tic-tac-toe-0.1.0-SNAPSHOT-standalone.jar bar

You can start with Web Start.

If you try on local environment, rewrite the codebase of jnlp file.

Miscellaneous Thoughts


I think that JavaFX is simpler than Swing and we would be able to write the GUI application easily.

But I felt that the Web Start is not suitable for other required language runtime, such as the Scala and Clojure.
Because file size becomes very large.

2012年12月15日土曜日

UndoT

この記事はScalaz Advent Calendarの15日目の記事です。

scalazのcoreのjarに含まれ、独自のパッケージが存在しながらも、全く話題に上がらないundoについて書きます。

scalaz.undo以下にはUndoTとHistoryの2つのデータ型があります。

UndoはHistoryを状態とするStateモナドで、Historyはundo, redoの為のListと、currentのデータを持ちます。

例を作ってみます。

この時、Historyはこのように変遷しています。

History("initialize", Nil, Nil) // eval("initialize")
History("hello", List("initialize"), Nil) // hput("hello")
History("world", List("hello", "initialize"), Nil) // hput("world")
History("hello", List("initialize"), List("world")) // undo
History("world", List("hello", "initialize"), Nil) // redo


これを使っているユーザーがどれだけいるのか気になるところです。

これだけでは物足りないと思ったので、MonadStateについて書こうと思いましたが、UndoTのMonadStateのインスタンスの定義がおかしい気がする。

なので今日はpull requestを投げて終わります。

2012年12月13日木曜日

Codensity

この記事はScalaz Advent Calendarの13日目の記事です。

Codensityについてググると、

The Mother of all Monads

という記事が見つかる。
Codensityは継続モナドとほぼ同じものみたい。

この記事にある例をScalaで書いてみる。

Option

Disjunction

なるほど。
CodensityがOptionやDisjunctionとして動く。

でもこれってIdTじゃ(ry

Codensityは継続モナドのようなもの、ということで継続らしい例を書いてみる。

iprintで、計算の経過を表示する。

Some(bar)とNoneが表示される。

継続を破棄するbreakを定義し、for式で使ってみる。

Some(bar)だけが表示される。

無事、計算が破棄された。

Codensityはあるモナドにおいて計算量を減らせることがわかった。
他にも何か出来そうだが、わたしが思いついたのはこれくらい。

2012年12月9日日曜日

Injectiveを考える

この記事はScalaz Advent Calendarの9日目の記事です。

この記事に書いてあることは役にたたないと思うので、あまり気合を入れて読まないでください。

Injective


Scalazには、Injectively, Injective1 ~ Injective5が定義されている。
よくわからない。

Injectiveをググってみると、どうやら単射のことっぽい。

Injectiveは型パラメータをとる型を型引数にとる。
つまり、種(カインド)が* -> *や、* -> * -> *である型が単射であるいう制約をつけるものではないかと考えた。

とりあえずInjectiveの例を列挙してみる。

List

ふつうに定義できる。

type member

Hoge#Fは未定義なので、インスタンスの供給は出来ない。

dependent method types

明示的にインスタンスを渡す必要はあるが、コンパイルすることは可能。


ふむ、よくわからない。

単射にならない型がもしあるのだとしたら、F[_]に対して、ある型Aを渡した時にコンパイルが通らないということだろうか。
ということは、F[_]がとりうる型に対して制約をかければよいということだろう。

次のような例を書いた。

なるほど。
確かに、単射ではないからInjectiveのインスタンスが定義出来ない。

Injectiveの意味がようやく理解できた。

InjectiveはLiskovのコードで使われているが、まあ、よくわからない。
わからなくても、この先困るということもないと思う。

2012年12月5日水曜日

ClojureでJavaFX & Web Start

JavaFX Advent Calendar 2012
5日目の記事です。

三目並べ

Cojureで三目並べの続き。

ここでは三目並べのJavaFX実装について書きます。

ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。

Application


JavaFXの基本として、メインクラスにjavafx.application.Applicationを継承します。

ここではgen-classを使って、Javaのclassファイルにコンパイルします。

mainメソッドではApplication.launchを呼び出します。

あとはstartメソッドでtic-tac-toe.game.Canvasを実装し、各パネルにhandlerを登録します。

ClojureでGUIライブラリを使うときに便利なのがdoto。
あるインスタンスのもとで、メソッドを連続して実行することが出来ます。
Rubyのinstance_evalのようなものですね。

EventHandlerなどのインターフェースはreifyを使うことで実体を得られます。

Web Start


JavaFX Script時代にはいくつかWeb Startのアプリケーションを作ったことが
ありましたが、JavaFX 2になってからは初のWeb Startです。

まずは、lein2 uberjarでstandaloneなjarを作ります。
20MBもあるのはClojure+JavaFXのclassファイルが入ってる所為です。

次にjnlpですが、こんな感じになりました。

all-permissionsになっているのはClojureを実行するためです。
多分JRubyやGroovyでもall-permissionsが必要になるはず。

all-permissionsを要求するので、署名をしなければなりません。
keytoolで適当なkeystoreを作ります。

keytool -genkey -keystore foo -alias bar

fooというファイルが作られるので、jarsignerを使ってjarに署名します。

jarsigner -keystore foo target/tic-tac-toe-0.1.0-SNAPSHOT-standalone.jar bar

これでWeb Startで起動できます。
実際に試す場合はjnlpファイルのcodebaseを

codebase="file:/home/halcat0x15a/tic-tac-toe/"

のように書き替え、

javaws tic_tac_toe.jnlp

で実行可能です。

雑感


このプログラムではたいしたことをしていませんが、JavaFXのおかげで、Swingよりもシンプルで簡単にGUIを書けるようになったと思います。
他のGUIライブラリと比べても、ライブラリの設計は格段に良くなったと感じます。

Web Startは、ScalaやClojureなどのランタイムが他に必要な言語にはあまりむかないのかなと感じました。
プログラム+ライブラリ+ランタイムとなると、かなりファイルサイズが大きくなってしまいます。

ClojureScriptでgoog.graphics

altjs Advent Calendar 2012
5日目の記事です。

三目並べ

Cojureで三目並べの続き。

ここでは三目並べのClojureScriptによる実装について書きます。

ゲームのロジックは作ってあるのであとは描画のところを実装するだけ。

goog.graphics


描画にはgoog.graphicsを使うことにします。

ClojureScriptはGoogle Closure Libraryで実装されており、nsでJavaScriptのライブラリをrequireすることが出来ます。

各種定数。

tic-tac-toe.game.Canvasを実装します。

main関数を定義します。

HTMLはコンパイルされたJavaScriptを読み込み、main関数を呼び出します。

これで動いてほしいところですが、cljs.core.logicがバグってるので、コンパイルされた.jsの修正が必要です。
cljs.core.logic.macros._take_STAR_のところをcljs.core.logic._take_STAR_に変更します。

masterでは直ってますが、修正版がpublishされていないのが悲しいですね。

雑感


いままでもClojureScriptについていろいろ書いてますが、やはりClojureは書いてて楽しいです。                                                            
最近はprotocolとrecordとmacroが好みです。                                                                                                           

論理プログラミングで書いたコードがWeb上で動いているのはなかなかおもしろいと思うのですが、コンパイルされたJavaScriptのコードをみるとものすごくカオスです。

Google Closure Compilerによるアシストがあるとはいえ、ファイルサイズは比較的大きくなるので、注意です。

cljsbuildのおかげで、今回のようなJVMとWebの両方で動くようなコードが書けるので、これからClojureScriptを使う人には是非知ってもらいたいものです。

Clojureで三目並べ

Lisp Advent Calendar 2012
6日目の記事です。

三目並べ

ここでは三目並べソルバについて書きます。

tic tac toe


三目並べ、すなわち◯×ゲームです。
小学生の頃とかやってました。
このゲームは両者が最善を尽せば必ず引分けになるゲームで、その最善手もわかりやすいので他人とやってもだいたいドローになります。

この三目並べで盤面から次の手を返すプログラムを、ClojureとClojureScriptの両方で動くように作成します。

core.logic


今回は論理プログラミングでこのパズルを解きます。

最初にnamespaceですが、ClojureとClojureScriptの両方で動かす為に、多少の黒魔術があります。

;*CLJSBUILD-REMOVE*;はcljsbuildがビルド時に削除してくれるコメントです。
core.logicがclj版とcljs版で違うnamespaceを使っているのでこうなっています。

盤面で、空いているところはnilとします。
not-nil?という述語を作るために、!=を使いたいところですがcljs版に存在しないのでprojectを使います。

projectはcore.logicで使われている変数にあたるものから値を取り出します。

盤面が空いていたらコマを置く述語write。

コマが2連続で続いていたら自分であろうと相手であろうと決着します。
そのため、コマを優先して置く述語checkを定義します。

これで補助の述語の定義は終りです。
あとは愚直に盤面を検査します。

checkやwriteの順番を並べ変えると強くなったり弱くなったりします。
ここではなるべく中心にコマを置くように書いています。

盤面から次の手を返す述語が定義できました。
もう1つ、ゲームが終了したか調べる述語も定義します。

実際の使い方はこんな感じ。

敵味方の区別をつけていないので思った通りの手が返ってきていませんが、勝てないというのもつまらないのでこのままにします(手抜き)。

これらの関数を使い、ゲームのロジックを書きます。

Canvasプロトコルを実装し、play関数を各パネルをクリックした時のhandlerとして登録することで動きます。

JavaFXによる実装goog.graphicsによる実装を書きました。

雑感


core.logicによる論理プログラミングは慣れていないせいか、とても頭をつかいました。
完成したコードは愚直だけれど分かり易いものになりました。
こういった書き方が出来ることが論理プログラミングの1つの利点でもあると思います。

ゲームのロジックに関してはあまり綺麗に書けなかったのですが、各ライブラリと協調できるうまい書き方を知りたいものです。

2012年12月1日土曜日

Isomorphism

Scalaz Advent Calendar!

Isomorphism


あるcase classに対してMonoidを定義したいとき、大体のものはTupleのMonoidのインスタンスが使えると思います。
こんなときにIsomorphismMonoidが使えます。

Monoid以外の型クラスを定義したい時もこんな感じで使える。

このように、データ構造が同じもののインスタンスを流用する場合はIsomorphismが使えます。

<=>[A, B]はIso[Function1, A, B]のtype aliasで、to: A => Bとfrom: B => Aを定義します。
IsomorphismMonoidなどの型クラスは、toを使って実装されていることに注意しましょう。

2012年10月31日水曜日

ClojureでLisp評価器

SICP読書会、毎週月曜19時からmixiでやってます。
現在第4章の超循環評価器を作っています。

4章の一番最初に出てくるevalの定義は以下の通り

とてもわかりやすいけど、データ主導にしたいよね、そうしよう、というのが問題4.3にあります。

これをClojureっぽく書くことを考えてみる。

Protocol


ClojureといったらやっぱProtocolだよね!ということでプロトコルベースで考える。
とりあえず評価器プロトコル、Eval(uator)の定義

このプロトコルを実装したリテラルの評価器を書いてみる。

部分関数っぽくしたいのだけど、例外を投げるか迷った。
今回はとりあえずこれで。

このように、小さな評価器をいっぱい作って合成していくという考え方。

special form


ifやdefineやbeginなんかのspecial formをチェックする関数tagged?の定義

先頭要素を比較するだけ。

これを使って、special formを以下のように表してみる

Specialを使ったquote


if


ifは式を評価しなければいけない。
しかし、どの評価器を使えばいいのかわからない。

評価器を引数にとるという選択肢もあるけど、不都合がある。

この式を評価するとよくわからないエラーが投げられると思う。
ここでは評価機が部分適用されたeval関数をとることにする。


compose


一番大事な評価器を合成する関数

やっていることは簡単、引数の先頭の評価器から順に、式を評価器で評価して失敗したら次の評価器で評価するという評価器を作っているだけ。

これを使ってifとliteralだけが使えるlispを定義すると以下のようになる。

実行

ヤッター

まとめ


こんな感じで小さな評価器を書いていって大きな評価器を作っています。
なかなか楽しい。

今回のプログラムはScalaBaseで@maeda_さんが発表されていた、Javascript as an Embedded DSLに触発されて書いてみました。
おもしろいので読んでみるとよいです。

次はぱーさーこんびねーたについて書く、書きたい、書けたらいいな。

2012年10月27日土曜日

Clojureのエラー処理

Clojureでエラー値を返すかもしれない関数ってどう書くのだろうとちょっと考えてみる。

Scalaだと例外はあまり使わず、EitherやValidationを使う派。
やはり、コンパイラの恩恵を受けることが出来る書き方が良い。

しかし、Clojureは動的型付けの言語。
コンパイラの恩恵は特にない。

なので、 どのような値が返ると扱いやすいかを考える。

Clojureは基本的に
  • nil返す
  • 例外投げる
の2通りだと思う。

Clojure標準のライブラリはnilを渡してもそれなりに動作するし、if-let,when-let,fnilなどの関数も用意されている。
しかし、nilだとどのようなエラーだったのか判別がつかない。
このような時に例外を使って、エラーの種類によって投げる例外を変えれば良いのだと思う。

Clojureの例外を投げるような関数は以下のように書ける。

この場合は、Java APIのIllegalArgumentExceptionとIndexOutOfBoundsExceptionを使った。
しかし、何時でもJava APIに自分が欲しいExceptionが定義されているわけではない。
このような時は、独自の例外を作るだろう。

駄菓子菓子!

Clojureでclassを定義するのはとても面倒。
nsgen-classを見てもらえればわかると思う。
Throwableがinterfaceならば、deftypeやdefrecordが使えたのだけれど・・・

例外を定義する部分だけJavaで書いたほうが楽かも。

leiningenはJavaもサポートしているので、共存させるのは苦ではない。

結論


基本的にnilを返す。
独自の例外を定義したかったらJavaを使うと楽

2012年10月13日土曜日

Clojureでモナド内包表記とStateモナド

cljsbuildのcrossoversという機能を知らない所為で今まで無駄に苦労してきましたが、これでマクロが使えないという制約から解き放たれました。
万歳!cljsbuild!

マクロが使えるようになってまず一番最初にやることは何か?
もちろん、モナド内包表記の実現ですね!

HaskellのdoよりはScalaのforの方が慣れているのでこちらを採用しました。

動的型付けの言語でのモナドの実現はいくつか見てきましたが、明示的にコンテキストを指定するタイプはあまり好かないので、ClojureらしくProtocolで表現することにしました。

Monadic Protocol


通常モナドはunitとbindが実装され、モナド則
  • bind f (unit x) == f x
  • bind unit m == m
  • あともう一個なんかあった気がする
を満たしますが、動的型付けの言語でunitを実現するのは面倒なので、モナドっぽいインターフェースを定義します。

このインターフェースが実装されていれば、モナド内包表記が使えるようになります。
とてもScala的。

モナド内包表記


Lispは神の言語と皆ネタにしていますが、Lispのマクロは本当に強力です。
既存の言語にある構文の全てはLispのマクロで表現できるのではと思えるくらいです。

Clojureの標準ライブラリではパターンマッチが出来ないので、準標準ライブラリであるcontribのcore.matchを使います。

しんぷるいずべすと、MonadPlusなんて知らないのでガードは実装しません。めんどい。

このdo-mマクロがどのように展開してくれるかというと



こんな感じになります。

実際に動かしてみます。

動いたー!
素敵です。

Stateモナド


私が現在製作中のアプリケーションでは、レコードを更新する関数が多数定義されています。
これは、状態をとって、新しい状態を返す関数ですが、少し問題があります。

一つ例を示します。

このような関数が定義されていた時、右下へ移動する関数を定義するのに->>マクロを使い、手続き的に書くことができます。

しかし、このrightでの計算結果、つまりxを使う関数を定義する時、コードはこのようになります。

このパターンが関数内で頻出する場合、一時的なcursorの状態を保存する為の変数が増えてしまいます。
さらに、この場合はxを取得するコストは微々たるものですが、フィールドの取得に複雑なロジックを用いたり、計算値が状態の更新に間接的に使われるだけで、レコードからは取得できない場合があります。

新しい状態だけを返すのではなく、計算値とのペアで返せばこのパターンを解決できます。

しかし、->>マクロのようにネストせずに書けるわけではありません。

そこでStateモナドの出番です!(導入長い!

Stateモナドは状態を取り、新しい状態と計算値のペアで返す関数に対してモナドを定義したものです。

先ほど定義したMonadicをStateに実装してみます。

right, down関数をStateで定義してみます。

この時、square関数はdo-mを使って以下のように定義できます。

ヤッター!

関数の合成が手続き的に書けますね。

まとめ


マクロ強力。Stateモナド美しい。

本当はFreeモナド使おうと思ったけどStateモナドの素晴らしさを伝えたかったので控えました。

これから70個近い関数をStaeモナドに書き換える作業が待ってます。
Freeモナドの資料も作らなきゃですね。
私の代わりに大学のC言語の課題をやってくれるといいと思います。

2012年10月3日水曜日

Clojureへの不満とか

最近はClojureばかり書いているので、良い所ばかりでなく、気になるところも見えてきました。

なにか意見をもらえるかもしれないので書き並べておきます。

セルフホスティングして欲しい


Clojureのソースコードを読むときに、高確率でJavaのコードを読まなければいけないので悲しくなります。
やはり、gen-classとかでは物足りないのかなあ?
それとも、セルフホスティングにはあまりヤル気がないのか・・・・

clojure.langのJavaDoc欲しい


ソースコード追うのが面倒なので。

Protocolをもっと使って欲しい


自分で新しいデータ型を作った時に、既存の関数を使うためにclojure.langの得体の知れないinterfaceを実装するわけですが、Protocolとして存在すればClojureの中で完結するのでうれしいのだけど、これはデータ型がJavaに依存しすぎてて簡単にはいかないんだろうなあと。

関数が返す値は適用する値と同じデータ型で返して欲しい


特にStringとか。
charのシーケンスで返ってくるのが悲しい。
これはなぜだろう、効率のためかな?
どこかで読んだ気がしなくもない。

いっそのことClojure独自に文字列作るというのは・・・・まあ、それはそれで面倒臭そう。

Scalazは独自にCordというデータ型を定義しています。
さすが、尖ってる。

insertしたい


ArrayListLinkedListを使えばいいのですが、functionalでpurelyなdata structureが欲しいわけです。

Arrowが欲しい


Haskellのfirst,secondに当たるものが欲しい。
分配束縛したくない。
もっとポイントフリーなプログラミングがしたいのです。

しかし、comppartialjuxtでやりすぎたコードを書くのには注意です。

if-let, when-letが1つの変数しか束縛できない


なぜ複数束縛できないのか・・・・・

要素を1つだけ持つlistとmapmapcatまたはforを使って、Maybeモナドっぽいことは出来ます。
あとは(fn [a] (if (nil? a) (list) (list a)))のようなものがあるといいのだけど。

do記法、for内包、コンピュテーション式にあたるものが欲しい


for内包はあることにはあります。
しかし、これはSequableでSequentialなデータ型(JavaのIterableとIteratorのようなもの?)の為のもので、モナドの為のマクロではないです。

Maybeモナドやdo記法はalgo.monadsで提供されていますが、あまり設計に納得がいかない。
私はあるデータ型に対してモナドを定義したいので、Protocolをベースに設計したものが欲しかった。

限定継続が欲しい


do記法がないなら限定継続を使えばいいじゃないと昔の貴族は言ったものです。
限定継続があれば括弧を減らせるような構文がいろいろと簡単に定義できそうだなあと思い挙げてみた。 

delimicといものがあるらしい。

まとめ


私はいままではScalaばかり書いていましたが、いまはClojureばかり書いているのでこのような記事を書いています。
実際には2年前くらいから少しずつ書いていましたが、これほどClojureを書いてる期間はありませんでした。

Scalaに触れ、さらにScalazに触れたことで完全に関数型プログラミング信者になってしまいましたが、実際に有用な技法を多く知ることが出来ました。
それをClojureで実現するために、このような贅沢な不満が出てきました。

Clojureはまだまだ若い言語だと思うので、あれもこれもと求め過ぎていると思います。
なので、今後私が期待しているものに発展してくれるようClojureに貢献していきたいです。

2012年9月13日木曜日

ClojureScriptのテスト

皆さんテスト書いてますか?
私はあまり書いてません。
テストは大事です、書きましょう。

私は現在ClojureScriptを使っているのですが、JavaScriptでのテスト方法とかよくわからないし、Clojureでテスト書きたいので、ClojureからClojureScriptを読み込もうという考えに至りました。

が、しかし。
requireなどを使って、ClojureScriptのコードを読み込むことはできませんでした。
なぜなら拡張子がcljsだから。
load-fileなども使ってみましたが、無理でした。
ClojureScriptのコードの中でrequireを使っているからです。

どうにかして拡張子がclj,classのファイル以外を読み込むことはできないのかと調べてみたところ・・・・

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L403

ベタ書き・・・!
差し替えることなど到底無理っぽい。

ならば作るしかありません、cljファイルを。


copyしてuseしてdeleteする、悲しみあふれるコード。
cleanupのところはtry-finallyした方が良いかも。

clojure.testはfailした時にマクロを利用して述語に渡した値を展開してくれたりでなかなか便利なので割と好きです。
しかし、ここまでして使うのもどうかなと。

素直にJavaScriptのテストフレームワークを使うとか、assertで済ませる(ClojureScript本体のテスト方法)などでいいかもしれません。

2012年9月10日月曜日

Scalaでdo記法

函数プログラミングの集いで限定継続の話が面白かったので書いておきます。

ScalaでもHaskellのdo記法っぽく書ける。

調度良くScalaでHaskellしてる記事があったので、これを参考にさせていただきます。

\めんどい/

2012年9月5日水曜日

Clojureのinsert

Clojureでlistやvectorのn番目に値をinsertしたい時はありませんか?
Clojureには標準でlistやvectorに対するinsertが定義されていません。
でもzipperにはinsertがあるみたい。
そこでvectorとzipper、どちらのinsertが速いか測ってみました。

コード


結果


ClojureScript

Clojure

思っていたよりは差がつかなかった。

vectorやlistはいつもこんな感じでinsertしてるのですが、もっと綺麗で効率のよい方法があったら教えて下さい。

効率のよいinsertが出来るシーケンスを標準で用意してくれてもいいのではと思わなくもないです。

2012年9月1日土曜日

Machines

先日rpscalaに行った時、@xuwei_kさんにscala-machinesというものを教えてもらったので調べてみました。

Example.scalaを参考に、コードを読んでいきます。

少々書き換えました。

ぱっと見ても全くわからないですね。

IO


副作用(アクション)を表します。
IO.applyは値をcall by nameでとります。
unsafePerformIOを呼ぶことで、アクションを実行します。

bufferFile


ファイルをとってBufferedReaderを返す関数です。
IOでラップしています。

rReadLn


BufferedReaderから一行読み取ります。
readLineは文字列かnullを返すのでOption.applyを使用しています。
これもIOでラップしています。

closeReader


Readerを閉じます。
当然副作用なのでIOでラップされます。

Process


Process[I, O]はI => Oをラップしたものと考えていい・・・・はず。
Process[I, O]はMachine[I => Any, O]のシノニムで、Machine[K, O]はPlan[K, O, Nothing]のシノニムなので、実体はPlanなわけですが、まだ私は理解できていません。
IterateeのIteratee,Enumeratee,Enumeratorの内のIterateeにあたるようなものだと思われます。
なのでストリームの要素はこいつを使って処理していきます。

countLn


文字列をとって1を返すProcessです。

getFileLines


型パラメータAとProcess[String, A]とFileをとり、Procedure[IO, A]を返します。
モナド変換子と同じく、Procedureから値Aを取り出す時にIOにラップされるようになります。
ProcedureはEnumeratorのようなもので、ストリームとそれを処理するMachineを持ちます。
ProcedureはMachineの第一型パラメータとMachine、抽象メソッドのwithDriverを定義します。
Process[I, O]は先述の通りMachine[I => Any, O]と定義されているので、抽象タイプメンバにはString => Any、Machineは引数としてとったProcessで定義します。
Driverでは入力を定義するのですが、当然、入力にはリソースが必要になります。
そこで、このwithDriverではリソースの作成、開放、Driver(入力)の作成、Driverの適用を定義します。
リソースの作成はbufferedReaderを使います。
IO#bracket(f)(g)は処理gの後に必ず処理fが処理されます。
事後処理としてcloseReaderを渡し、Driverの作成と適用をします。
DriverにはrReadLnを使い、入力を適用するapplyを定義します。
最後にwithDriverがとる関数kにDriverを適用します。

exec


ファイルを関数に適用し、実行、出力する関数です。
executeはProcedureの結果の型Aがモノイドである必要があります。
ストリームを処理した結果をaccumulatorに加える関数で合成していきます。

runc


main関数で呼ばれる関数で、裏でunsafePerformIOを呼びます。

CSVファイルの読み込みと要素のカウントを書いてみた。

まとめ


IterateeよりはIOに特化していると思われる。
リソースの処理をProcedureでやっているところとか。
ProcessやProcedureを自分で書くのは、IterateeやEnumeratorを自分で書くよりは楽・・・・な気がしなくもない。

今回は本当にExampleをさわっただけで、詳細はわかっていない。
作者のドキュメントに期待です。

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やります、多分。

2012年7月2日月曜日

core.logic

clojureのcontribをながめてるとcore.logicなるものが。

なにやらClojureで論理プログラミングをするためのものらしいのでいろいろと試してみた。

よく例に出るappendの例。


xとyが連結するリスト、zが連結後のリストです。
xが空ならyとzは同じ。
xの先頭とzの先頭が同じなら、xのテールとyを連結したzのテールになる。

普通の関数で書いたらこんな感じ?



しかし、普通の関数と違ってかなり高機能です。

実行してみます。


なんと、append一つ定義するだけで連結・差分・組み合わせの三つの使い方が出来るのです!

おー、論理プログラミングすげー

さらに、ClojureScript版も用意されています。

上記のappendのコードは動きますが、clojure.core.logicと比べると定義されている関数やマクロは少ないです。
バグってたりします。

数独も解いてみた。


数字の扱いが微妙なのでリストで数字を表してみました。

しかしこのコード、正しいパズルかどうかはテストしてくれますが、パズルを解決してくれません。

!=を使っているから・・・・?

まあ、まだまだ開発途中なので今後に期待です。

2012年6月27日水曜日

Stateもなど

Stateモナドの有用性を考えるために書いてみます。


Rangeオブジェクトはカーソルが指すNodeとoffsetを持っています。
getRangeは現在のRangeを返すものとします。
moveはそのRangeにカーソル移動するものとします。
nextNodeとprevNodeはそれぞれ次のNodeと前のNodeを返します。

getRange,nextNode,prevNode,moveは擬似的なものなので、定義は気にしないで下さい。
この4つの関数は参照透過とかそんなわけないのでIOを返します。

これらに対して、4方向にカーソルを動かす関数を定義します。


IOはモナドなのでforが使えます。
predとsuccはscalaz.Enumのシンタックスでデクリメントとインクリメントのようなものです。

実際には移動するときに、offsetなどを調べるものですが、OptionT[IO, Unit]などと複雑になるので省略します。
これらの関数を組み合わせてみます。


さて、これらの関数、ちょっと冗長ですね。
いちいちmoveを実行しているところもいただけません。

これらをStateを使って書きなおしてみます。


squaredは値をペアにして返します。

同じように、合成したStateとそれを使って移動する関数を定義します。


getRangeとmoveの呼び出しは1回で済むようになりました。
movemovemoveというStateを使い回すことも出来ます。

さらに、Stateモナドであることを活かして、次のようなStateを定義することが出来ます。


移動した直後の状態を扱えるのがStateモナドの利点ですね。



最近は大学生がなかなか忙しいです。
俺、定期試験が終わったらScalaz勉強会開くんだ・・・・・

2012年6月23日土曜日

Pythonの復習

最近Pythonさわってなかったので。

FizzBuzz



なんのへんてつもないコード。

yield使って、generatorにしてみる。


このケースならitertoolsを使ったほうがカッコイイ。


countはnからstep(デフォルトは1)づつ増えていくgeneratorを作る関数です。
mapはいつの間にかイテレータに対応してくれてました。

素数


判定を書く


functoolsとoperatorで関数型っぽく書けて素敵ですね。
functools.partialは部分適用、operator.modは剰余です。

素数列を作る


なかなかいい感じ。

フィボナッチ数列


n番目のフィボナッチ数を返す関数


dict使って分岐する


switch的なものはdictで代用できるのでもーまんたいですね。
getの第二引数はキーが存在しない場合返ります。

イテレータ版


Pythonはなかなか関数型言語ちっくに書けて素敵ですね。
Rから始まる4文字のプログラミング言語より関数型っぽいです。

2012年6月10日日曜日

Proof with Scala

※今回はScala2.10.0-M3を使います。

ある型クラスのインスタンスを定義するとき、何らかの規則を満たす必要があるときがあります。

例えばMonadだとモナド則。
bind,returnを定義するときに、以下のものが満たされないといけません。

bind (return a) f = f a
bind m return = m
bind (bind m f) g = bind m (fun x => bind (f x) g)

しかし、Scalazの型クラスなどはモナド則を満たしているかどうかを検査してくれるわけではありません。

そこで、コンパイル時に規則を満たしているかどうかを検査するように型クラスを定義してみます。

Monoidを例に考えます。


ScalazのMonoidの定義と違うところは、ある型のサブクラスも許容しているところです。

Monoidは以下のものを満たす必要があります。

append zero a = a
append a zero = a
append a (append b c) = append (append a b) c

これをScalaで記述すると


となります。

型が命題でプログラムが証明になります。
つまり、leftIdentity,rightIdentity,associativityを定義出来れば証明できたことになります。
カリー=ハワード同型対応!

自然数を定義します。


自然数をMonoidのインスタンスにします。


コンパイル通ったー!

通らない例を作ってみましょう。

正の整数を定義して、Monoidのインスタンスを考えてみます。


この定義では当然コンパイルは通りませんね。

コンパイルが通るように定義することも多分できないと思われます。(asInstanceOfは使っちゃダメですよ。)

これらのコードを書いてる中で疑問が現れました。
NatInstanceのrightIdentityとassociativityです。
このコード、コンパイルは通らないと思っていたのですが、implicitを付けると通りました。
・・・・・なぜ?

2012年6月5日火曜日

わたしのScalazプログラミングその2

型クラスについて。

例によって有理数で。


Groupのインスタンスを定義します。
Groupとは、結合演算子、単位元、逆元を持つもののことです。


動かしてみる。


Groupのインスタンスを定義するだけでこれだけのことができます。

自分でデータ型を定義するときは、インスタンス自体に関数を定義より、データ型にメソッドとして定義したほうがいいかもしれません。
また、Groupのインスタンスからメソッドが定義できます。



乗算、除算も定義してみます。



べんり!

2012年6月2日土曜日

わたしのScalazプログラミング

Scalaはオブジェクト指向言語なのですよ。
知ってました?

重要:これから書くコードはとてもメニアックなので参考にしないようにして下さい。

今日は有理数を定義してみます。



加算と減算を追加してみる。


さて、この2つのメソッド、とても似ていますよね。
抽象化してしまいます。


さて、今日の本題はここからです。
この加算と減算を他の数値型に対応させたいとします。
普通はこのようにオーバーロードを使いますよね。


しかし、+や-はメソッド型ではなく、値型なのでオーバーロードは使用できません。
そこで、オーバーロードを使わず、UnionTypesを使って定義します。


これでもまだ問題があります。
Scalaでは、型パラメータをとる関数を値として定義できません。
そこで、関数のようにふるまう型を自分で定義します。


これで+と-の演算を抽象化し、さらに多相に対応しましたね。
めでたしめでたし。

2012年6月1日金曜日

Scalaz7でIterateeとIO

いつものようにTwitterでScalazを検索すると


この様なつぶやきが。

コードはこんな感じ。


fmfm.
先頭行をとって長さをとって行数分ぬりつぶして合計をとっているようですね。

このコードはScalaz6なのですが、Scalaz7でも書けるかなーと思い、ちょっと書いてみました。


違いを1つ1つみていきます。

まず、Scalaz7ではgetReaderLinesがないので、BufferedReaderではなくReaderを使うようにしました。
なので、1行ずつではなく1文字ずつしかみれなくなります。
そこで、改行コードをみるようにします。
改行コードはシステムプロパティーのline.separatorで取得できるとのことなので、sys.propsから取得します。

もとのコードでは、先頭行を取得する為にheadを使っていますが、このコードではtakeWhileを使います。
ここでは、述語として改行コードかどうかの判定をとります。

さて、肝心のIterateeの要素ですが、IoExceptionOr[Char]となっています。
これはその名の通り、IoExceptionとの和で、どちらかが内包されています。
ここではvalueOrを使い、IoExceptionだった場合の値を決め、値を取得しています。

repeatBuildはScalaz6のscalaz.IterV.repeatと同じです。
on[IO]は、Iteratee[E, A]から、IterateeT[E, IO, A]に変換しています。

enumReaderはReaderからEnumeratorを作り、&=はEnumeratorをIterateeに流し込みます。

最後に実行の部分ですが、mainを定義しているわけではありません。
SafeAppはunsafePerformIOを明示的に呼び出さない仕組みで、runをオーバーライドすることで実行できます。

・・・・・とまあこんな感じなのですが、Scalaz6と比べて、かなり違うことが分かりますね。
とくにIteratee。
IterVとIterateeで別々のものになっていましたが、いまはIterateeTのみで大分使いやすくなった気がします。(Iteratee[E, A]はIteratee[E, Id, A]の別名)
ただ、enumReaderLinesのようなものは欲しかった。

IOはMonadIOとかMonadControlIOとかいろいろ高機能になっているのですが、基本的な機能が少ないので、相変わらず残念です。
せめてSourceとReaderとWriterのインスタンスくらい作ってくれればいいのに。
あと入出力系。

超便利とまでは言えないけれど、将来性はありそうなiterateeとeffect。
一度さわってみてはどうでしょう?

2012年5月23日水曜日

Scalaz7

最近はgistでScalazワンライナー職人やってます。
ワンライナーになるのはScalazにアルゴリズムが揃ってるからですよ!と主張してみる。

Scalaz7


現在の最新リリース版はScalaz6系です。
githubのmasterも6系ですね。更新が1ヶ月前で止まってますが。

開発が活発に行われているブランチはscalaz-sevenです。
これは次期Scalazで、大幅な設計の見直しがされています。

主な違いは、
  • scalazのconcurrent,effect,iterateeパッケージがサブプロジェクトに分離されました。
    • httpとgeoはお亡くなりになりました・・・
  • 型クラスの階層構造が見直されました。
    • ZeroやEmptyがなくなったり、TraverseがFoldableを継承したり。
  • 型クラスのコンパニオンオブジェクトにインスタンスが定義されなくなりました。
    • インスタンスの定義は、scalaz.std以下や、各データ構造のコンパニオンオブジェクトに定義されるようになりました。
  • scalaz.syntax以下にimplicit conversionを使ったシンタックスが定義されるようになりました。
    • Identity,MA,MABなどない!
  • 新しいデータ構造が追加されました。
    • モナド変換子がいっぱいだよ! 
とまあこんな感じ。

Scalaz6と7では、パッケージ、データ構造、型クラス、メソッド名、かなり違います。
なので、6から7への移行は少し面倒かもしれません。

上記の違いはREADME参考にしながら書きましたが私的に重要だと思った変更を列挙していこうと思います。

Tag, Union


これだけでもにScalaz6から7へ移行する理由に成り得ます。
これらを使うことで適度に制約を加えられるようになり、設計がしやすくなります。
いままでNewTypeを使って実装していたものは全てTagで書き直されています。
あまり詳しく書いてないけれど、過去にちょっと書いた

scalaz.std


いままでは、*WにScalaの基本的なデータ構造の拡張が定義されていましたが、Scalaz7ではscalaz.std以下に型クラスのインスタンスと共に定義されています。
シンタックスも定義されていますが、高階関数に関数を渡すときなどに、直接関数を指定できるようになりました。

Sugarがない


Scalazのアイデンティティとも言える変態記号メソッドがなくなりました!
これを使ってScalazは変態だなんてもう言えなくなってしまうと思うと少し残念です。
いままで☆とか使ってた人はどうなるのでしょう・・・・・

まとめ


いまからScalazを使い始める人は、Scalaz7を使って欲しいかなあと思います。
変更が大きいということもありますが、Scalaz7の方が洗礼されてますし、より高機能になっているので、Scalazの凄さがよくわかるのではないかと思います。

Scalazを勉強したい方へ


自分の趣味のプロジェクトのコードにこの2行を加えましょう

import scalaz._
import Scalaz._




Scalaz勉強会とか需要があるのなら開こうと思うのだけれど、実際どうだろう?

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で動くので、是非試してみて下さい。

2012年2月3日金曜日

Tagged, Union

Scalaz7のSNAPSHOTがリポジトリにあったので、いろいろ試しています。

設計が大幅に変わったので6系にべったりだと移行はかなり大変な気がします。

Tagged

Scalaz7ではNewTypeがなくなり、代わりにTagged Typesというものが入りました。

これは既存の型にタグを付けることで、コンパイラに別の型のように見せることができます。
さらに、この型は元の型が必要な場合にはunboxされるという素敵なものです。


@@がタグを付けるためのものです。
ここではIntにFooタグを付けたものをBarとしました。


この型を取る関数にIntを渡すとコンパイルエラーになります。


エイリアス付けるとTagを使ったときに推論が効かないので、@@を直接書くか、型パラメータをとるようにするといいです。

Scalaz7ではNewTypeを使っていた殆どはTagged Typesに置き換えられました。
あまりなにも考えずNewTypeばかり継承していると移行が大変ですのでこのことも考えておきましょう。 (体験者談)

Tagged Typesについて詳しく知りたい場合はこちらを。

Union

最近入って、SNAPSHOTにもまだ入ってないもの。
型の和が簡単に作れてしまう優れもの。
これもunboxされる。


t[A]#t[B]でAとBの和を作ります。
この型を直接引数に取るのではなく、Containsという型を使います。


Converterで値を持てるけど、Anyになってしまうので微妙。

Tagged Typeにも言えますが、Unionはsealed traitとcase classで新しいデータ構造を作るより手軽に使えるところがいいところですね。

Scalaz7は全体的に効率化がされていて、Unboxedなこれらの型もそのためにあるのだと思います。

便利な上に効率もいいのでガンガン使ってしまいましょう。

早くScalaz7が出て欲しいなぁ。

2012年2月2日木曜日

ClojureとFXML

JavaFX for Linux キタ━(゚∀゚)━!
ということでさわってみました。

ただ動かすのも面白くない、というかJava面白くない、ということでClojureから呼び出してみました。

JavaFXで私が一番注目していたものはFXML。
XMLは好きじゃないけど、ちゃんとロジックが分離できそうだし、GWTのUiBinderを気に入っていたので楽しみにしていました。

というわけでClojure+FXMLで書いてみました。

プロジェクトの設定(Linux)

Leiningenを使います。

多分Winの場合はそのまま動く。
Linuxの場合は http://www.oracle.com/technetwork/java/javafx/downloads/devpreview-1429449.html から Linux 32-bit をダウンロードして、 lib に jfxrt.jar を、 bin に *.so を置いて下さい。

main.clj

まずはApplicationを継承した起動ポイントを書く。


main/launchだとエラーが出る謎。

pane.clj

xmlをFXMLLoaderでロードするだけ。


root.xml

fx:controllerを指定してButtonを置いてonActionを設定する。


controller.clj

Buttonから呼び出される関数を定義する。


gen-classに:methodsをわざわざ書くのがめんどう。

実行



なんかあっさり動いてしまった。

これでバリバリClojureでGUIが書けるぞー










と思ったらそんなことなかった。

fx:id

Buttonを押したらLabelのテキストが変わるようにしてみたい。
そんな場合はfx:idでControlに名前をつけるとコントローラで扱えるようになる。
その時にコントローラはmutableFXMLアノテーションが付いたフィールドを持っていなければならない。

gen-classでフィールドは指定できない。
Clojureでは:stateを使うことで状態を実現している。

一番最初に思いついたものはdeftypeを使う方法。

deftype

deftypeではmutableなフィールドを持てます。
なのでdeftypeでコントローラを作ってみます。


でもこれだと、コンストラクタが引数をとるのでFXMLLoaderがインスタンスを作れない。
なのでこれを更に継承・・・・・出来なかった。
なぜならdeftypeで作ったクラスはfinalが修飾されている。
メソッドの型も曖昧なままなので継承できたとしても動くかどうかはわからない。

こうなると別の方法を取るしかないですね。

別の方法といってもClojureでclassを作るにはdeftype, defrecord, gen-classしかない。
deftypeは先程の通りコンストラクタが引数をとってしまう。
defrecordではそもそもmutableなフィールドを持てない。
gen-classはフィールドを指定できない。

Javaを使うことを・・・強いられてるんだ!

ここで登場Java!
嫌いじゃないけど使いたくないJava!

Java側でmutableでFXMLアノテーションが付いた変数を宣言しておこうという戦略。


これを継承してさあ実行。


javafx.fxml.LoadException: Value is already set.


\(^o^)/

ヤンナルネ・・・・・

結果

onActionで関数を指定して呼び出すことはできたがfx:idが使えなかった。

誰か解決方法があったら教えて下さい!

2012年1月22日日曜日

coq2scalaをさわってみた

http://proofcafe.org/wiki/Coq2Scala を試してみました。

インストールはhgでソースコードとってきて、
./configure
make world
make install
でおk。

Extraction Language Scala. が使えちゃうCoqがインストールされます。

使ってみた

とりあえず自然数と足し算を定義してみます。


吐き出されたScalaのコード。


Notationは無視される?
パラメータとらない場合はcase object使って欲しいかも・・・・
あとインデントも付くとうれしい。

ClassとInstanceを使ってみる

Monoidを定義してみた。

私はtraitとimplicit parameterでかっこ良く変換されるのかな!?と期待。


結果は・・・・・


(´・ω・`)ショボーン
明示的にインスタンスを渡して関数を得る感じですね。
まぁ、まだまだ開発途中なのでこれからどうなるかはわかりません。

最後に証明付きコード


proof-editing mode楽しいです。
ScalaでPDDの時代が来るかもですね。

2012年1月10日火曜日

Coqはじめました。

あけましておめでとうございます。

何か新しいことをはじめようと思い、Coqに手を出しました。

まだ慣れていないけど、なかなか楽しいです。

証明楽しいとかどんな変態(褒め言葉)なんだ!

と思っていましたが、私も無事変態の仲間に入ることが出来ました。

Coqをはじめる

Coqを使い始めたきっかけは冬休みの宿題で読書感想文です。

私は選んだ本はもちろん「数学ガール」。

なかなかおもしろいのでオススメです。

数学が得意というわけでもない私は、理解の手助けとしてプログラムを書こうと思いました。

そこでCoqの登場です!

本に出てくる命題を証明していくことにしました。

Coqに関する資料は決して多くありませんが、良いチュートリアルがあるので、まずはこれらを参考にしましょう。

書いてみた

正の整数型を作って加算を定義し、結合法則と交換法則を証明してみました。


結合法則はスラスラと書けて、「うはwっww楽勝www」とほざいていたのですが、交換法則は丸一日かかりました・・・・・

この中で使われているタクティクは
  • intros (導入)
  • induction (帰納)
  • reflexivity (再帰?反射?)
  • simpl (簡約)
  • rewrite (書き換え)
  • assert (表明)
  • replace (置換)
だけです。

プログラミングに慣れている人は、こういったタクティクを覚えていくだけで書けるようになると思います。

書いてみて

私はパズルを解くようなものだと感じました。

Qed. が書けたときはとても嬉しいです。

自然数の定義、自然数の加算・比較、整数の定義、ソースコードをみるだけでも勉強になります。

一度は触ってみてはどうでしょう。

Coq、おもしろいですよ!