Unlambda
パラダイム | 関数型言語 |
---|---|
設計者 | David Madore |
最新リリース | 2.0.0/ 1999年12月20日 |
型付け | なし |
主な処理系 | unlambda |
影響を与えた言語 | Lazy K |
プログラミング言語 | C言語, CAML, Java, Perl, Scheme, SML/NJ |
ウェブサイト |
www |
Unlambda(アンラムダ)はコンビネータ論理とラムダ計算に基づく、仕様の小さな、ほぼ純粋な関数型言語のプログラミング言語である[1]。デビッド・マドレ(David Madore)によって設計された。
概要
[編集]この言語はコンビネータ論理とラムダ計算にもとづいている。この言語は主に2つの組込関数(「s」と「k」)および、関数適用演算子(「`」と書かれる)によって成り立っている。これらだけによってチューリング完全をなしているが、ユーザーとのインタラクションを可能にする入出力関数群と、いくつかのショートカット関数群、そして、遅延評価のための関数も備えている。この言語には変数は存在しない。
Unlambda言語の目的は実用ではなく純粋関数型言語の実証にあるため、この言語は難解なプログラミング言語になっている。実用的な普通の言語にあるような演算子やデータ型が存在しないというのがこの言語の大きな特徴である。この言語に唯一存在するデータは1引数の関数だけである。それにもかかわらず、あらゆるデータはラムダ計算による関数を用いて表現することができる。複数の引数の関数もカリー化の手法によって表現することができる。
Unlambda言語は抽象削除の原理(あるいは、関数を含むあらゆる変数の削除の原理)で動作する。純関数型言語であるため、Unlambda言語の関数は一階のオブジェクトである。また、この言語にとって関数とは唯一のオブジェクトでもある。
処理系の実装は色々なプログラミング言語で行われている。ML系の言語では100行程度で実装されている。
例
[編集]下記はUnlambda言語によるHello worldプログラムの実装例である。
`r```````````.H.e.l.l.o. .w.o.r.l.di
組み込み関数
[編集]一覧
[編集]組み込み関数の一覧は以下の通り。
- `
- 関数適用
- 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文字読み込み、表示する
バージョン1から存在する物
[編集]「.H
」や「.e
」などの、「.A
」で表されるものは恒等関数 (引数として与えられた値を全く変更せずにそのまま返す関数) で、副作用として「A」を表示するものである。「i
」は副作用を伴わない恒等関数である。上述の Hello world プログラムではダミーの引数として使われている。「`.di
」というプログラムは、文字「d」を表示する関数(「.d
」)に引数i
を適用して呼び出すもので、戻り値(評価結果)として関数「i
」を返し、副作用として文字「d」を表示する。同様に、「``.l.di
」というプログラムでは、まず、関数「 .l
」に引数として「.d
」が適用され、文字「l」が表示されて、戻り値として関数「.d
」を返す。そして次に、この戻り値「.d
」に対して、引数として関数「i
」が適用され、前述の通りの動作が続く。関数「r
」は改行文字を表示する関数の糖衣構文である。
Unlambda言語のその他の重要な特徴として、「kA
演算子」と「s
演算子」がある。kA
演算子は、引数の値に関係なく戻り値として A を返す演算子である。つまり、「``kAB
」の戻り値は、 B の値に関係なく、いつも A である。
「s
」は汎用の評価演算子である。「```sABC
」というプログラムは、A、B、Cの値に関係なく、「``AC`BC
」と評価される。この「s
」と「k
」だけでいかなる計算も行えるという事実は、注目すべき点である。例えば、恒等関数「i
」は「``skk
」によって実現することができる。なぜなら、「```skkA
」は、いかなる A に対しても A を返すからである。
Unlambda言語の唯一のフロー制御機構は「c
」演算子によって提供される「現在の継続を伴う呼び出し」(call with current continuation) である。「`cA
」というコードが評価されると、その瞬間の処理系の状態を表す「継続」と呼ばれる特殊なオブジェクトが生成される。続いて「A」の部分が評価され、その評価結果に対して、先の継続オブジェクトが引数として渡される。もしも、その継続が引数として渡されることがなければ、コード「`cA
」の評価値は「A」の評価値と同じになる。しかし、その継続オブジェクトが「B」に渡されたなら、「A」の実行はすぐに中断され、コード「`cA
」の全体としての評価は「y」になる。
Unlambda言語の既定の評価戦略は先行評価であるが、d
演算子をつかえば遅延評価をさせることもできる。原則としては「`AB
」というコードは、まず A そして B を評価し、それから、A に対して B を適用する。しかしながら、もし A が特殊な値「d
」を評価するなら、B が評価される代わりに、「`dB
」が「遅延演算」という特殊なオブジェクトになる。その遅延演算オブジェクトに引数 C が適用された時に初めて B が評価される。それ自身に副作用がないという点で、`d
演算子と`i
演算子は等価であるといえる。ただし、「`dB
」では後に何かの引数が適用された場合に B の副作用が発生するが、「`iB
」では B を評価する時点で副作用が発生するという点で異なる。
Unlambda言語には「v
」という組込演算子もある。これは引数を無視してv
を返すものである。厳密にいうと、この演算子は必要不可欠というわけではない。というのは、v
演算子は「```s``s`kskk``s``s`kskk
」として実現することができるからである。つまり、この演算子は利便性のために用意されているものである。(このコードは、不動点演算子 Y
を使って、さらに簡単に「`Yk
」と表現することもできる。)
バージョン2で追加になった物
[編集]Unlambda言語の第2版では新たな機能が導入された。「@
」と「?U
」によって、Unlambdaプログラムへの外部からのデータ入力が出来るようになったのである。「@
」が関数 A に適用されると、入力から文字をひとつ読み込み、「現在の文字」として保存する。それから、関数 A がi
演算子に適用される。しかし、もし入力から文字を読み込むことでできない場合は、「現在の文字」は未定義状態のままにされ、関数 A はv
演算子に適用される。?U
関数は、この関数が関数 A に適用されると、「現在の文字」が「U」であれば「`Ai
」が、そうでなければ「`Av
」が評価されるというものである。
「再表示関数」と呼ばれる関数「|
」もある。これは、この関数が関数 A に適用されると、「現在の文字」が U であれば関数 A が 「.U
」に適用され、そうでなければ関数 A が 「v
」に適用されるというものである。
最後に、「終了関数」の「e
」がある。 これは、この関数が関数 A に適用されると、プログラムの実行が終了され、関数 A がそのプログラム全体の最終結果として返される。(とはいえ、既存のUnlambdaインタプリタのほとんどがその結果値を無視する。)
脚注
[編集]参考文献
[編集]- Felix-Hernandez Campos (2002年4月1日), Lecture 28: More on functional programming, ノースカロライナ大学 COMP144
- 原 悠 (2008) (日本語). Rubyで作る奇妙なプログラミング言語. 毎日コミュニケーションズ. p. 205–214. ISBN 4839927847