ITエンジニアのブログ

IT企業でエンジニアやってる人間の日常について

プログラミング言語を作る。第12回:関数適用とメソッドチェーン

今、二つの数値を受け取り、その和を返す関数 add があるとします。

多くの関数型言語で用いられる関数適用は、次のような形を指定します。

add 1 2

exp を式として、 exp exp という形です。他方で、手続き型やオブジェクト指向型の言語での関数適用は、次のような形を指定します。

add(1, 2)

もしこの記法が関数型言語のものであるとすると、 add という関数に (1, 2) というタプルを適用する格好になります。自作言語では、そう解釈するようにしようと思います。

また、最近の言語だと、メソッドをたくさんつなげる事ができます。例えば、 a という変数の値に f という関数を適用し、その結果に対し g を、さらにその結果に h を適用する場合は次のように書きます。

a.f(b).g(c, d).h()

ここで、結合力の問題が出てきます。 f x のような関数適用と、ドットを用いた関数適用の結合力をどちらが強力にするかについてです。メソッドチェーンが実行可能なようにするためには両者の結合強度が等しいことが条件になりますが、例えば

f x y.z

という式は、 f という関数に二つの引数 x, y.z を適用すると考えるのが適当でしょう。この場合、ドットのほうが結合力が強いと判断できます。このように、結合力について矛盾が起きてしまいます。これを解決するためには、新しい演算子を定義するしかないように思えます。例えば、まず exp.exp は exp exp よりも結合力が強いと判断し、 exp exp よりも結合力の弱い(等しいの方が妥当か)演算子として exp .. exp を定義すると、メソッドチェーンが

a.f (b) .. g (c, d) .. h ()

というように表され、衝突を起こすことがなくなると思います。