web-dev-qa-db-ja.com

次のレベルの抽象化は何ですか?

プログラミング言語は、最初は順次実行されるコード行のみを使用し、抽象化の最初のレベルの1つである関数を含むように進化し、さらにそれをさらに抽象化するためにクラスとオブジェクトが作成されました。次のレベルの抽象化は何ですか?

クラスより抽象的なものは何ですか?それともまだありますか?

15
Jordan Medlock

コンピューティングの歴史について誤解されていると思います。

最初の抽象化(1936年)は、実際には、アロンツォ教会のラムダ計算でした。これは、高次関数とそれに続くすべての関数型言語の概念の基礎です。それは直接LISP(1959年に作成された2番目に古い高水準プログラミング言語)に影響を与え、MLからHaskellやClojureまですべてに影響を与えました。

2番目の抽象化は、手続き型プログラミングでした。それは、逐次プログラムが一度に1つの命令で作成されるフォンノイマンコンピュータアーキテクチャから生まれました。 FORTRAN(1958年の最古の高水準プログラミング言語)は、手続き型パラダイムから生まれた最初の高水準言語でした。

3番目の抽象化はおそらく実際には宣言型プログラミングであり、最初はAbsys(1967)、次にProlog(1972)で例示されました。これは論理プログラミングの基礎であり、一連の命令を実行するのではなく、一連の宣言またはルールを照合することによって式が評価されます。

4番目の抽象化はオブジェクト指向プログラミングであり、60年代にLISPプログラムで最初に登場しましたが、1972年にSmalltalkによって例示されました(SmalltalkのメッセージパッシングスタイルがOne Trueオブジェクト指向の抽象化です。ここでは触れません。)

他のすべての抽象化、特に伝統的なフォンノイマンコンピュータアーキテクチャは、これらの4つのテーマのバリエーションです。これらの4つ以外に、単なるバリエーションや組み合わせではない抽象化があるとは思いません。

しかし、抽象化は、本質的に、アルゴリズムをモデル化して記述する方法にすぎません。アルゴリズムは、一連の個別のステップとして、従わなければならない一連のルールとして、一連の数学関数として、または相互作用するオブジェクトとして説明できます。アルゴリズムを説明またはモデル化する他の方法を想像することは非常に難しく、たとえそれがあったとしても、その有用性については確信が持てません。

ただし、量子計算モデルがあります。量子コンピューティングでは、量子アルゴリズムをモデル化するために新しい抽象化が必要です。この分野の新生物なので、コメントすることはできません。

32
greyfade

多くの人にとって、バイナリプログラミングの現在の時代におけるコードの抽象化の最も純粋な形式は、「高次関数」です。基本的に、関数自体はデータとして扱われ、関数の関数は、オペランドの結果を定義する演算子とこれらの演算の「ネスト」を定義する所定の演算順序を含む数式で見られるように定義されます。数学の構造には、「命令コマンド」がほとんどありません。私が考えることができる2つの例は、「xに何らかの値を設定するか、何らかの制約に準拠する任意の値にする」と、出力を生成するために必要な式を入力が決定する「ピースワイズ関数」です。これらの構造は、独自の関数として簡単に表現できます。 「関数」xは常に1を返し、関数の「オーバーロード」はそれらに渡されるものによって定義されます(オブジェクト指向のオーバーロードとは異なり、値の入力に基づいて定義できます)。自分自身の観点からも機能します。そのため、プログラムは低レベルでの命令の概念を排除し、代わりに入力データを与えられた「自分自身を評価する」ことに焦点を当てています。

これらの高階関数は「関数型言語」のバックボーンを形成します。プログラムが行うことは、「純粋な関数」(1つ以上の入力、1つ以上の出力、副作用なし、または「隠された状態」)の観点から定義され、互いにネストされ、必要に応じて評価されます。このような場合、ほとんどの「命令論理」は抽象化されます。ランタイムは、関数の実際の呼び出し、および関数のいずれかのオーバーロードを呼び出す必要がある可能性のある条件を処理します。このようなプログラムでは、コードは何かを「行う」とは見なされず、「存在する」と見なされ、プログラムが初期入力を与えられて実行されるときに正確に何が決定されます。

