Icon言語
出典: フリー百科事典『ウィキペディア(Wikipedia)』
パラダイム: | マルチパラダイム |
---|---|
開発者: | Griswold |
型付け: | 弱い動的型付け |
方言: | Unicon |
影響を受けた言語: | SNOBOL |
Iconは、米国アリゾナ大学のGriswoldにより開発されたプログラミング言語である。
Iconはテキスト処理を目的として作られ、Griswoldが以前に作成したSNOBOLの後継として作られたが、仕様はかなり異なる。
言語の特徴としては、ゴール指向評価(goal-directed evaluation)、呼び出しごとにデータを返すジェネレータ、手続きをそのものを変数に格納するco-expressionなどがある。
Iconの後継にはUniconがある。
目次 |
[編集] 基本構造
Iconの基本構造は以下のようになる。
# コメント link ライブラリ procedure main(args) メインルーチン end procedure 関数(引数) サブルーチン return サブルーチンの返り値(省略可) end
メインルーチンはC言語と同様にmain関数に記述する。なおIconは一度中間形式にコンパイルするときサブルーチンの形式をチェックしてから、再度コンパイルしなおして実行ファイルを生成するので、サブルーチンは宣言の必要がなくソースコードのどの位置に書いても良い。言語の構造はちょうどC言語とPascalの中間のような構造になっている。例えば代入式は
x := x + n
でPascalと同じ代入演算子:=
を用いるがこの式はIconでは
x +:= n
と、まるでC言語のような省略形式での表記が可能である。他にも関数はPascalやAdaのようにprocedure~end
でくくるが、while文やif文などのブロック構造はC言語のように{~}
で範囲を指定するなどである。
[編集] データ構造
Iconは後継元であるSNOBOLとは違い、多数のデータ構造を持つ。主なデータ構造としては関数型プログラミング言語のリスト、SNOBOLからテーブル型(連想配列)、Pascalの集合、レコード型(構造体)など、あらゆる言語のデータ構造のアイデアを実装している。 例えばリストを得るには
cat := ["muffins", "tabby", 2002, 8]
などとすればよい。
ただし上記にないデータ構造も、PythonやRubyと同様に配列、スタック、キューはリストとの区別が無いだけであり、文字列 はC言語同様、文字型の配列として扱うので、これらのデータ構造の機能をもっていないというわけではない。
またIconの変数は基本的にデータの型を宣言する必要が無いが、これはAWKのようにデータ型が存在しないというわけではなく、MLのような型推論が行われているだけである。このため、上記のデータ構造を利用する場合は使用前に宣言を行う必要がある。この宣言は代入文の形で行われる、例えば連想配列の場合
t := table() t["abc"] := 1
となる。これは連想配列t
を使用する前にt := table()
によってt
が連想配列であることを明記している。
[編集] ジェネレータとevery文
ジェネレータとは呼び出しごとに値を返す機構である。一見関数と同じに見えるが、返す値が複数であることが大きく違う。
例えば
if x = ((1 to 5) | y) then write("True") else write("False")
というプログラムがあったときこれはx
が1から5またはy
と等しいなら"True"
そうでなければ"False"
を表示するプログラムである。
このジェネレータの値を逐次処理するためのIconの基本ループとしてevery文が存在する。このevery文は例えば
every i := 1 to 5 do write(i)
と表記すると1~5までの数字を画面に印字する。このevery の後に来る文はジェネレータであればなんでもよいので上の文は
every write(1 to 5)
と記述しても良い。
なお、ジェネレータは自分で作成することも可能である、単純に返り値をreturn
ではなくsuspend
にすることで実装される。例として奇数を出力し続けるジェネレータは以下のようになる、
procedure odd() x := 1 repeat { suspend x x +:= 2 } end
イメージとしてはsuspend
は値を返した後、サブルーチンを中断せずに次の処理に移るものである。これを
every i := odd() do write(i)
と実行した場合、永久に奇数を表示し続ける。
[編集] ゴール指向評価
Iconの中心的な特徴の1つは制御構造を真理値によるものから、成功か失敗によるものへと変更したことである。このモデルでは、
if a < b
のような単純な比較は多くの言語のように
- 「もし式全体が真と評価されるならば」
という意味ではなく、
- 「もし処理全体が成功ならば」
というような意味である。この場合は比較が成り立つなら、<
演算子は成功する。よってIconとその他の言語で実行結果は同じとなる。この方式がより興味深いのは、
if a < b < c
のような場合である。このような比較は、ほとんどの言語ではこのまま記述することができないが、Iconでは可能である。
この方式の有用性がより明確になるのは、現実の例で考えたときである。Iconでは
if a := read() then write(a)
は標準入力から標準出力へと1行をコピーする。この例はファイルが存在しないなどの理由でread()
がエラーを発生したときでも正しく動作する。その場合は、a := read()
が失敗し、write(a)
は呼ばれない、という単純な動作である。
成功と失敗は例外処理のように関数を遡る、つまりネストした関数呼び出しの中で失敗が起こると呼び出し側の関数も失敗する。例として、入力ファイルの内容すべてを出力するプログラムは
while write(read())
と書ける。read()
が、例えばファイルの終わりに達して。失敗すると、呼び出しを遡ってwrite()
も同様に失敗する。よってファイルの内容すべてを出力して停止する。比較のためにJava風の擬似コードを考える。
try { while ((a = read()) != EOF) { write(a); } } catch (Exception e) { // 何もしないでループを抜ける }
この場合、2つの比較が必要とされる。1つはファイルの終端(EOF
)であり、もう1つはその他のすべてのエラー(Exception
)である。JavaではIconと違って例外を真理値として比較することができないので、長いtry-catch
の構文が必要となる。またtry
ブロックには、たとえ例外が発生しなくても、Iconにはないパフォーマンス上のペナルティの問題がある。
「何らかのゴールに達するまで評価が続けられる」という意味で、Iconではこのような方式をゴール指向評価という。上の例でのゴールはファイル全体を読み出すことであり、まだ読むべき情報が有るあいだはread()
は成功し続け、無くなったら失敗する。従って、戻り値を調べる文や余分な構文は必要なく、ゴールが言語によって直に記述される。