J

J、その可読性の低さゆえ全く流行していないプログラミング言語。

まずはJをゲット

Jの処理系はJsoftwareで配布されている。
Download→Stableからそれぞれの環境にあった処理系のインストーラをダウンロード。

インストーラでは、一人で使うのか、それともPCのユーザー全員で使うのか聞いてくる。
これは人それぞれ自由に選んでおk。
一人で使う場合はそのユーザのホームフォルダに、全員で使う場合はProgram Files(Windowsの場合)にインストールされる。

Jに触ってみる

Jの起動

Jの処理系は、Jがインストールされたディレクトリから
./bin/j.exe
と辿ったところにあるので起動する。

Jの処理系は対話型なので、プログラムを入力するとその場で実行してくれる。
これを使ってJを高性能かつ簡単な電卓として使うこともできる。

Hello, world!

Jでは、文字列は''(シングルクォーテーション)で囲ったもので表される。
また、文字列を入力するとそのまま返すので、Hello, world!プログラムは以下のようになる。

'Hello, world!'

上の通りにJに入力してやると、Hello, world!という表示が返ってくる。
Jの窓は以下のような状態になっているはず。

   'Hello, world!'
Hello, world!

このように、Jでは入力を半角スペース三つ分インデントして表示する。
また出力は行頭から表示される。
以降に示すサンプルも全てこれに則って書いてあるので
実際に試すときはインデントされている部分だけを入力すればおk。

呼称について

例えば普通のプログラミング言語の場合、以下のプログラムでは「10」が定数、「+」が「演算子」、「printf」が「関数」、「a」が「変数」などと言った呼び方をする。

int a = 10;
printf("%d\n", a + 10)

だがJの場合、演算子とか関数とか言った呼称は用いず、次のような呼び方をする。

ほかにも、動詞の動作に影響を与える副詞、品詞同士をつなぐ接続詞などもある。
余談だがこのように自然言語っぽい呼び方をする所は俺大好き。

まずは簡単な計算から

四則演算+α

まず加算減算乗算除算そして剰余を求める計算をやってみる。
加算減算乗算を行う動詞はそのまんま、+と-と*。

   5 + 3
8
   7 - 4
3
   6 * 5
30

除算の動詞は % を使う。
普通の言語だと除算は / で、剰余が % とかいうことが多いけど、
Jでは除算が % なので間違ったりこんがらがったりしないように。

   16 % 8
2
   5 % 2
2.5
   13 % 7
1.85714

で、剰余(あまりを求める)の動詞は | (縦線)。
注意しなきゃいけないのは、剰余を求めようとして「x | y」とした時に、
「xをyで割ったときのあまり」ではなく「yをxで割ったときのあまり」になるから
名詞の順番を間違えないように。

   5 | 13
3
   2 | 30
0

とりあえず理解確認のために以下の問題を解いてみようか。

答がそれぞれ56088、5.76471、11になったら読み進めよう。
ならなかったら読み直せ。

数値リテラル

一口に数といってもいろいろある。
整数、小数、正の数、負の数、実数、複素数・・・
それらの数を表現するための方法が幾つかある。

指数表現

とても大きい数やとても小さい数を表すのに使う「xのy乗」の形。
たとえば「13000000000」は「1.3の10乗」で「1.3e10」と書く。

   1.3 * 10000000000
1.3e10
   1.2345e5
123450

負の数

負の数はふつう「-」(マイナス)の符号をつけるが
Jの場合は少し違う。Jで負数を表すには _ (アンダースコア)を使う。

   3 - 5
_2
   _3 + 9
6
   _5 * 4
_20

無限・未定義

数が大きすぎたり、定義されない値をとった場合の表現の仕方があるが
まあ普通、ほとんど使わない。
無限は _ (アンダースコア)、未定義は _. (アンダースコアとピリオド)で表される。 無限と負数の表現が同じだけれども、無限の場合はアンダースコアだけを書き、
負数の場合は数も書くので区別できる。
ちなみに、アンダースコアを二つ繋げるとマイナス無限大を表すこともできる。

   1.2345e999 * 6.789e999
_
   _. * 123 + 456 - 789 % 999
_.
   _1 * _
__

その他

その他にも複素数とか分数とかあるけどまあ後々説明する。

優先順位

優先順位は数学と同じ、なんて甘いことを言っちゃいかん。
だからといって複雑な順位が決められてるわけでもなく、
右から順番に計算されるだけ。つまり、

   1 - 2 - 3 - 4
_2

こうなる。
「1 - 2 - 3 - 4」は「1 - (2 - (3 - 4))」になるので答はマイナス2になる。

というわけで確認問題

予測と実際の答が合っていれば読み進めよう。
合ってなかったら読み直せ。

単項と二項

Jの動詞は単項で使った場合(動詞の右にだけ名詞がくる)と
二項で使った場合(動詞の左右両方に名詞がくる)場合で全く異なった挙動をする。
詳しい挙動については後々品詞一覧で述べようと思うが
代表的なものを挙げておこうと思う。

「*」は単項だと符号の判定、二項だと乗算になる。

   2 * 4
8
   3 * 5
15
   * 3
1
   * _12
_1
   * 0
0

「|」は単項だと絶対値、二項だと剰余になる。

   3 | 15
0
   4 | 22
