「直交性」という用語は、正確な数学的概念を表す素人の用語です。言語用語は初期代数を形成します(Wikipediaで調べてください)。
それは基本的に「構文と意味の間に1-1の対応がある」ことを意味します。つまり、物事を表現する方法は1つしかなく、特定の場所に表現を置くことができれば、そこに他の表現を置くこともできます。
「直交」について考えるもう1つの方法は、構文が置換の原則に従うことです。たとえば、式のスロットを持つステートメントがある場合、任意の式をそこに置くことができ、結果は依然として構文的に有効なプログラムです。さらに、交換すると
「意味」は計算結果を意味するものではないことを強調したい。明らかに、1 + 2と2 + 1は両方とも3に等しくなります。ただし、項は異なり、同じ結果になっても異なる計算を意味します。2つのソートアルゴリズムが異なるように、意味も異なります。
「抽象構文木」(AST)を聞いたことがあるかもしれません。ここで「抽象的」という言葉は、正確に「直交」を意味します。技術的には、ほとんどのASTは実際には抽象的ではありません。
おそらく「C」プログラミング言語を聞いたことがありますか?C型表記は抽象的ではありません。検討してください:
int f(int);
したがって、ここにtypeを返す関数宣言がありますint
。この関数へのポインターのタイプは、次のように指定されます。
int (*)(int)
関数の型を書くことはできません!Cタイプ表記は、大物を吸います!それは抽象的なものではありません。それは直交していません。ここで、intの代わりに上記の型を受け入れる関数を作成するとします。
int (*) ( int (*)(int) )
すべて大丈夫ですが、代わりにそれを返したい場合はどうしますか。
int (*)(int) (*) (int)
おっと!無効。括弧を追加しましょう:
(int (*)(int)) (*) (int)
おっと!それも機能しません。これを行う必要があります(これが唯一の方法です!):
typedef int (intintfunc*) (int);
intintfunc (*)(int)
これで問題ありませんが、typedefをここで使用する必要があるのはよくありません。Cは吸う。それは抽象的なものではありません。それは直交していません。MLでこれを行う方法は次のとおりです。
int -> (int -> int)
構文レベルでCを非難します。
では、C ++をflogしてみましょう。上記の愚かさをテンプレートで修正して、表記のようなML(多かれ少なかれ)を取得できます。
fun<int, int>
fun< fun<int,int>, int>
しかし、実際の型システムには、参照によって根本的に欠陥があります。T
型である場合T&
、型は何ですか?答えは気まぐれです。構文レベルで、型U = T&がある場合、U&は許可されますが、それはT&を意味するだけです。参照への参照は元の参照です。これは最悪だ!これは、一意性要件を意味的に破ります。さらに悪いことに、T&&は構文的には許可されていません。これは置換の原則に違反します。したがって、C ++リファレンスは、バインディング時間(解析または型分析)に応じて、2つの異なる方法で直交性を壊します。これを正しく行う方法を理解したい場合は、ポインタに問題はありません。
直交する実際の言語はほとんどありません。表現の明快さを装うSchemeでさえそうではありません。ただし、多くの優れた言語は「直交特徴ベースにかなり近い」と判断することができます。これは、構文と基礎となるセマンティクスの両方に適用される言語に適した推奨事項です。