'Hello World!'
I言語はJ言語に影響を受けた言語で、J言語はAPLに影響を受けているため、A+言語の時と同様の理由によって、文字列リテラルを書くだけでHello, World!になります。
J言語やAPLは配列を扱うことに特化した言語でしたが、I言語は連想配列などのそれ以外のデータ構造も扱えるようにした言語です。
このAdvent CalendarにはAPL系の言語が多く登場しますが、他のAPL系言語にはないI言語の特徴も紹介します。
それは演算子の結合優先順位を表すために空白の個数を使うというものです。なお、同じ優先順位の場合には左から右に結合していきます。多くのプログラミング言語にあるような*は+よりも優先するというルールはなく、空白の個数によって決まります。
例えば、以下のコードを考えます。
b.- +,- b.q - 4*a*c . Q / 2*a
空白の個数が分かりやすいように①②③…で、個数を表現してみます。
b.-③+,-③b.q①-①4*a*c①.①Q③/③2*a
このときに、まずは空白が0の箇所が先に左から右に結合します。
(b.-)③(+,-)③(b.q)①-①((4*a)*c)①.①Q③/③(2*a)
次に空白が1つの箇所が同様に左から右に結合します。
(b.-)③(+,-)③(((b.q)-((4*a)*c)).Q)③/③(2*a)
そして最後に空白が3つの箇所が結合します。なお、最後の空白の個数は3でなく2でも十分ですが、可読性のためにスペースを多めにしています。
((b.-)(+,-)(((b.q)-((4*a)*c)).Q))/(2*a)
なお、上記の式は二次方程式の解の公式です。登場する記号で分かりづらいものを解説します。
b.-: 他の言語で言うところの -b に相当
+,-: この部分がプラスの場合とマイナスの場合の、2つの要素からなる配列を生成
.q: .の手前の数の二乗を求める処理
.Q: .の手前の数の平方根を求める処理
+,- がややとっつきづらいですが、numpyのブロードキャストを数ではなく演算子で行っているようなものです。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr + 10) # [11 12 13 14 15]
この演算子の結合の優先順位を空白の個数で決める手法はDijkstraの「The notational conventions I adopted, and why」から着想を得ているそうです。
Surround the operators with the lower binding power with more space than those with a higher binding power. E.g.,
p ∧ q ⇒ r ≡ p ⇒ (q ⇒ r )