J言語で記号プログラミング

2010-12-06

こんにちは、勇士Qです。
他にも記号プログラミングできるような言語を紹介したいなぁということで参加させて頂きました。

Jはかの特殊な記号を使うAPLの後継として生まれた言語です。
APLとは違って特殊な記号ではなく普通の記号で使用できるようになったため、まさに記号プログラミング向けの言語ですね。

記号だけで数字を作ろう

とりあえず、記号だけで任意の数字を表現してみましょう。
Jには記号だけをつかった特別な数値があります。

_   NB. 無限大
__ NB. 無限小
_. NB. 不定形

これに対して上手く演算を行えば任意の数字が作れそうです。文字数が少ない「_」を使って、簡単な数字を作ってみましょう。

%_  NB. 0
*_  NB. 1

無事に0と1がつくれました。同様に演算を行っていくと任意の数字をつくることができます。

0:   %_
1:   *_ 
1:   !*_
2:   +:*_
3:   >.^*_
4:   +:+:*_
5:   >.!^*_
6:   !>.^*_
7:   <.*:^*_
8:   >.*:^*_
9:   *:>.^*_
10:  +:>.!^*_
11:  >.+:+:^*_
12:  +:!>.^*_
13:  <.^!-^*_
14:  <:<.^^*_
15:  <.^^*_
16:  >.^^*_
17:  >:>.^^*_
18:  <.*:!^*_
19:  >.*:!^*_
20:  <.^>.^*_
21:  >.^>.^*_
22:  >:>.^>.^*_
23:  <:!+:+:*_
24:  !+:+:*_
25:  *:>.!^*_
26:  <.^<:!^*_
27:  >.^<:!^*_
28:  <.^.!^^*_
29:  <.*:+:^*_
30:  +:<.^^*_
31:  >.+:^^*_
32:  +:>.^^*_
33:  >:+:>.^^*_
34:  <:<.!!^*_
35:  <.!!^*_
36:  >.!!^*_
37:  >:>.!!^*_
38:  +:>.*:!^*_
39:  <.^!!-^*_
40:  >.^!!-^*_
41:  <.^>:^*_
42:  >.^>:^*_
43:  >:>.^>:^*_
44:  <.*:*:!-^*_
45:  <.!^!%:^*_
46:  >.!^!%:^*_
47:  <.!<:+:^*_
48:  +:!+:+:*_
49:  *:<.*:^*_
50:  >.^%:^^*_
51:  >.!^>:-:*_
52:  +:<.^<:!^*_
53:  <:<.*:*:^*_
54:  < .*:*:^*_
55:  >.*:*:^*_
56:  >:>.*:*:^*_
57:  <.*:-:^^*_
58:  >.*:-:^^*_
59:  <.+:*:+:^*_
60:  -:!>.!^*_
61:  <.^^%:+:*_
62:  +:>.+:^^*_
63:  <:*:>.*:^*_
64:  *:>.*:^*_
65:  >:*:>.*:^*_
66:  <.^<:^%:^*_
67:  >.^<:^%:^*_
68:  +:<:<.!!^*_
69:  <:<.^!^*_
70:  <.^!^*_
71:  >.^!^*_
72:  +:>.!!^*_
73:  >.*:+:!^*_
74:  <.!>:>:^*_
75:  >.!>:>:^*_
76:  >.^.!+:^^*_
77:  <.*:!+:%:^*_
78:  >.*:!+:%:^*_
79:  <:<:*:*:>.^*_
80:  <:*:*:>.^*_
81:  *:*:>.^*_
82:  +:<.^>:^*_
83:  >.+:^>:^*_
84:  +:>.^>:^*_
85:  >.^<:+:^*_
86:  +:>:>.^>:^*_
87:  <:<.^^>:-:*_
88:  <.^^>:-:*_
89:  >.^^>:-:*_
90:  <.-:^^%:^*_
91:  -:>.^^%:^*_
92:  +:+:<:!+:+:*_
93:  <.^*:-:!^*_
94:  -:<.!>:!^*_
95:  <.^.!!!^*_
96:  >.^.!!!^*_
97:  <.*:*:^.-*_
98:  +:*:<.*:^*_
99:  >.+:^%:^^*_
100: *:+:>.!^*_
101: >.!>:%:^^*_
102: +:>.!^>:-:*_
103: >:+:>.!^>:-:*_
104: <:<.%:!*:^*_
105: <.%:!*:^*_
106: >.%:!*:^*_
107: >:>.%:!*:^*_
108: +:<.*:*:^*_
109: <.+:*:*:^*_
110: +:>.*:*:^*_
111: <.^>:>:^*_
112: >.^>:>:^*_
113: -:>:*:<.^^*_
114: <.-:*:^^*_
115: -:>.*:^^*_
116: +:>.*:-:^^*_
117: <:<.*:+:+:^*_
118: <.*:+:+:^*_
119: <:!>.!^*_
120: !>.!^*_
121: >:!>.!^*_
122: >:>:!>.!^*_
123: >.+:^^%:+:*_
124: +:+:>.+:^^*_
125: -:<.*:!>:^*_
126: >.-:*:!>:^*_
127: <.*:^^!-:*_

変数が使えず、1から作っていくためどうしても長くなってしまうのが少し残念なところです。

文字列を作ろう

困ったことに、数字と記号から直接文字に変換する方法がありません。
しかし、「a.」でASCIIのリストが取得できるので、そこから取り出せば他の文字も生成できます。なんとしてでも文字列「a」を生成したいところです。
探してみたところ運良く「18!:5''」というCurrent localeを表示し、デフォルトで文字列「base」を含むリストを返してくれるものがあったのでそれを使うことにします。
ここから切り出せば「a.」が作れますね。

(1{>18!:5''),'.' NB. 'a.'

このままではただの文字列なのでこれをevalしたいわけですが、Jでは動詞「".」を使うことでそれが可能です。

".(1{>18!:5''),'.' NB. ASCIIリスト

これで無事にリストがとれました。
さらに、リストから要素を取り出す動詞「{」をつかって「ASCIIコードのリスト{a.」で任意の文字列を生成できます。

Hello, world!

以上のことを含めて、「Hello, world!」を書いてみましょう。
記号化する前のコードはこんな以下のような感じになります。非常にシンプルですね。

(72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33){a.

あとは記号だけにする簡単なお仕事になります。

((+:>.!!^*_),(>.!>:%:^^*_),(+:<.*:*:^*_),(+:<.*:*:^*_),(<.^>:>:^*_),(<.*:*:!-^*_),(+:>.^^*_),(<:!>.!^*_),(<.^>:>:^*_),(<.-:*:^^*_),(+:<.*:*:^*_),(*:+:>.!^*_),(>:+:>.^^*_)){".((*_){>(+:*:>.^*_)!:(>.!^*_)''),'.'

完成です! これを実行すると見事に、「Hello, world!」と表示されます。