言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Joy でエンジョイ

昨日は Joy の紹介の翻訳をアップしたら、勢い余って後で著者が違ってると指摘されました。今本当の著者の許可を待っている所ですので少々お待ちください。

と、気を取り直して簡単に Joy 言語で遊ぶ方法を書きます。Joy は C で書かれていますので、LinuxCygwin 等、C が使える環境なら大体使えると思います。Joy の情報はhttp://www.latrobe.edu.au/philosophy/phimvt/joy.html に纏まっています。

$ wget http://www.latrobe.edu.au/philosophy/phimvt/joy/joy.tar.gz
$ mkdir joy
$ cd joy/
$ tar xf ../joy.tar.gz 
$ make

まず Joy のソースコードとして http://www.latrobe.edu.au/philosophy/phimvt/joy/joy.tar.gz をダウンロードします。他にも色々あってどれが一番良いのか分からないけど、とりあえずこれで話を進めます。展開する前にディレクトリを作っておく事をお勧めします。コンパイルは make 一発です。これでカレントディレクトリに ./joy コマンドが出来ます。小手調べに電卓として使ってみます。

$ ./joy.exe
JOY  -  compiled at 13:54:32 on May 17 2007 (NOBDW)
Copyright 2001 by Manfred von Thun
usrlib  is loaded
inilib  is loaded
agglib  is loaded
3 4 + .
7

"3 4 + ." が入力した部分です。ドット . まで読むと結果を返します。Joy は Forth 族の言語なので、なかなか変態的な文法です。スタックというデータ構造を使います。スタックは箱を積み上げたような形のデータで、先端に積み上げる事(プッシュ)と先端から取り去る事(ポップ)は出来ますが、途中を抜き取る事は出来ないという性質を持っています。"3 4 + ." は「3 をプッシュして、4 をプッシュして、それを足した結果と入れ替えて、表示する」と読みます。もっと簡単に、「3 と 4 を足して表示する」と読んでも良いです。関数定義はキーワード DEFINE とドット . の間に書きます。

DEFINE double == 2 *.
7 double.
14

単項演算子の雰囲気が Smalltalk っぽくて親しみが沸きますね。if-then 文に相当する物は ifte で [条件] [真のとき] [偽のとき] ifte といった書き方をします。[] も Smalltalk のブロックみたいですが、クォーテーションと呼びます。意味は大体同じです。

DEFINE 男 == [30 >] ["おじさん"] ["おにいさん"] ifte.
18 男.
"おにいさん"
34 男.
"おじさん"

関数型言語なので、関数型言語でお馴染みの高階関数が使えます。プログラムを引数にする時は [] で包みます。

"IBM" [pred] map. (* pred は前の値を返します。*)
"HAL"

ちなみに、これを Haskell で書くと map pred "IBM" となります。括弧が必要かどうかの違いがありますが、端的に言って Joy の文法は Haskell を逆にして、所謂ポイントフリースタイルを強制した物と考えると分かりやすいです。最後に、よくどれだけ短いか勝負されるクイックソートです。

DEFINE sort == [small]  []  [uncons [<] split]  [swapd cons concat]  binrec.

["Ruby" "C" "Haskell" "Python" "Squeak" "Joy"] sort.
["Squeak" "Ruby" "Python" "Joy" "Haskell" "C"]