プログラミング言語の1番目、2番目、3番目のクラス値の数学の基礎は何ですか?


19

追加しました

関連する2つの質問を見つけた

/math//q/1759680/1281

/programming//a/2582804/156458


プログラミング言語では、Michael ScottのProgramming Language Pragmaticsから

一般に、プログラミング言語の値は、パラメータとして渡されたり、サブルーチンから返されたり、変数に割り当てられたりする場合、ファーストクラスのステータスを持つと言われ ます。整数や文字などの単純な型は、ほとんどのプログラミング言語で最高の値です。対照的に、「セカンドクラス」値はパラメーターとして渡すことができますが、サブルーチンから返されたり変数に割り当てられたりすることはできません。また、「サードクラス」値はパラメーターとして渡すことさえできません。

ラベルは、ほとんどのプログラミング言語では第3クラスの値ですが、Algolでは第2クラスの値です。サブルーチンは最も多くのバリエーションを表示します。これらは、すべての関数型プログラミング言語およびほとんどのスクリプト言語で最も優れた値です。また、C#での最高クラスの値であり、Fortran、Modula-2および-3、Ada 95、C、C ++など、いくつかの他の必須言語では、いくつかの制限があります。11これらは、他のほとんどの命令型言語では第2クラスの値であり、Ada 83では第3クラスの値です。

  1. プログラミング言語の1番目、2番目、3番目のクラス値の数学の基礎は何ですか?

    用語は一次/二次のロジックを思い出させますが、それらは関連していますか?

  2. それらの違いは、値を使用できる特定のケースであるように思えます

    • パラメータとして渡され、
    • サブルーチンから返された、または
    • 変数に割り当てられます。

    なぜ特定のケースが重要なのに、他のケースは言及されていないのですか?

ありがとう。


23
値をファースト/セカンドクラスに分類することは、言語をパラダイムに分類するのと同じくらい無益です。最終的には、あいまいな一般化が画像を混乱させます。これは、プログラミング言語を理解するための正しいアプローチではありません。重要なのは、言語の構文、静的、および動的を理解することですが、コメントに入れるには大きすぎます
-Gardenhead

3
余談:PL / Iはファーストクラスとしてのラベルの例です。PL / Iでは、ラベル付けするように入力された変数を宣言し、コードの場所を割り当てて、それらに移動できます。また、それらをパラメーターとして渡し、それらの配列を作成することもできます。
Theraot

@Theraot:おそらく私は自分と付き合っていますが、FORTRANで割り当てられ計算されたGOTOを処理する必要があったのは私だけですか?いいえ、@ $%は書きませんでした!コード、私はそれをリエンジニアリングで立ち往生しました。
jamesqf

@jamesqf FORTRANとCOBOLでラベルに割り当てることを知っています。いいえ、使用していません。そこでラベルを分類する方法がわかりません。しかし、私が読んだもの(マニュアルを持っています)については、PL / Iはそれを超えており、ラベルはそこにあると確信しています。
Theraot

回答:


45

何もありません、そしてそれはかなりarbitrary意的です。

唯一の便利な違いは、ファーストクラスとその他すべてです。「その他」の括弧内にあるすべてのケースには、それぞれ独自のルールセットがあり、それらをまとめてまとめることはあまり役に立ちません。「ファーストクラス」とは「ルールを調べる必要がない」ことを意味し、「その他」とは「ルールを学ぶ必要がある」ことです。

たとえば、C ++では、ステートレスである限り、個々の関数はファーストクラスの値です。オーバーロードセットはそうではありませんが、ラムダはそうです。C#の関数は一般に一流の値ですが、型推論を処理するときにすべての場合に機能を妨げる厄介なケースがいくつかあります。


10
+1、ただし、プログラミング言語語彙のような本の文脈では、多数の言語の多数の構成体を比較し、類似点、相違点、および含意を詳細に分析しますが、この種の速記は役立つと思います。(他の人が「セカンドハンド」と「サードハンド」を特定のことを意味するものとして理解することを期待しないでください。)
ruakh

