プログラミング言語は最初は連続して実行されるコード行のみを使用し、抽象化の最初のレベルの1つである関数を含めるように進化したため、さらに抽象化するクラスとオブジェクトが作成されました。次の抽象化レベルは何ですか?
クラスよりもさらに抽象的なものはありますか?
プログラミング言語は最初は連続して実行されるコード行のみを使用し、抽象化の最初のレベルの1つである関数を含めるように進化したため、さらに抽象化するクラスとオブジェクトが作成されました。次の抽象化レベルは何ですか?
クラスよりもさらに抽象的なものはありますか?
回答:
コンピューティングの歴史について誤解があると思います。
最初の抽象化(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つ以外にも、単なるバリエーションやそれらの組み合わせではない別の抽象化があるとは確信していません。
しかし、抽象化は、本質的に、アルゴリズムをモデル化して記述するための単なる方法です。アルゴリズムは、一連の個別のステップ、従わなければならないルールのセット、数学関数のセット、または相互作用するオブジェクトとして記述することができます。アルゴリズムを記述またはモデル化する他の方法を思い付くのは非常に難しく、たとえあったとしても、その有用性を確信していません。
ただし、量子コンピューティングモデルがあります。量子コンピューティングでは、量子アルゴリズムをモデル化するために新しい抽象化が必要です。この分野の初心者なので、コメントすることはできません。
多くの場合、バイナリプログラミングの現在の時代におけるコードの抽象化の最も純粋な形式は、「高階関数」です。基本的に、関数自体はデータとして扱われ、関数の関数は、オペランドの結果を定義する演算子とこれらの演算の「入れ子」を定義する所定の順序の数学方程式で見るように定義されます。Mathの構造には、「命令型コマンド」がほとんどありません。私が考えることができる2つの例は、「xに何らかの値を持たせるか、何らかの制約に適合する値にする」と、入力が出力を生成するために必要な式を決定する「ピース単位の関数」です。これらの構造は、独自の関数として簡単に表現できます。「関数」xは常に1を返し、「オーバーロード」(オブジェクト指向のオーバーロードとは異なり、値の入力に基づいて定義できる)関数に渡されるものによって定義され、関数の名前付きグループの「ピース単位」評価が可能になります。そのため、プログラムは低レベルでの命令の概念を廃止し、代わりに入力データが与えられた場合の「自身の評価」に焦点を合わせます。
これらの高階関数は、「関数型言語」のバックボーンを形成します。プログラムが行うことは、「純粋な関数」(1つ以上の入力、1つ以上の出力、副作用なし、または「隠された状態」)の観点から定義され、互いにネストされ、必要に応じて評価されます。そのような場合、ほとんどの「命令型ロジック」は抽象化されます。ランタイムは、関数の実際の呼び出し、および関数のいずれかのオーバーロードを呼び出す必要がある可能性のある条件を処理します。そのようなプログラムでは、コードは「何かをする」とは考えられず、「何かをする」と考えられ、最初の入力を与えられてプログラムが実行されると正確に何が決定されます。
高階関数は現在、多くの命令型言語の主要要素でもあります。.NETのラムダステートメントは、基本的に別の「関数」への「匿名」機能入力を可能にします(命令的に実装されますが、理論的にはそうである必要はありません)。望ましい結果。
プログラミング言語の最新のラウンドで一般的に見られる別の抽象化は、「アヒル型」の概念に基づく動的変数型です。それがアヒルのように見え、アヒルのように泳ぎ、アヒルのように飛び、アヒルのように鳴くなら、あなたはそれをアヒルと呼ぶことができます。それが実際にマガモであるかキャンバスバックであるかは関係ありません。それが実際にガチョウまたは白鳥であるかどうかは重要かもしれませんが、それでもあなたが気にするのはそれが泳いで飛ぶことであり、ちょっとカモのように見えるかどうかは問題ではないかもしれません。これは、オブジェクトの継承の究極のものと見なされます。名前を付けない限り、それが何であるかは気にしません。何より重要なのは、それが何であるかありません。このような言語では、基本的に2つのタイプしかありません。「アトム」、情報の単一要素(1つの「値」、数字、文字、関数など)、およびタプル内の他のすべてへの「ポインター」で構成される「タプル」。これらの型がランタイムによってバイナリでどのように実装されるかはまったく関係ありません。これらを使用すると、単純な値型から文字列、コレクションまで、考えられるほぼすべての型の機能を実現できます(値は異なる「型」であるため、「複雑な型」または「オブジェクト」を可能にします)。
SQLのようなドメイン固有言語は、より高い抽象化の順序と考えることができます。SQLは、ストレージなどの操作を抽象化し、集合論に基づいた高レベルの機能を提供する、非常にターゲットを絞った言語です。また、現在特定のアーキテクチャではなく、仮想マシン(JVMや.NET CLRなど)をターゲットにしている主流言語の数を検討してください。たとえば、C#はILにコンパイルされます。ILは、ネイティブランタイムエンジンによって解釈される(またはより頻繁にネイティブ実装にJIT変換される-ジャストインタイムコンパイルされる)。
DSLが非常に高レベルの言語を作成するために使用され、実用的なプログラムを作成するために多くの技術的経験がなくても使用できるという概念については、多くの騒ぎがありました。誰かがエンティティと相互作用を平易な英語に近い形で説明でき、オペレーティング環境がシンプルなUIの表示から、何らかのデータベースへのデータの保存まで、すべてを処理したと考えてください。これらの操作が抽象化されると、プログラミングがどれだけ楽になるか想像できます。
JetBrains MPS(DSLを記述するためのツールキットまたは言語ジェネレーター)など、今日存在するものがいくつかあります。Microsoftは、M言語(このM言語は非常に完全であるため、この言語はMで定義されていました)を使用して、このスペースに簡単に進出しました(そして、非常に有望です)。
コンセプトの批評家は、プログラムを開発する仕事からプログラマーを排除するための以前の失敗した試みを指摘します、DSLワークベンチとの違いは(ファウラーがそれらを呼ぶように)、開発者はまだドメインエキスパートが表現するために使用できる概念を体系化することに関与しているということですドメインのニーズ。OSおよび言語ベンダーがプログラミングに使用するツールを作成するように、DSLを使用してビジネスユーザーにツールを提供します。開発者はデータとロジックを記述するDSLを想像できますが、開発者はデータを保存および取得し、DSLで表現されたロジックを適用するインタープリターを作成します。
メタ構造、モジュール、フレームワーク、プラットフォーム、およびサービスはすべて、クラスよりも高いレベルの機能グループであると主張します。プログラミングシステムの抽象化の私の階層:
メタクラス、高階関数、 ジェネリックなどのメタ構造は、 基本クラス、関数、データ型、データインスタンスに抽象化を明確に追加します。特性、アスペクト、およびデコレーターは、コード機能を結合するための新しいメカニズムであり、同様に他のクラスおよび関数を「加速」します。
事前オブジェクト言語にもモジュールとパッケージがあったため、それらをクラスの上に置くことは議論の余地があるかもしれません。Buにはそれらのクラスとメタ構造が含まれているので、それらを上位にランク付けします。
フレームワークは最も精巧な答えです。洗練された高レベルの抽象化を提供するために、複数のクラス、メタ構造、モジュール、関数などを調整します。それでも、フレームワークは、プログラミングの領域でほぼ完全に動作します。
ソリューションスタックまたはプラットフォームは通常、複数のフレームワーク、サブシステム、またはコンポーネントを組み合わせて、複数の問題を解決するための環境にします。
最後に、多くの場合、Webサービスまたはネットワークサービスとして展開されるサービスがあります。これらは、完全なバンドルとして提供されるアーキテクチャ、フレームワーク、ソリューションスタック、またはアプリケーション機能です。多くの場合、内部は不透明で、主に管理者、プログラミング、およびユーザーインターフェイスを公開します。PaaSとSaaSは一般的な例です。
さて、この進行は、いくつかの理由で完全に満足できるものではないかもしれません。まず、完全に線形または階層ではないもののきちんとした線形の進行または階層を作成します。開発者が完全に制御できるわけではない「スタック」やサービスなどの抽象化についても説明します。そして、それは新しい魔法の妖精の塵を置きません。(ネタバレ:魔法の妖精の塵はありません。)
新しい抽象化レベルだけを探すのは間違いだと思います。上に挙げたものはすべて、今ほど目立つものでも人気があるものでも、何年も存在しています。そして、これらの年月の間、あらゆるレベルのコーディングで可能な抽象化が改善されました。配列だけでなく、汎用の汎用コレクションができました。インデックス範囲だけでなく、コレクションをループします。リスト内包表記とリストフィルターおよびマップ操作があります。多くの言語の関数は、可変数の引数やデフォルト引数を持つことができます。等々。すべてのレベルで抽象化を増やしているため、レベルを追加することは抽象化の全体的なレベルを高めるための要件ではありません。
クラスの次の抽象化はメタクラスです。それはとても簡単です;)
インスタンスがクラスであるクラス。通常のクラスが特定のオブジェクトの動作を定義するように、メタクラスは特定のクラスとそのインスタンスの動作を定義します。すべてのオブジェクト指向プログラミング言語がメタクラスをサポートしているわけではありません。それらの中で、メタクラスがクラス動作の特定の側面をオーバーライドできる範囲は異なります。各言語には、独自のメタオブジェクトプロトコル、オブジェクト、クラス、およびメタクラスの相互作用を制御するルールのセットがあります...
Type
リフレクション機能を提供しますが、ミューテーションを提供しないC#です(CLOSでできることをMyType
言っtypeof(MyType).Methods += new Method ( "Foo", (int x)=>x*x )
て新しいメソッドを追加することはできません)
カテゴリ理論について誰も言及していないことに驚いています。
プログラミングの最も基本的な単位は、型に基づいた関数です。通常、関数はf:A-> Bで示されます。AとBは型です。私がタイプや関数と呼んでいるこれらのものを正しい方法でまとめると、カテゴリーと呼ばれるものが得られます。この時点で停止する必要はありません。
これらのもの、カテゴリーを取り、それらを互いに関連付ける正しい方法は何であるかを自問してください。正しく実行すると、ファンクターと呼ばれるものが得られます。ファンクターは2つのカテゴリにまたがり、通常はF:C-> Bと表示されます。もう一度停止する必要はありません。
すべてのファンクターを取り、それらを正しい方法で組み立てることができます。もしあなたが適切なことをすれば、2つのファンクターを互いに関連付ける方法を疑問に思い始めます。この時点で、自然変換と呼ばれるmuが得られます。F-> Gです。ここで、FとGはファンクターです。
この時点での私の知識は曖昧になりますが、これを続けて抽象化のはしごを登り続けることができます。オブジェクトやクラスは、抽象化のはしごをどれだけ高く登れるかを説明することすらできません。上記の概念を計算で表現できる言語は数多くありますが、これらの言語の中で最も顕著なのはHaskellです。したがって、抽象化が実際に何であるかを本当に知りたい場合は、Haskell、Agda、HOL、またはMLを学んでください。
候補者のリストに俳優モデルが欠けていると思います。
アクターの意味は次のとおりです。
このモデルは、決定論的なチューリングマシンを超えたものであり、同時実行プログラムを見ると、実際には実際のハードウェアにより近くなっています。余分な(コストのかかる)同期手順を使用しない限り、最近ではコードがデータを受信するときに、同じダイの反対側(おそらく同じコア内)でその値が既に変更されている場合があります。
短いディスカッション/紹介:http : //youtube.com/watch?v=7erJ1DV_Tlo
私があなたを正しく理解していれば、あなたの「上昇する抽象化」は、主にコードの再利用に関連する、ますます大きなロジックのカプセル化と考えることができます。
次々に実行される特定の命令から、関数/サブルーチンに移動します。これらは、命令の論理グループを単一の要素にカプセル化または抽象化します。次に、特定の論理エンティティまたはカテゴリに関連するサブルーチンをカプセル化するオブジェクトまたはモジュールがあります。そのため、String
クラスの下のすべての文字列操作、またはMath
モジュール(またはC#などの言語の静的クラス)の下のすべての一般的な数学操作をグループ化できます。
それが私たちの進行である場合、次に何が来るのでしょうか?まあ、私はあなたが明確な次のステップを持っているとは思わない。他の人が答えたように、あなたの進歩は命令型/手続き型プログラミングスタイルにのみ適用され、他のパラダイムは抽象化の概念を共有しません。しかし、私があなたの比phorを論理的に拡張できるものがあれば、それはサービスです。
サービスは、機能を公開するエンティティであるという意味でクラスに似ていますが、自分でインスタンス化したオブジェクトとのやり取りよりもはるかに厳密な懸念の分離を意味します。それらは限られた操作セットを公開し、内部ロジックを隠し、必ずしも同じマシン上で実行されるとは限りません。
繰り返しますが、細かい区別があります。ほとんどの場合、サービスのプロキシとして機能するオブジェクトを使用します。2つは非常に似ていますが、アーキテクチャとしては2つは異なります。
新しい形式の抽象化により、低レベルの作業が隠されます。名前付きプロシージャと関数は、プログラムアドレスを隠します。オブジェクトは、動的メモリ管理と一部のタイプに依存する「ifステートメント」を隠します。
低レベルの骨の折れる作業をあなたから隠す実用的な抽象化の次のレベルは、関数型リアクティブプログラミングのものであることをお勧めします。http://elm-lang.org/のような「シグナル」を見てください。コールバックを隠し、javascriptで明示的に管理する必要がある依存関係を更新します。FRPは、大規模なインターネットアプリケーションや高性能並列処理にも必要なプロセス間通信やマシン間通信の多くの複雑さを隠すことができます。
これが今後5年ほどで私たち全員が興奮することになると確信しています。
集合理論-リレーショナルデータベースに部分的に実装されていますが、SASやRのような統計言語にも実装されているため、オブジェクト指向とは異なる、ほぼ間違いなく高い抽象化レベルを提供します。