Unlambda

Unlambda（アンラムダ）はコンビネータ論理とラムダ計算に基づく、仕様の小さな、ほぼ純粋な関数型言語のプログラミング言語である。デビッド・マドレ()によって設計された。
概要.
この言語はコンビネータ論理とラムダ計算にもとづいている。この言語は主に2つの組込関数(「s」と「k」)および、関数適用演算子(「`」と書かれる)によって成り立っている。これらだけによってチューリング完全をなしているが、ユーザーとのインタラクションを可能にする入出力関数群と、いくつかのショートカット関数群、そして、遅延評価のための関数も備えている。この言語には変数は存在しない。
言語の目的は実用ではなく純粋関数型言語の実証にあるため、この言語は難解なプログラミング言語になっている。実用的な普通の言語にあるような演算子やデータ型が存在しないというのがこの言語の大きな特徴である。この言語に唯一存在するデータは1引数の関数だけである。それにもかかわらず、あらゆるデータはラムダ計算による関数を用いて表現することができる。複数の引数の関数もカリー化の手法によって表現することができる。
言語は抽象削除の原理(あるいは、関数を含むあらゆる変数の削除の原理)で動作する。純関数型言語であるため、言語の関数は一階のオブジェクトである。また、この言語にとって関数とは唯一のオブジェクトでもある。
処理系の実装は色々なプログラミング言語で行われている。ML系の言語では100行程度で実装されている。
例.
下記は言語によるHello worldプログラムの実装例である。
組み込み関数.
一覧.
組み込み関数の一覧は以下の通り。
バージョン1から存在する物.
「codice_1」や「codice_2」などの、「codice_3」で表されるものは恒等関数 (引数として与えられた値を全く変更せずにそのまま返す関数) で、副作用として「"A"」を表示するものである。「codice_4」は副作用を伴わない恒等関数である。上述の Hello world プログラムではダミーの引数として使われている。「codice_5」というプログラムは、文字「d」を表示する関数(「codice_6」)に引数codice_4を適用して呼び出すもので、戻り値(評価結果)として関数「codice_4」を返し、副作用として文字「d」を表示する。同様に、「codice_9」というプログラムでは、まず、関数「 codice_10」に引数として「codice_6」が適用され、文字「l」が表示されて、戻り値として関数「codice_6」を返す。そして次に、この戻り値「codice_6」に対して、引数として関数「codice_4」が適用され、前述の通りの動作が続く。関数「codice_15」は改行文字を表示する関数の糖衣構文である。
言語のその他の重要な特徴として、「codice_16演算子」と「codice_17演算子」がある。codice_16演算子は、引数の値に関係なく戻り値として "A" を返す演算子である。つまり、「codice_19」の戻り値は、 "B" の値に関係なく、いつも "A" である。
「codice_17」は汎用の評価演算子である。「codice_21」というプログラムは、"A"、"B"、"C"の値に関係なく、「codice_22」と評価される。この「codice_17」と「codice_24」だけでいかなる計算も行えるという事実は、注目すべき点である。例えば、恒等関数「codice_4」は「codice_26」によって実現することができる。なぜなら、「codice_27」は、いかなる "A" に対しても "A" を返すからである。
言語の唯一のフロー制御機構は「codice_28」演算子によって提供される「現在の継続を伴う呼び出し」() である。「codice_29」というコードが評価されると、その瞬間の処理系の状態を表す「継続」と呼ばれる特殊なオブジェクトが生成される。続いて「"A"」の部分が評価され、その評価結果に対して、先の継続オブジェクトが引数として渡される。もしも、その継続が引数として渡されることがなければ、コード「codice_29」の評価値は「"A"」の評価値と同じになる。しかし、その継続オブジェクトが「"B"」に渡されたなら、「"A"」の実行はすぐに中断され、コード「codice_29」の全体としての評価は「"y"」になる。
言語の既定の評価戦略は先行評価であるが、codice_32演算子をつかえば遅延評価をさせることもできる。原則としては「codice_33」というコードは、まず "A" そして "B" を評価し、それから、"A" に対して "B" を適用する。しかしながら、もし "A" が特殊な値「codice_32」を評価するなら、"B" が評価される代わりに、「codice_35」が「遅延演算」という特殊なオブジェクトになる。その遅延演算オブジェクトに引数 "C" が適用された時に初めて "B" が評価される。それ自身に副作用がないという点で、codice_36演算子とcodice_37演算子は等価であるといえる。ただし、「codice_35」では後に何かの引数が適用された場合に "B" の副作用が発生するが、「codice_39」では "B" を評価する時点で副作用が発生するという点で異なる。
言語には「codice_40」という組込演算子もある。これは引数を無視してcodice_40を返すものである。厳密にいうと、この演算子は必要不可欠というわけではない。というのは、codice_40演算子は「codice_43」として実現することができるからである。つまり、この演算子は利便性のために用意されているものである。(このコードは、不動点演算子 codice_44を使って、さらに簡単に「codice_45」と表現することもできる。)
バージョン2で追加になった物.
言語の第2版では新たな機能が導入された。「codice_46」と「codice_47」によって、プログラムへの外部からのデータ入力が出来るようになったのである。「codice_46」が関数 "A" に適用されると、入力から文字をひとつ読み込み、「現在の文字」として保存する。それから、関数 "A" がcodice_4演算子に適用される。しかし、もし入力から文字を読み込むことでできない場合は、「現在の文字」は未定義状態のままにされ、関数 "A" はcodice_40演算子に適用される。codice_47関数は、この関数が関数 "A" に適用されると、「現在の文字」が「"U"」であれば「codice_52」が、そうでなければ「codice_53」が評価されるというものである。
「再表示関数」と呼ばれる関数「codice_54」もある。これは、この関数が関数 "A" に適用されると、「現在の文字」が "U" であれば関数 "A" が 「codice_55」に適用され、そうでなければ関数 "A" が 「codice_40」に適用されるというものである。
最後に、「終了関数」の「codice_57」がある。 これは、この関数が関数 "A" に適用されると、プログラムの実行が終了され、関数 "A" がそのプログラム全体の最終結果として返される。(とはいえ、既存のインタプリタのほとんどがその結果値を無視する。)