(ええと、「セカンドハンド」と「サードハンド」とは、もちろん「セカンドクラス」と「サードクラス」を意味します。:
P

3
中古の機能と取引したい場合は、機能が第一級の市民である言語でそれを行うことをお勧めします。^^
5gon12eder

@ 5gon12eder:「セカンドハンド関数」は、サードパーティのライブラリから呼び出すものでしょうか?
jamesqf

11

私はDeadMGに同意します。重要な違いは、ファーストクラスと「その他すべて」です。ただし、違いを分類するより馴染みのある方法があります。

一流の値はデータであり、その他はコードです。(大まかに言って、例外はあると確信しています。しかし、これは実際の言語に当てはまる本当に良い近似です。)

一部の言語では、コードをデータとして扱うことができます。関数型言語はこれで有名です。それらのいくつかは、実行中にプログラムのコードを変更できるようにします(遺伝的プログラミングの基礎)。

CやC ++などの言語を使用すると、関数のアドレスを取得できます。変更することはできませんが、関数をパラメーターとして他の関数に渡すことができます。C ++には、ファンクターの構文糖衣もあります。そこにある考えは、表面上では関数のように振る舞い、データのように受け渡しできるオブジェクト全体を作成することです。それ以外の場合、より低いクラスの値はファーストクラスの値として扱うことができます。

数学的には、プログラムのASTを考えることが最善の方法だと思います。通常、各トークンには特定のタイプがあり、他のタイプと互換性がある場合と互換性がない場合があります。C ++では、l値、r値、およびその他の値型の混乱を考えてください。次に、キーワード、関数であるシンボルなどを追加します。これらの一部は、言語に応じて、1番目、2番目、または3番目のクラス値になる場合があります。

学術的な環境を除いて、価値の「クラス」がどれほど重要であるかはわかりません。現実の世界で知っておくべき重要なことは、データをファンクタ、ラムダ/クロージャ、関数ポインタなどのように扱い、コードを渡す方法です。


2
非コードの非ファーストクラス値の例:Luaには、...可変引数関数パラメーターを示すために使用される特別な「変数」があります。値リスト(print(...)orなどlocal args = {...})のように多くの式で使用できますが、クロージャ(function(...) return function() return ... end end)で参照するなど、使用できないことがあります。
大佐32

8

Denotational Semanticsは、プログラミング言語で値と変数がどのように機能するかを記述するための数学的な基礎を提供します。Computer Sci Degreeで非常によく説明されていたので、Denotational Semantics試験で最高点を獲得しましたが、ほとんど忘れてしまい、20年間プログラマーとしてそれを使用する必要はありませんでした。

明確に定義された数学的な基盤を使用することも、「ファーストクラスのステータス」などの非公式の用語を使用することもできます。コースがスコットのプログラミング言語プラグマティクスに基づいていれば、もっと多くを学びましたが、プログラミング言語の設計でPHdを行う人には正式な数学が必要です。

ほとんどのプログラミング言語の仕様を読めば、デノテーショナルセマンティクスの反対に欠けていることに気付くでしょう。しかし、最もうまく設計された言語には、プログラミング言語デザインの専門家であるチームの誰かがいたため、デノテーショナルセマンティクスをよく理解しています。

そのため、Michearl Scottは形式的な数学と何らかの関係がある非公式の用語を使用し、ほとんどのプログラマーが恩恵を受けることができる方法で主題を提示します。 彼の用語は他の人には使用されていないため、コミュニケーションには役立ちませんが、新しいプログラミング言語を初めて見るときに尋ねるべき質問の良い基礎となります。

Michael L. ScottはComputer Sciの主要な研究者であるため、公式の数学を理解して非常に満足していますが、最高の研究者のように、研究の応用を他の人に説明するスキルがあります。


ありがとう。どの本がクラスで使用されましたか?今、どの本をお勧めしますか?私は自己学習者です
ティム

@ティム、20年以上前にクラスをやった!Michearl Scottの本は最高の本の1つであり、PHdレベルの研究を行うつもりでない限り、必要なものより多くの本をカバーできると期待しています。
イアン

3

いいえ、「ファーストクラス」と「ファーストオーダー」の「ファースト」という言葉は、異なることを意味します。

しかし、はい、「ファーストクラス」と「ファーストオーダー」の概念は関連しています。どちらも、言語が説明できる概念を分類し、言語が抽象化できるようにすることです。

言語の通常の抽象化メカニズムがその概念を抽象化できる場合、その概念は一流です。

たとえば、Javaプログラミング言語は整数を記述することができ、整数を抽象化するための通常のメカニズム(メソッドパラメーターとして受け入れ、関数結果として返す、データ構造に格納するなど)はすべて整数に対して機能します。

概念を抽象化するために使用できない場合、その概念は1次です。

たとえば、Javaでも、メソッドを使用して特定のものを抽象化できます。ただし、メソッド名をメソッドパラメーターとして渡すことはできないため、メソッドを使用してメソッドを抽象化することはできません。これはJavaScriptでは異なります。JavaScriptでは、ブラケット表記を使用して、オブジェクトのプロパティに文字列としての名前でアクセスでき、文字列を抽象化できます。

概念は、2次使用ではなく、1次使用自体を抽象化するために使用できる場合は2次です。

たとえば、Javaでは、Genericsを使用して型を抽象化できます(などclass Foo<T> { public List<T> content; })。ただし、ジェネリックを使用してジェネリックを抽象化することはできません(などclass Bar<T> { public T<Int> content; })。これはScalaでは異なります。

概念は、三次、それ自体の上に一次抽象及び二次の用途に使用され、なくオーバー二次使用することができる場合。

等々。

最後に、概念は、それ自体の任意の使用を抽象化するために使用できる場合、高次です

要約:抽象化機能がファーストクラスの場合、それも高次です。また、抽象化機能が1次である場合、それを1次クラスにすることはできません。


1
あなたはできませんList<List>が、Javaで。たぶん、あなたはその部分で何を意味するのかを明確にすることができますか?
ポリノーム

1
いい視点ね。私は意味します:class Foo<A> { A<Int> ... }。つまり、ジェネリック型パラメーターをジェネリッククラスとして使用するということです。次に、Foo<List>をインスタンス化A<Int>List<Int>ます。Javaでは、それは不可能です。後で答えにこれを編集しようとします。
トキサリス

確かに、それは不可能です。
ポリノーム

私は今、誤解を招くList<List>例に取って代わりました。問題を指摘してくれてありがとう、@ Polygnome。
トキサリス

@Toxarisこれはあなたが自分で作った単なる特異な用語だと思います。「概念」は1次または2次ではなく、論理量指定子です。
マイルルーティング

2

プログラミング言語の1番目、2番目、3番目のクラス値の数学の基礎は何ですか?

私が知っていることはありません。

用語は一次/二次のロジックを思い出させますが、それらは関連していますか?

あんまり。

プログラミング言語要素の「クラス」は、私の言語のユーザーがプログラムで操作したいものは何かという質問についての簡単な考え方です。たとえば、C#には、を操作するための豊富な操作セット、を操作するためのそれほど豊富でない方法セットがあり、ラベルを操作する操作はありません。

しかし、ここに接続があるというあなたの直感は完全に見当違いではありません。一次論理から手続き型プログラミングまで、および高次論理から関数型プログラミングまでの類似点があります。一次論理は、値の論理的操作に関するものです。手続き型プログラミングは、プログラムによる値の操作に関するものです。高階述語論理は論理的な操作についてですロジックのステートメント、関数型プログラミングは、プログラムの操作についてです機能

なぜ特定のケースが重要なのに、他のケースは言及されていないのですか?

決定的な答えを著者に尋ねる必要があります。

私はこの「クラス」の概念にこだわることはありません。正式に定義するものではありません。これは、言語設計者がプログラム的にどのようなものを操作できるかについて話すために使用する略記です。


2

この文脈での「一流の価値」は、プログラミング言語理論の標準用語です。ファーストクラスの値は、言語の通常の値として操作できるものであり、実行時に計算できるものです。もちろん、それは言語のセマンティクスを定義するまではトートロジーの定義であり、値はセマンティクスが値として定義するものであれば何でもです。概念のポイントは、間接的にアクセスするだけではなく、直接操作できるものを識別することです。

たとえば、ほとんどすべてのプログラミング言語では、制限されたサイズのマシン整数(8ビット整数、32ビット整数、64ビット整数など)はファーストクラスの値です。それらを変数に保存し、関数に渡すなどすることができます。アセンブリやCなどの低レベル言語ではなく、ほとんどの言語では、文字列は第一級の値です。しかし、Cではそうではありません。文字列へのポインタを取得します。Cでは、文字列と配列は一流の値ではありません。たとえば、関数に配列を渡すことはできません。配列変数に配列を割り当てることはできません。Cでは、関数は一流の値ではありません。どちらか:関数を変数に格納することはできず、関数へのポインターのみを格納できます。対照的に、文字列と関数は、ほとんどの高レベルプログラミング言語のファーストクラスの値です。文字列などに保存できます。

コンパイルするように設計された多くのプログラミング言語で一流ではない概念の例は型です。CやJavaのような言語では、型はコンパイル時に存在し、言語構造を使用して型を操作することはできません。(Javaには、クラスに基づいた動的型システムもあります。クラスはリフレクションによるファーストクラスの値です。)対照的に、Pythonのような言語にtypeは、引数の型を表す値を返す関数があります。

標準的な用語での「ファーストクラスの値」の否定は「ファーストクラスの値ではない」です。「セカンドクラス値」という用語は一般的に使用されず、「サードクラス値」という用語は一般的に使用されません。この本の外でそれらを見ると期待しないでください。「2番目」を「パラメータとして渡すことができる」、「3番目」を「パラメータとして渡すことができない」と定義する根拠はまったくなく、意味のある番号を付けることができるスケールはありません。関数にパラメーターとして渡すことができる値と変数に割り当てることができる値の違いを生じさせる言語はほとんどないため、この概念の名前を定義することは有用ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.