高階関数は現在、多くの命令型言語の主食にもなっています。 .NETのラムダ文は、基本的には別の「関数」への「匿名の」関数入力を可能にします(命令的に実装されますが、理論的にはそうする必要はありません)。望ましい結果。

最新のプログラミング言語で一般的に見られるもう1つの抽象化は、「ダックタイピング」の概念に基づく動的変数タイピングです。アヒルのように見えたり、アヒルのように泳いだり、アヒルのように飛んだり、アヒルのように鳴いたりする場合は、アヒルと呼ぶことができます。それがマガモなのかキャンバスバックなのかは関係ありません。それが実際にガチョウか白鳥かどうかは重要かもしれませんが、それでもあなたが気にするのはそれが泳いで飛ぶことであり、そしてkindaがアヒルのように見えるかどうかは問題ではないかもしれません。これは、オブジェクト継承の究極と見なされています。名前を付ける以外は、何でも構いませんis。より重要なのは、それが何であるか行うです。そのような言語では、基本的に2つのタイプしかありません。 「atom」は情報の単一の要素(1つの「値」、数値、文字、関数など)、およびatomと「ポインタ」で構成される「タプル」タプル内の他のすべてのものに適用されます。これらの型がランタイムによってバイナリでどのように実装されるかは正確には関係ありません。これらを使用すると、単純な値型から文字列、コレクションなど、考えられるほぼすべての型の機能を実現できます。値はさまざまな「タイプ」にすることができ、「複雑なタイプ」または「オブジェクト」を許可します).

4
KeithS

SQLのようなドメイン固有言語を抽象化の上位として考えることができます。 SQLは、ストレージなどの操作を抽象化し、集合論に基づいてより高いレベルの関数を提供する、非常に対象を絞った言語です。また、特定のアーキテクチャではなく仮想マシン(JVMや.NET CLRなど)を対象とする今日の主流言語の数も検討してください。たとえば、C#はILにコンパイルされ、ILはネイティブランタイムエンジンによって解釈されます(より頻繁には、ネイティブ実装にJITされた-ジャストインタイムコンパイル-です)。

DSLが非常に高水準の言語を作成するために使用され、実用的なプログラムを作成するための技術的な経験があまりなくても使用できるという概念については、多くの問題があります。誰かがエンティティとインタラクションを平易な英語に近い形で説明でき、オペレーティング環境が単純なUIの表示から何らかの種類のデータベースへのデータの格納まですべてを処理したかどうかを考えます。これらの操作が抽象化されると、プログラミングがいかに簡単になるかを想像できます。

JetBrains MPS (DSLや言語ジェネレーターを記述するためのツールキットです)など、現在いくつか存在しています。 Microsoftは M言語 (M言語はMで定義されているほど言語が完全だった)で、このスペースに短い進路(そして私が追加する可能性が非常に有望)を持っていました。

この概念の批評家は、プログラマーをプログラム開発の仕事から引き離そうとして失敗した以前の試みを指摘しています。DSLワークベンチとの違い(Fowlerがそれらを呼ぶ)は、ドメインエキスパートが表現するために使用できる概念の体系化に開発者が依然として関与するということです。彼らのドメインのニーズ。 OSや言語のベンダーがプログラミングに使用するツールを作成するのと同じように、DSLを使用してビジネスユーザーにツールを提供します。データとロジックを記述するDSLを想像できますが、開発者はデータを格納および取得し、DSLで表現されたロジックを適用するインタープリターを作成します。

2
Michael Brown

クラスの後の次の抽象化は meta classes です。とても簡単です;)