2
   | 50
50
   | _13
13
   | 0
0

この単項と二項の使い分けはJのコードを読む上でとても重要だから
単項と二項で動作が変わるということは覚えておいてほしい。

コメント

コメントは「NB.」でつけることができる。 NB.以降は行末までがコメントになる。

   3 * 5 + 6  NB. 5と6を足して3倍する
33

アレイ

アレイの基本

Jでは沢山の値を纏めて扱うことができる。
他の言語でいう配列のようなものをアレイと呼ぶ。
アレイを定義するには、数値同士を半角空白で区切ればいい。
アレイ同士の演算も可能である。

   1 2 3 + 4 5 6
5 7 9
   1 2 3 * 6 5 4
6 10 12

アレイ同士で演算を行う場合、両方の長さが等しくなければならない。
長さの等しくないアレイ同士で演算を行おうとすると、length errorと怒られる。

   1 2 3 4 + 5 6
|length error
|   1 2 3 4    +5 6

また、アレイと単一の名詞との演算もできる。

   1 2 3 + 5
6 7 8
   1 2 3 * 10
10 20 30

アレイの操作

アレイの要素数は動詞 # (シャープ)で求めることができる。

   # 1 2 3
3
   # 1 2 3 4 5 6 7 8 9 10
10

0から指定された値 - 1までのアレイを作る動詞 i. (イオタ)というものもある。

   i. 10
0 1 2 3 4 5 6 7 8 9
   5 + i. 10
5 6 7 8 9 10 11 12 13 14
   # i. 10
10

アレイの整形

動詞 $ (ドル)を使うと、アレイを整形することができる。
整形する場合、$は二項動詞として用い、左に形、右に値をもってくる。
二次元以上のものを作り出すことができる。

   3 4 $ i. 12    NB. 3 * 4のテーブルの形に i. 12 を整形する
0 1  2  3
4 5  6  7
8 9 10 11
   2 4 $ 1 2 3    NB. 要素が足りない場合は繰り返される
1 2 3 1
2 3 1 2
   3 3 $ i.100    NB. 要素が余る場合は切り捨てられる
0 1 2
3 4 5
6 7 8

副詞を使ってみる

副詞は、動詞の動作に影響するもので、使いようによってはかなり使える。
とりあえず一番よく使うであろう副詞 / (スラッシュ)の説明をしよう。

まず副詞はどうやって使うかというと、動詞の直後につけて使う。
動詞 + に副詞 / をつけると +/ となる。
この場合、 +/ という新しい動詞ができたと考えた方が簡単。

で、この副詞 / というものの効果は「挿入」(もちろん性的な意味dうわなにをするやめr)。
「挿入」というのはアレイの各要素の間にその動詞を挿入することを言って、
「+/ 1 2 3 4 5」という文は「1 + 2 + 3 + 4 + 5」と解釈される。
つまり +/ というのはアレイの要素の合計を求める新しい動詞になるわけだ。
これを使えば、1~100までの自然数の和を求めるプログラムだって簡単に書ける。

   +/ i. 101
5050

フックとフォーク

さて、それではJ言語の一番の特徴である「動詞の合成」の説明をしようと思う。
ここは結構複雑だから一気に理解しようとせずに、ゆっくり理解していってほしい。

フック

フックは動詞二つを合成するときの決まりで、以下のようになる。
(f, gは動詞、x, yは名詞)

(f g) y   →   y f g y
x (f g) y →   x f g y

まず単項の場合、動詞gを単項動詞としてyを与えて評価させる。
そして動詞fを二項動詞として「g y」の値と、元のyを与えて評価させる。例えば

   (+ *) 5
6

この場合、まず動詞*に5が渡されて「* 5」が評価される。
単項*動詞は符号の判定なので、「* 5」は1となる。
次に動詞+に 1 と 5 が渡され、結果は6となる。

二項の場合、最後の動詞fに渡す名詞がyではなくxになるだけで、
単項の場合の動作が分かれば簡単に理解することができる。

フォーク

フォークは動詞三つを合成するときの決まりで、以下のようになる。
(f, g, hは動詞、x, yは名詞)

(f g h) y   →   (f y) g h y
x (f g h) y →   (x f y) g x h y

まず単項の場合、動詞fとhにyを与えて評価し、
その結果の二つ値をgに与えて評価させる。例えば

   (+/ % #) 3 5 7 9
6

この場合、

となるから、

(+/ 3 5 7 9) % # 3 5 7 9

と解釈される。

#はアレイの要素数を求めるので 4 (これが「h y」の値)

  1. /はアレイの要素の合計を求めるので 24 (これが「f y」の値)
    よって、
24 % 4

になるから、答は6となる。
合計を要素数で割る操作、つまりこれは平均を求めていることになる。
フォークをうまく使うことで、平均を求める操作を (+/ % #) だけで記述することができる。

トレイン

四つ以上の動詞の合成時の決まりで、これはフックとフォークの組み合わせにすぎない。 例えば、四つの動詞a, b, c, dを合成するときは

(a b c d) → (a (b c d))

となり、右から三つ b, c, d でフォークが起きる。
その結果と a でフックが起きる。

トレインの合成規則はかなり複雑になるが、所詮フックとフォークの合わせ技なので
フックとフォークを理解できていれば読むのは難しくはない。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS