pureいじってみる
先日、id:nskj77 さんに教えてもらった、Pureという言語を試してみた。
簡単に、pureの特徴を説明すると、
なんというか、いろんなものを詰め込んだ感がいなめませんね。
msiのパッケージや、macportにも入っているので、インストールは簡単。
どんな感じかだけ見たいなら、examples/hello.pureを見れば、Haskellとか、MLを知っているならわかると思います。
で、いじってみた感想なのですが、まず置き換えモデルが面白すぎ。pureは、式を変換できるところまで、置き換えていきます。
squ x = x*x;という関数に対して、プリミティブな値である8をいれると計算してくれます。
> squ x = x * x; > squ 8; 64
しかし、定義されていない(a+b)という値を与えると、(a+b)*(a+b)というふうに置き換えてくれます。
> squ (a+b); (a+b)*(a+b)
そのあと、別の置き換え方法を定義してやり、再度(a+b)をsquにわたしてやると、さらに置き換え可能なところまで置き換えてくれます。
> (x + y) * z = x*z +y*z; > x *(y+z) = x*y + x*z; > x*(y*z)=(x*y)*z; > x+(y+z)=(x+y)+z; > squ (a+b); a*a+a*b+b*a+b*b
面白いとは思うんだけど、何が便利なの?っていわれると困ります。まだ、いじり足りていないので。あと、置き換えパターンの定義をミスると、置き換えで無限ループ起こして大変なことになります。(C-cとかC-dでインタラプトもできませんでした。強制的にkillしたった。)
あとパターンマッチと動的片付けの部分について。pureは、関数定義時に引数の型を指定できます。
> append1 x::int = x + 1; > append1 10; 11
このとき、引数に定義されていない型の値を渡すと、当然置き換えができません。
> append1 "10"; append1 "10"
なので、stringのときの定義を作ってやれば、動きを変更できます。
> append1 x::string = x + "1"; > append1 "10"; "101"
当然、引数に型を定義しなくても、処理で使われる演算が型に対して定義されていれば、当然計算されます。
> append x = x + x; > append 10; 20 > append "mo"; "momo"
ここらへんは、Haskellとかだと型推論や総称型で似たような動きできるけど、いちいち総称型作らなくていいのは便利そうね。
ただ、動的だからリストにいろんな型をいれれるのは、ちょっと怖いかなぁ。
> map (\x->x+x) [1,"10",3]; [2,"1010",6]
あと、curry化が用意にできるのは、萌えるなぁ。
> map (+) [1,"10",3]; [(+) 1,(+) "10",(+) 3] /* (+) は2引数必要な演算なのでcurry化されるのみ */ > map (\x-> x 1) (map (+) [1,"10",3]); [2,"10"+1,4] /* 文字列に数字は適用できないから置き換えるのみ */
あと、flipあるでよ。
> (+) "ho" "ge"; "hoge" > flip (+) "ho" "ge"; "geho"
今のところ、一番の難関はセミコロンの付け忘れです。