インスタンスがクラスであるクラス。通常のクラスが特定のオブジェクトの動作を定義するのと同様に、メタクラスは特定のクラスとそのインスタンスの動作を定義します。すべてのオブジェクト指向プログラミング言語がメタクラスをサポートしているわけではありません。そうするものの中で、メタクラスがクラスの動作の特定の側面をオーバーライドできる程度は異なります。各言語には、独自のメタオブジェクトプロトコル、つまりオブジェクト、クラス、メタクラスがどのように相互作用するかを管理する一連のルールがあります...

1
Sebastian Bauer

メタ構造、モジュール、フレームワーク、プラットフォーム、サービスはすべてクラスよりも高レベルの機能グループであると私は主張します。プログラミングシステムの抽象化の私の階層:

  • サービス
  • プラットフォーム、ソリューションスタック
  • フレームワーク
  • モジュール、パッケージ
  • メタ構造:メタクラス、高次関数、ジェネリックス、テンプレート、トレイト、アスペクト、デコレーター
  • オブジェクト、クラス、データ型
  • 関数、プロシージャ、サブルーチン
  • 制御構造
  • コード行

metaclasses高次関数 、および generics のようなメタ構造は、基本クラス、関数、データ型、およびデータインスタンスに抽象化を明確に追加します。特性、アスペクト、デコレータは、コード機能を組み合わせるための新しいメカニズムであり、同様に他のクラスと関数を「加速」します。

事前オブジェクト言語でさえモジュールとパッケージがあったので、それらをクラスの上に置くことは議論の余地があるかもしれません。これらのクラスとメタ構造が含まれているため、上位にランク付けします。

Frameworks は最も複雑な答えです-洗練された高レベルの抽象化を提供するために、複数のクラス、メタ構造、モジュール、関数などを調整します。それでも、フレームワークはプログラミングの領域でほぼ完全に機能しています。

ソリューションスタック またはプラットフォームは、通常、複数のフレームワーク、サブシステム、またはコンポーネントを組み合わせて、複数の問題を解決するための環境にします。

最後に、 services - Web またはネットワークサービスとして展開されることがよくあります。これらは、完全なバンドルとして提供されるアーキテクチャ、フレームワーク、ソリューションスタック、またはアプリケーション機能です。それらの内部はしばしば不透明であり、主に管理者、プログラミング、およびユーザーインターフェイスを公開しています。 PaaS および SaaS は一般的な例です。

