![](https://habrastorage.org/files/911/f92/fbb/911f92fbb16e4d92ba67002bf28c1ac1.jpg)
プログラムの概念から始めましょう。 数学的な観点から見ると、プログラムは関数です。 時々これは明らかではないかもしれません。 プログラムが関数の場合、引数が何であり、何が返されるかを決定する必要があります。 bcのような単純なユーティリティの場合、すべてが明確です。引数はstdinの式であり、結果はstdoutの結果です。 より複雑なケースでは、プログラムが関数であるという結論に達することもできます。 たとえば、DBMSを考えてみましょう。この場合、プログラムは関数でもあり、引数を使用してuser-spaceに割り当てられたメモリを取得し、継続的に実行しながらそれを返します。 それはかなり次善の例かもしれませんが、理解できます。
プログラムが関数である場合、この関数を取得する手段がどのようなものになるかを検討する必要があります。 それはすべてプログラミング言語に依存し、それらはそのようなツールです。 そして、それが関数型言語、手続き型、命令型、宣言型などであるかどうかにかかわらず、それらはすべて明示的または暗黙的な構成を使用する傾向があります。 構成の概念を定義する時が来ました。 2つの関数を与えましょう
![](https://habrastorage.org/getpro/habr/post_images/0ca/284/f28/0ca284f284dc0e909bf3061ff5255a19.png)
![](https://habrastorage.org/getpro/habr/post_images/36e/eed/f7b/36eeedf7bfc4011473c607e2aa57de6d.png)
![](https://habrastorage.org/getpro/habr/post_images/c7a/f3e/fe9/c7af3efe9053acd355bae877cdee6ab8.png)
![](https://habrastorage.org/getpro/habr/post_images/3e2/06d/978/3e206d9787f9adffcf24532be73bcc19.png)
![](https://habrastorage.org/getpro/habr/post_images/c7a/f3e/fe9/c7af3efe9053acd355bae877cdee6ab8.png = F(f_1,f_2))
![](https://habrastorage.org/getpro/habr/post_images/c7a/f3e/fe9/c7af3efe9053acd355bae877cdee6ab8.png)
支店組成物。 2つの関数を与えましょう
![](https://habrastorage.org/getpro/habr/post_images/0ca/284/f28/0ca284f284dc0e909bf3061ff5255a19.png)
![](https://habrastorage.org/getpro/habr/post_images/36e/eed/f7b/36eeedf7bfc4011473c607e2aa57de6d.png)
![](https://habrastorage.org/getpro/habr/post_images/c8b/220/0b3/c8b2200b373dd2f6fcbab9f1c79ef2aa.png)
![](https://habrastorage.org/getpro/habr/post_images/c04/661/121/c04661121da236d614d4b2c4ca0a13d1.png)
![](https://habrastorage.org/getpro/habr/post_images/c38/707/d73/c38707d73ddbf890a11b5c264e2c4750.gif)
![](https://habrastorage.org/getpro/habr/post_images/c04/661/121/c04661121da236d614d4b2c4ca0a13d1.png)
![](https://habrastorage.org/getpro/habr/post_images/69d/46f/49d/69d46f49d8604cf5918c91c084be3473.png)
![](https://habrastorage.org/getpro/habr/post_images/c04/661/121/c04661121da236d614d4b2c4ca0a13d1.png = If(p, f_1, f_2))
重ね合わせ構成 。 設定しましょう
![](https://habrastorage.org/getpro/habr/post_images/b75/018/bdf/b75018bdf6686c7b196dc0b5a2951856.png)
![](https://habrastorage.org/getpro/habr/post_images/00d/d5f/f65/00dd5ff65d7edff1520e2955f2455cec.png)
![](https://habrastorage.org/getpro/habr/post_images/f20/678/c96/f20678c9638f25972870a772a6cad335.png)
![](https://habrastorage.org/getpro/habr/post_images/3e0/0c6/192/3e00c61929b9d2e5eb29c4379a0f69ce.png)
![](https://habrastorage.org/getpro/habr/post_images/77c/b65/87e/77cb6587e2a0805b69003627abacaf8f.png)
![](https://habrastorage.org/getpro/habr/post_images/77c/b65/87e/77cb6587e2a0805b69003627abacaf8f.png = f(f_1(X),f_2(X),...f_n(X)))
![](https://habrastorage.org/getpro/habr/post_images/77c/b65/87e/77cb6587e2a0805b69003627abacaf8f.png)
![](https://habrastorage.org/getpro/habr/post_images/c3a/7cb/869/c3a7cb869a7ccdb96d374dec79f69321.png)
![](https://habrastorage.org/getpro/habr/post_images/77c/b65/87e/77cb6587e2a0805b69003627abacaf8f.png=S^{n+1}(f,f_1,...,f_n))
これらの操作のプロトタイプをプログラミング言語で検討してください。 どこかでより明確で、どこかより少ない。 C言語では、分岐操作は明らかに制御構造に隠されています
![](https://habrastorage.org/getpro/habr/post_images/44a/119/7e8/44a1197e8adc4fc1715942cff04de61e.png)
if(p(X)) f1(X); else f2(X);
または三項演算子: 最初のケースでは、表現ではなくステートメントが考慮されましたが、これはプレゼンテーションに干渉しませんp(X) ? f1(X) : f2(X);
![](https://habrastorage.org/getpro/habr/post_images/a04/d59/179/a04d59179f39458aafb7594036b36b5d.png)
(if (p X) (f1 X) (f2 X))
Haskellでは、次のようになります if p X then f1 X else f2 X
どちらか
gx | px == True = f1 x | px == False = f2 x
重ね合わせの操作について話すと、多くのプログラミング言語ではさらに目立たなくなりますが、それでも遍在しています。 C言語の重ね合わせ演算により、次の置換が可能になります f(f1(X), f2(X), f3(X));
LISPでは、次のようになります (f (f1 X) (f2 X) (f3 X))
Haskellと同じ f (f1 x) (f2 x) (f3 x)
提案されたすべての機能のアリティが統一されるべきであることにすぐに注意する必要があります。そうしないと、それらへの合成メカニズムの適用が著しく困難になる可能性があります。 Xは実際には次のようなものです
![](https://habrastorage.org/getpro/habr/post_images/a04/d59/179/a04d59179f39458aafb7594036b36b5d.png = {x_1,x_2,x_3...x_n})
明らかに、コンポジションはプログラミング言語の構文に深く「埋もれて」おり、暗黙的にそれらに含まれています。 しかし、洗練された読者なら当然気付くことができるように、新しいものは何もありません。 Edsgar Dijkstraでさえ、彼の著書「プログラミングの規律」でこれに気付きました。
曲を使う
上記に関連して、多くの疑問が生じます。 特に、構成が明示的に使用されないのはなぜですか? 実際、組成物の使用は明確に多くの利点をもたらす可能性があります。 特に、プログラミングプロセス自体を考慮することが可能になるため、複雑なプロジェクトの開発を最適化できます。 結局のところ、プログラマーは現在どのようにプログラミングしていますか? 彼は絵を描くアーティストとしてこれを行います。 言い換えれば、デザインの決定は、彼の経験、予感、同僚のアドバイス、いくつかの個人的な美的信念に基づいて行われます。 しかし、この考え方は、プログラムでファイルに単純に入れることはできません。 つまり プログラムはありますが、それを導いた一連の思考はありません。 これが最初の質問です。 なぜ言語はそのような構文を持っているのか、なぜ言語の作成者はまさにそのような制御構造のセットを定めているのか? なぜ彼らのセットは独断的なのですか? 他の制御構造を追加する必要がある場合の対処方法。
これらの質問は、組成物の適用と生成の手段を解決するのに役立ちます。 人による任意の複雑なタスクの解決策は、分析/分解、そして合成に縮小されるため、このプロセスは構成メカニズムによって有機的にサポートされます。 結局、コンポジションは、タスクが分割されたパーツを接着する正確な接続要素になります。 まあ、人は何らかの方法でタスクを壊さなければなりません、それはまさに彼の特権であり、タスクの構文設計ではありません。 残念ながら、これまでのところ、作曲の概念に合わせて調整された単一の言語は認識されていません。
理解を深めるために、コンポジションを使用して最大公約数(GCD)を見つける例を検討してください。 電卓は、除算の残りを見つけることができます(
![](https://habrastorage.org/getpro/habr/post_images/23f/e87/541/23fe875417d710bdddf770084b0e369f.png)
![](https://habrastorage.org/getpro/habr/post_images/01b/d9d/50a/01bd9d50a530a5743d0c3f9768a4927f.png)
![](https://habrastorage.org/getpro/habr/post_images/6ec/fc7/f04/6ecfc7f04920a82d326e84f8810361ed.png)
![](https://habrastorage.org/getpro/habr/post_images/50c/900/43a/50c90043a4c85c9b3c70474635fdee9f.png)
![](https://habrastorage.org/getpro/habr/post_images/3bf/9e7/a85/3bf9e7a855475daadf102161895fc900.png)
![](https://habrastorage.org/getpro/habr/post_images/01b/d9d/50a/01bd9d50a530a5743d0c3f9768a4927f.png)
![](https://habrastorage.org/getpro/habr/post_images/23f/e87/541/23fe875417d710bdddf770084b0e369f.png)
![](https://habrastorage.org/getpro/habr/post_images/50c/900/43a/50c90043a4c85c9b3c70474635fdee9f.png)
![](https://habrastorage.org/getpro/habr/post_images/6ec/fc7/f04/6ecfc7f04920a82d326e84f8810361ed.png)
![](https://habrastorage.org/getpro/habr/post_images/09f/51c/f76/09f51cf766f214ea26d5da8e989f36ce.png)
![](https://habrastorage.org/getpro/habr/post_images/09f/51c/f76/09f51cf766f214ea26d5da8e989f36ce.png)
![](https://habrastorage.org/getpro/habr/post_images/3e0/0c6/192/3e00c61929b9d2e5eb29c4379a0f69ce.png)
![](https://habrastorage.org/getpro/habr/post_images/94b/5ab/51d/94b5ab51daddd82cf2c2a612d2031cbf.png)
![](https://habrastorage.org/getpro/habr/post_images/3e0/0c6/192/3e00c61929b9d2e5eb29c4379a0f69ce.png)
![](https://habrastorage.org/getpro/habr/post_images/b75/018/bdf/b75018bdf6686c7b196dc0b5a2951856.png)
![](https://habrastorage.org/getpro/habr/post_images/3e0/0c6/192/3e00c61929b9d2e5eb29c4379a0f69ce.png)
![](https://habrastorage.org/getpro/habr/post_images/0ca/284/f28/0ca284f284dc0e909bf3061ff5255a19.png, f_2,...f_n)
![](https://habrastorage.org/getpro/habr/post_images/3e0/0c6/192/3e00c61929b9d2e5eb29c4379a0f69ce.png)
![](https://habrastorage.org/getpro/habr/post_images/c8b/220/0b3/c8b2200b373dd2f6fcbab9f1c79ef2aa.png)
![](https://habrastorage.org/getpro/habr/post_images/0ca/284/f28/0ca284f284dc0e909bf3061ff5255a19.png)
![](https://habrastorage.org/getpro/habr/post_images/549/b03/dca/549b03dca36221c3a00e830676cca1b1.png)
![](https://habrastorage.org/getpro/habr/post_images/36e/eed/f7b/36eeedf7bfc4011473c607e2aa57de6d.png)
![](https://habrastorage.org/getpro/habr/post_images/c32/0f6/327/c320f632753848fd8defdb08f857ef7c.png)
![](https://habrastorage.org/getpro/habr/post_images/0ca/284/f28/0ca284f284dc0e909bf3061ff5255a19.png)
![](https://habrastorage.org/files/6ab/96f/dd0/6ab96fdd01e34c89907f85779c173971.png)
したがって、アルゴリズム自体を「数学の言語」で定式化することが可能になります。つまり、数学的な手段で研究できるため、人が書くプログラミング言語ではなく、実際には、さまざまな言語の根底にある構成を反映します。
ソリューション自体への組成的アプローチは、A.I。 Maltsev(Maltsev代数)、学者Glushkov(アルゴリズム代数)。 しかし、それらはすべて、作曲の適用レベルで機能し、作曲中の作曲セットを独断的に扱います。 構成アプローチの重要な改善点は、既存の構成からメタ構成を適用することで新しい構成を取得できることです。 このトピックは興味深いものです。誰もそれに触れることはありませんが、次回はそれについて詳しく説明します。 私はあなたを退屈させなかったと思います。
以上が私の研究の主題です。 私はすぐに、同じGCDアルゴリズムのように、または計算の割合が無視できるプロジェクトで、単純な計算に使用するための合成アプローチが提案されていないことを述べます。 コミュニティが信じていることを本当に知りたいです。 組成アプローチには未来がありますか? 作曲を練習しますか? このためのツールが必要ですか?
PS突然、作曲のテーマに触れた最近の投稿を見ました。 それらが互いに補完することを望みます。
PPS記事の修正を手伝ってくれたsekrasoftに感謝します。