Unlambda

Unlambdaはコンビネータ論理とラムダ計算に基づく、仕様の小さな、ほぼ純粋な関数型言語のプログラミング言語である。デビッド・マドレによって設計された。

1. 概要
-----

この言語はコンビネータ論理とラムダ計算にもとづいている。この言語は主に2つの組込関数および、関数適用演算子によって成り立っている。これらだけによってチューリング完全をなしているが、ユーザーとのインタラクションを可能にする入出力関数群と、いくつかのショートカット関数群、そして、遅延評価のための関数も備えている。この言語には変数は存在しない。

en言語の目的は実用ではなく純粋関数型言語の実証にあるため、この言語は難解なプログラミング言語になっている。実用的な普通の言語にあるような演算子やデータ型が存在しないというのがこの言語の大きな特徴である。この言語に唯一存在するデータは1引数の関数だけである。それにもかかわらず、あらゆるデータはラムダ計算による関数を用いて表現することができる。複数の引数の関数もカリー化の手法によって表現することができる。

en言語は抽象削除の原理で動作する。純関数型言語であるため、en言語の関数は一階のオブジェクトである。また、この言語にとって関数とは唯一のオブジェクトでもある。

処理系の実装は色々なプログラミング言語で行われている。ML系の言語では100行程度で実装されている。

2. 例
----

下記はen言語によるHello worldプログラムの実装例である。

3. 組み込み関数
---------

3.1. 一覧
-------

組み込み関数の一覧は以下の通り。

` 関数適用 s SKIコンビネータ計算のS k SKIコンビネータ計算のK i SKIコンビネータ計算のI v 引数を無視して v を返す d 厳密には関数というよりも特殊形式で、評価を遅延し、2回目の評価の時に初めて評価する c 継続。call-with-current-continuation。 e 継続を無視し、プログラムを終了させる r 改行を表示し、後はIと同じ振る舞い . 引数の文字を表示し、後はIと同じ振る舞い @ 標準入力から1文字読み込む? 標準入力から1文字読み込み、引数と比較する | 標準入力から1文字読み込み、表示する

3.2. バージョン1から存在する物
------------------

「.H」や「.e」などの、「.//A//」で表されるものは恒等関数  で、副作用として「//A//」を表示するものである。「i」は副作用を伴わない恒等関数である。上述の Hello world プログラムではダミーの引数として使われている。「`.di」というプログラムは、文字「d」を表示する関数に引数iを適用して呼び出すもので、戻り値として関数「i」を返し、副作用として文字「d」を表示する。同様に、「``.l.di」というプログラムでは、まず、関数「 .l」に引数として「.d」が適用され、文字「l」が表示されて、戻り値として関数「.d」を返す。そして次に、この戻り値「.d」に対して、引数として関数「i」が適用され、前述の通りの動作が続く。関数「r」は改行文字を表示する関数の糖衣構文である。

en言語のその他の重要な特徴として、「k//A//演算子」と「s演算子」がある。k//A//演算子は、引数の値に関係なく戻り値として //A// を返す演算子である。つまり、「``k//AB//」の戻り値は、 //B// の値に関係なく、いつも //A// である。

「s」は汎用の評価演算子である。「```s//ABC//」というプログラムは、//A//、//B//、//C//の値に関係なく、「``//AC//`//BC//」と評価される。この「s」と「k」だけでいかなる計算も行えるという事実は、注目すべき点である。例えば、恒等関数「i」は「``skk」によって実現することができる。なぜなら、「```skk//A//」は、いかなる //A// に対しても //A// を返すからである。

en言語の唯一のフロー制御機構は「c」演算子によって提供される「現在の継続を伴う呼び出し」 である。「`c//A//」というコードが評価されると、その瞬間の処理系の状態を表す「継続」と呼ばれる特殊なオブジェクトが生成される。続いて「//A//」の部分が評価され、その評価結果に対して、先の継続オブジェクトが引数として渡される。もしも、その継続が引数として渡されることがなければ、コード「`c//A//」の評価値は「//A//」の評価値と同じになる。しかし、その継続オブジェクトが「//B//」に渡されたなら、「//A//」の実行はすぐに中断され、コード「`c//A//」の全体としての評価は「//y//」になる。

en言語の既定の評価戦略は先行評価であるが、d演算子をつかえば遅延評価をさせることもできる。原則としては「`//AB//」というコードは、まず //A// そして //B// を評価し、それから、//A// に対して //B// を適用する。しかしながら、もし //A// が特殊な値「d」を評価するなら、//B// が評価される代わりに、「`d//B//」が「遅延演算」という特殊なオブジェクトになる。その遅延演算オブジェクトに引数 //C// が適用された時に初めて //B// が評価される。それ自身に副作用がないという点で、`d演算子と`i演算子は等価であるといえる。ただし、「`d//B//」では後に何かの引数が適用された場合に //B// の副作用が発生するが、「`i//B//」では //B// を評価する時点で副作用が発生するという点で異なる。

en言語には「v」という組込演算子もある。これは引数を無視してvを返すものである。厳密にいうと、この演算子は必要不可欠というわけではない。というのは、v演算子は「```s``s`kskk``s``s`kskk」として実現することができるからである。つまり、この演算子は利便性のために用意されているものである。

3.3. バージョン2で追加になった物
-------------------

en言語の第2版では新たな機能が導入された。「@」と「?//U//」によって、enプログラムへの外部からのデータ入力が出来るようになったのである。「@」が関数 //A// に適用されると、入力から文字をひとつ読み込み、「現在の文字」として保存する。それから、関数 //A// がi演算子に適用される。しかし、もし入力から文字を読み込むことでできない場合は、「現在の文字」は未定義状態のままにされ、関数 //A// はv演算子に適用される。?//U//関数は、この関数が関数 //A// に適用されると、「現在の文字」が「//U//」であれば「`//A//i」が、そうでなければ「`//A//v」が評価されるというものである。

「再表示関数」と呼ばれる関数「|」もある。これは、この関数が関数 //A// に適用されると、「現在の文字」が //U// であれば関数 //A// が 「.//U//」に適用され、そうでなければ関数 //A// が 「v」に適用されるというものである。

最後に、「終了関数」の「e」がある。 これは、この関数が関数 //A// に適用されると、プログラムの実行が終了され、関数 //A// がそのプログラム全体の最終結果として返される。

4. 脚注
-----

5. 参考文献
-------

Felix-Hernandez Campos , [1], ノースカロライナ大学 COMP144

6. 関連項目
-------

Lazy K
Iota 
Jot 
Joy 

7. 外部リンク
--------

[2]
[3]