さて、いくつかの理由で、この進歩は完全に満足のいくものではないかもしれません。まず、完全に線形または階層的ではないものの、きちんとした線形の進行または階層を作成します。完全に開発者の管理下にない「スタック」やサービスなどのいくつかの抽象化について説明します。また、新しい魔法のピクシーダストはありません。 (ネタバレ: 魔法のピクシーダストはありません

新しい抽象レベルを探すのは間違いだと思います。私が上にリストしたものはすべて、現在ほど有名で人気があったわけではないにせよ、の間存在してきました。そしてその数年の間に、あらゆるレベルのコーディングで可能な抽象化が改善されました。これで、配列だけではなく、汎用の汎用コレクションができました。インデックス範囲だけでなく、コレクションをループします。リスト内包表記とリストフィルターおよびマップ操作があります。多くの言語の関数は、可変数の引数やデフォルト引数を持つことができます。等々。 everyレベルで抽象化を増やしているので、抽象化の全体的なレベルを上げるためにレベルを追加する必要はありません。

1
Jonathan Eunice

カテゴリー理論について誰も言及していないことに驚いています。

プログラミングの最も基本的な単位は、型に基づく関数です。関数は通常f:A-> Bとして表されます。ここで、AとBはタイプです。私がタイプや関数と呼んでいるこれらのものを正しい方法で組み合わせると、カテゴリと呼ばれるものが得られます。この時点で停止する必要はありません。

これらのもの、カテゴリを取り、それらを相互に関連付けるための正しい方法は何かを自問してください。正しく行うと、2つのカテゴリの間を行き来し、通常はF:C-> Bと表されるファンクタと呼ばれるものが得られます。ここでも、停止する必要はありません。

あなたはすべてのファンクターを取り、正しい方法でそれらを組み立てることができます、そしてあなたがちょうどいいことをするならば、あなたは2つのファンクターをお互いにどのように関連付けるか疑問に始めます。この時点で、自然変形と呼ばれるもの、mu:F-> Gが得られます。FとGはファンクタです。

この時点での私の知識は曖昧になりますが、これを続けて抽象化のはしごを登り続けることができます。オブジェクトやクラスは、抽象化のはしごをどれだけ高く登ることができるかを説明することすらできません。上記の概念を計算で表現できる言語はたくさんありますが、これらの言語の中で最も目立つのはHaskellです。だから、抽象化について本当に知りたいのであれば、Haskell、Agda、HOL、MLを学んでください。

1
davidk01

俳優のモデルは候補者のリストから欠落していると思います。

ここに私が俳優によって意味するものがあります:

  • 独立したエンティティ
  • メッセージを受信し、メッセージを受信すると、
  • 新しい俳優を作成し、
  • 次のメッセージのためにいくつかの内部状態を更新し、
  • メッセージを送信する

このモデルは、確定的なチューリングマシンを超えたものであり、並行プログラムを見ると、実際には実際のハードウェアに近いものです。余分な(コストのかかる)同期手順を採用しない限り、最近では、コードがデータを受信したときに、同じコアの反対側でも、おそらく同じコア内でもその値が変更されている可能性があります。

短いディスカッション/紹介: http://youtube.com/watch?v=7erJ1DV_Tlo

新しい形の抽象化により、低レベルの作業が見えなくなります。名前付きのプロシージャと関数は、プログラムアドレスを非表示にします。オブジェクトは、動的メモリ管理と一部のタイプに依存する「ifステートメント」を隠します。

低レベルの煩わしさをあなたから隠す次のレベルの実用的な抽象化は、関数型反応型プログラミングのものであると私は提案します。 http://Elm-lang.org/ のような「シグナル」を見てください。これにより、JavaScriptで明示的に管理する必要があるコールバックと更新の依存関係が非表示になります。 FRPは、大規模なインターネットアプリケーションや高性能並列処理でも必要とされるプロセス間およびマシン間通信の複雑さの多くを隠すことができます。

これが今後5年間で私たち全員がワクワクすることになると確信しています。

0
interstar

セット理論-リレーショナルデータベースで部分的に実装されているだけでなく、SASおよびRのような統計言語でも実装されているように、オブジェクト指向とは異なりますが、間違いなくより高いレベルの抽象化を提供します。

0
James Anderson

私があなたを正しく理解していれば、「昇順の抽象化」は、主にコードの再利用に関連する、ますます大きくなるロジックのカプセル化と考えることができます。

特定のinstructionsから次々に実行されるfunctions/subroutinesに移動します。これは、命令の論理グループを単一の要素にカプセル化または抽象化します。次にobjectsまたはmodulesを使用して、特定の論理エンティティまたはカテゴリに関連するサブルーチンをカプセル化し、Stringクラスの下ですべての文字列操作をグループ化できるようにします、またはMathモジュール(またはC#などの言語の静的クラス)の下のすべての一般的な数学演算.

それが私たちの進歩だとしたら、次に何が起こるでしょうか?まあ、私はあなたが明確な次のステップを持っているとは思いません。他の人が答えたように、あなたの進歩は命令型/手続き型プログラミングスタイルにのみ適用され、他のパラダイムは抽象化の概念を共有しません。しかし、私があなたの比喩を論理的に拡張できる何かがあるなら、それはservicesです。

サービスは、機能を公開するエンティティであるという意味でクラスに似ていますが、インスタンス化したオブジェクトとのやり取りよりも、懸念事項の分離がはるかに厳密であることを意味します。これらは限られた一連の操作を公開し、内部ロジックを非表示にし、必ずしも同じマシン上で実行されているわけではありません。

繰り返しになりますが、細かい違いがあります。ほとんどの場合、objectを使用します。これはserviceのプロキシとして機能し、2つは非常に似ていますが、アーキテクチャとして2つは異なります。