美しいプログラミング言語構文を考える

第3回

信用と保証

宣言型プログラミング言語であると言うこと

とても難しい宣言型プログラミング言語の説明

前回の頭に「プログラミング言語の構成要素を言及するとき、粒度や視野の違いによってそれらはまちまちである」と意訳できることを述べた。

それはプログラミング言語の今さらだが、これを一般にパラダイムと言う。 [annotation: 今さらだが、これを一般にパラダイムと言う。] について語るときも同様である。

その点で宣言型プログラミング言語は比較的大きく広い概念であると言えるだろう(以後全てについてプログラミング言語であるため、これを言語と省略する)。

例えば関数型言語と呼ばれるものは、これの最大派閥だ。

その名の通りデータの宣言を主とする考え方だが、これを本質とは言い難い。

あらゆる言語にデータの宣言は存在する上、その点で言えばクラスと言う統括機能を持つオブジェクト指向言語の方が、宣言のまとまりと言う面においてそれらしい印象がある。

なお、オブジェクト指向言語を指して宣言型言語だと言うことはこれこそ粒度や視野の異なる概念である。両方の性質をあわせ持つ言語も存在する。 [annotation: これこそ粒度や視野の異なる概念である。両方の性質をあわせ持つ言語も存在する。] だろう。

宣言型言語の本質は副作用思想にある。

基本的にプログラミングによって得られるものは入力と出力の繰り返しである。

ある入力Aによって、ある出力Bが発生する操作がある。

この入力Aと出力Bには関連があると人間は信じてこの操作を行うのだ。

さて、実はこの操作内部には1つ前の入力を記憶する領域があり、それが特定の内容であるとき代わりに出力Cを発生させる。

ここで2回目の入力を考える。1回目の入力を確認できないとき、この場合の出力は何だろうか。

確率論的に判断することはできるが、実際の出力が確定することはない。

こういった操作を一般に副作用のある操作と言う。この場合、副作用そのものは1つ前の入力を記憶する領域である。

この副作用が良い悪いではなく、途中で挟んだ「人間が信じる」と言う過程が最重要である。

副作用を持つ操作単体を真の意味で信じることはできないと言いたいのだ。

この操作のように内部が明確であればまだ良い。だが、多くの場合そうではない。

プログラミングで利用するリソースを全て自分で賄うことは稀である。第三者が記述した資産を何らかの形で利用する場合が多いと言うことだ。

たいていそれらは、ユーザ目線では中身を確認しなくても良い(動作する)プログラムのこと。大オープンソース時代の現代において、たいていの場合中身を確認しようと思えば確認できる。 [annotation: 中身を確認しなくても良い(動作する)プログラムのこと。大オープンソース時代の現代において、たいていの場合中身を確認しようと思えば確認できる。] であり、何が行われているかを知るにはコストを支払う必要があるだろう。

さて、ユーザが記述したコードが想定通りの動作をしないとき、最終的にはそのブラックボックスに捜査の手を伸ばさざるをえない。

そして、コード内部をじっくり監査し、ようやく原因となる副作用を見つけられるのである。

この場合、ユーザが同時に第三者は信用を失なった。 [annotation: 同時に第三者は信用を失なった。] と言える。結局そのためにクリティカルな手段を講じるための時間というコストを支払うのだ。

この場合の最適解はユーザが第三者を信じると言うことだ。かつ、第三者が「我々のコードのこことここには副作用が含まれ、それ以外に副作用はない」と明示することである。

明らかに根本的解決とは言いにくいが、これが真の意味で信じられないと言うことだ。

ミスや解釈違いなど、人間が記述・操作するものであるから例外は発生しうるものなのである。

当事者同士でこれが最適解だとするなら、これ以上はどうすべきなのか。

――――このやりとりを言語側で保証すると言うのが宣言型言語の本質である。

宣言型言語は信用に特化した言語であり、ゆえに自己解釈であるが、そう遠い理由ではないだろう。 [annotation: 自己解釈であるが、そう遠い理由ではないだろう。] なのだ。

この副作用にまつわる保証が必要だからこそ、宣言型言語が大分類である所以であり、その実現方法が様々な方法で模索された結果、多くの派閥を抱えているのだ。

なお、一般に宣言型言語の学習は難しいと言われている印象がある。この保証そのものが非常に難しい問題であるために、非宣言型言語よりも理解へのプロセスが複雑なのだろう。

何故宣言型プログラミング言語であるべきか

さて、ここまで宣言型言語がどのようなものか述べてきたが、ここからはWyv言語が第2回より。 [annotation: 第2回より。] わけに触れていく。

最大の理由、それは副作用を意図せず生成しないために常備されるべきである宣言型言語のとある仕組みが、第1回で定義したような「美しさ」にとって都合の良いためである。

特に不変変数を基本とする構造のことをここでは指している。

その名のとおり変数が不変、すなわち、変数への代入が実際には全ての変数が不変であると効率面で悪化の恐れがあり、可変変数を利用するために特殊なマークを要求する実装などによって表現される。デフォルトが不変である変数システムと表記する方が正しい。 [annotation: 実際には全ての変数が不変であると効率面で悪化の恐れがあり、可変変数を利用するために特殊なマークを要求する実装などによって表現される。デフォルトが不変である変数システムと表記する方が正しい。] と言うことである。

これはもはや代入とは異なる概念であるため、束縛と言われている。

察しがつくかもしれないが、これも副作用の有無を保証するためのものだ。

先述の入力と出力に関する操作とはやや状況が異なるが、複雑な操作を想定したときに変数の内部が常に同一であるとは、非宣言型言語において限らないのである。

第三者を信用できるかと先にあったが、この「第三者」は過去や未来の自分自身である可能性もあると言うことだ。

――――合理的で良い仕組みだが、直接的にWyv言語の要求する美しさには影響しないように思えるだろう。

これの注目すべき点は副作用がどうこうではなく、単に変数を操作する方法が厳密に縛られていると言うことだ。

そう「表記のブレが限りなく少ないこと」である。

変数への代入が無制限であると言うことは、ある変数を定義・表現する方法が複数あると言うことになる。すなわち、変数を無意味に段階的な表現で置き換えることが許容されてしまうと言うことだ。

それはこの美しさの観点から望ましくない。

x += 1が望ましい表現でないことは先に述べたとおりであるが、ここにきて二重の意味で望ましくないこととなったわけである。

少なくとも単純な変数の表現方法は制限されるべきなのだ。

さて、1つの機能をある考え方に合わせたとき、その他の機能をバラバラの思想から引用することは基本的に想定されない。

ここでは不変変数のこと。 [annotation: ここでは不変変数のこと。] はそれに最適化されていると考えるべきだからだ。

従って、Wyv言語は宣言型言語をベースにする必要がある。

あくまでベースであり、今後の展開によって差し戻しをせずにすむよう、決め打ちは避けておく。特に最近はマルチパラダイム言語と一般に呼称される。良いとこ取りと言う奴だ。 [annotation: マルチパラダイム言語と一般に呼称される。良いとこ取りと言う奴だ。] も珍しくはない。

宣言型言語を軸にすると決めたところで、ついに構文そのものを構築していくことになる。おそらくこれが美しさを左右する最も重要な段階だろう。

次回はブロックについて扱う予定だ。