連結言語に関するウィキペディアの記事を読みましたが、始めたときよりも混乱しています。:-)
愚かな人々の用語での連結言語とは何ですか?
連結言語に関するウィキペディアの記事を読みましたが、始めたときよりも混乱しています。:-)
愚かな人々の用語での連結言語とは何ですか?
通常のプログラミング言語では、自由に定義できる変数があり、これらの変数を引数として使用してメソッドを呼び出します。これらは理解するのは簡単ですが、いくらか制限されています。多くの場合、既存の変数をメソッドに必要なパラメーターにマップできないか、メソッドAが別のメソッドBを呼び出し、Bの呼び出しを置き換えることができれば、Aが最適であるため、既存のメソッドを再利用するのは困難です。 Cへの呼び出しで。
連結言語は、固定データ構造を使用して値(通常はスタックまたはリスト)を保存します。変数はありません。これは、多くのメソッドと関数が同じ「API」を持っていることを意味します。それらは、他の誰かがスタックに残したものに対して機能します。さらに、コード自体は「データ」と見なされます。つまり、コード自体を変更できるコード、または他のコードを「パラメーター」として(つまりスタック上の要素として)受け入れるコードを作成するのが一般的です。
これらの属性により、この言語は既存のコードをチェーンして新しいものを作成するのに最適です。再利用が組み込まれています。リストとコードの一部を受け取り、リスト内の各項目のコードを呼び出す関数を記述できます。これは、データベースからの結果、画像からのピクセルの行、文字列内の文字など、リストのように動作する限り、あらゆる種類のデータで機能するようになりました。
最大の問題は、何が起こっているのかヒントがないことです。データ型(リスト、文字列、数値)は2つしかないため、すべてがそれにマップされます。データを取得するときは、通常、それが何であるか、どこから来ているかは気にしません。ただし、コードを介してデータを追跡し、コードに何が起こっているかを確認することは困難です。
言語を上手く使うには、ある程度の心構えが必要だと思います。彼らは皆のためではありません。
[編集]フォースにはある程度の浸透がありますが、それほどではありません。PostScriptは、最新のレーザープリンターで見つけることができます。つまり、それらはニッチな言語です。
機能レベルからは、LISP、Cのような言語、SQLと同等です。これらはすべてチューリング完全であるため、何でも計算できます。それはあなたが書かなければならないコードの量の問題です。LISPでより単純なもの、Cでより単純なもの、クエリ言語でより単純なものがあります。「より良い」という質問は、文脈がない限り無駄です。
まず、理論がないというノーマン・ラムゼーの主張に反論します。
連結言語の理論
連結言語は関数型プログラミング言語であり、デフォルトの操作(2つの用語が並んでいる場合に発生する操作)は、関数適用ではなく関数合成です。それはそれと同じくらい簡単です。
したがって、たとえばSKIコンビネータ計算(最も単純な関数型言語の1つ)では、2つの用語を並べて使用することは、最初の用語を2番目の用語に適用することと同じです。例:S K K
はと同等S(K)(K)
です。
連結言語では、HaskellS K K
と同等です。S . K . K
だから大したことは何ですか
純粋な連結言語には、用語の評価の順序が重要ではないという興味深い特性があります。連結言語(S K) K
では、と同じS (K K)
です。これは、SKICalculusまたは関数型アプリケーションに基づくその他の関数型プログラミング言語には適用されません。
この観察が興味深い理由の1つは、アプリケーションではなく関数構成の観点から表現されたコードの評価における並列化の機会を明らかにするためです。
今、現実の世界のために
高階関数をサポートするスタックベースの言語のセマンティクスは、連結微積分を使用して説明できます。各用語(コマンド/式/サブプログラム)を、関数を入力として受け取り、関数を出力として返す関数にマップするだけです。プログラム全体は、事実上、単一のスタック変換関数です。
現実には、現実の世界では物事が常に歪んでいます(たとえば、FORTHにはグローバル辞書があり、PostScriptは評価順序が重要な場合に奇妙なことを行います)。ほとんどの実用的なプログラミング言語は、理論モデルに完全には準拠していません。
最後の言葉
典型的なプログラマーや8歳の人は、連結言語が何であるかを心配する必要はないと思います。また、タイプXまたはタイプYであるため、鳩の穴のプログラミング言語には特に有用ではありません。
http://concatenative.org/wiki/view/Concatenative%20languageを読み、10代の頃にForthをいじったことをほとんど覚えていないことを参考にした後、連結プログラミングの重要な点は次のことと関係があると思います。
上記のウェブページからこれらの引用をチェックしてください:
よく使われる用語には、スタック言語と連結言語の2つがあります。どちらも類似しているが等しくないクラスの言語を定義しています。ただし、ほとんどの場合、それらは同一です。
今日広く使用されているほとんどの言語は適用可能な言語です。言語の中心的な構成は、関数が一連のパラメーターに適用される何らかの形式の関数呼び出しであり、各パラメーター自体が関数呼び出しの結果であり、変数、または定数。スタック言語では、関数の名前を記述するだけで関数呼び出しが行われます。パラメータは暗黙的であり、呼び出しが行われるときにすでにスタック上にある必要があります。関数呼び出しの結果(存在する場合)は、関数が戻った後、次の関数が消費するために、スタックに残されます。関数は、追加の構文なしで名前を指定するだけで呼び出されるため、ForthとFactorは関数を「単語」と呼びます。これは、構文では実際には単なる単語であるためです。
これは、関数を特定の変数に直接適用するアプリケーション言語とは対照的です。
例:2つの数値を追加します。
適用言語:
int foo(int a, int b)
{
return a + b;
}
var c = 4;
var d = 3;
var g = foo(c,d);
連結言語(私はそれを作りました、Forthに似ているはずです...;))
push 4
push 3
+
pop
連結言語=スタック言語とは思いませんが、著者が上で指摘したように、それは似ているようです。
主なアイデアは1だと思います。他のプログラムを結合するだけで新しいプログラムを作成できます。
また、2。プログラムのランダムなチャンクは、有効な関数(またはサブプログラム)です。
古き良き純粋なRPNForthには、ランダムな非RPN構文を除いて、これらのプロパティがあります。
プログラム12+ 3 *では、サブプログラム+ 3 *は2つの引数を取り、1つの結果を返します。サブプログラム2は0個の引数を取り、1個の結果を返します。どのチャンクも関数であり、それは素晴らしいことです。
オプションで少量の接着剤を使用して、2つ以上の他の関数をひとまとめにすることで、新しい関数を作成できます。タイプが一致する場合に最適に機能します。
これらのアイデアは本当に良いです、私たちはシンプルさを大切にしています。
これは、RPN Forthスタイルのシリアル言語や、命令型または関数型プログラミングに限定されません。この2つのアイデアは、プログラムユニットが関数、プロシージャ、リレーション、プロセスなどのグラフィカル言語でも機能します。
通信するプロセスのネットワークでは、すべてのサブネットワークがプロセスのように機能します。
数学的関係のグラフでは、すべてのサブグラフが有効な関係です。
これらの構造は「連結」であり、任意の方法で分解し(円を描く)、さまざまな方法で結合する(線を引く)ことができます。
まあ、それは私がそれを見る方法です。私は、連結キャンプから他の多くの良いアイデアを逃したと確信しています。私はグラフィカルプログラミングに熱心ですが、この連結に焦点を当てるのは初めてです。
連結プログラミングの私の実用的な(そして主観的な)定義(これで、残りの部分を読むのを避けることができます):
->極端な方法での関数合成(逆ポーランド記法(RPN)構文を使用):
( Forth code )
: fib
dup 2 <= if
drop 1
else
dup 1 - recurse
swap 2 - recurse +
then ;
->すべてが関数であるか、少なくとも関数である可能性があります。
( Forth code )
: 1 1 ; \ define a function 1 to push the literal number 1 on stack
->引数は関数を介して暗黙的に渡されます(わかりました、それは暗黙のプログラミングの定義のようです)が、これはForthで:
a b c
Lispにあるかもしれません:
(c a b)
(c (b a))
(c (b (a)))
したがって、あいまいなコードを生成するのは簡単です...スタックにxt(実行トークン)をプッシュする定義を記述し、「execute」の小さなエイリアスを定義できます。
( Forth code )
: <- execute ; \ apply function
だから、あなたは得るでしょう:
a b c <- \ Lisp: (c a b)
a b <- c <- \ Lisp: (c (b a))
a <- b <- c <- \ Lisp: (c (b (a)))
言語を説明することはできません。言語を1つ(できればFactor )取得して、その言語でいくつかのチュートリアルを試してください。チュートリアルは、StackOverflowの回答よりも優れています。
あなたの簡単な質問に対して、ここに主観的で議論の余地のある答えがあります。
私は記事といくつかの関連するウェブページを見ました。ウェブページには本当の理論はないと書かれているので、人々が正確で理解しやすい定義を思いつくのに苦労しているのも不思議ではありません。現時点では、言語を「連結」または「非連結」に分類することは有用ではないと思います。
私には、 Manfred von Thunに帽子をかぶる場所を与える用語のように見えますが、他のプログラマーには役に立たないかもしれません。
PostScriptとForthは勉強する価値がありますが、ManfredvonThunのJoyプログラミング言語でひどく新しいものや興味深いものは見当たりません。確かに、 Haskellに接尾辞言語を埋め込むためのテクニックに関するChris Okasakiの論文を読んだら、Joyと比較して完全に主流の設定でこれらすべてを試すことができます。
ですから、私の答えは、連結言語の概念の根底にある成熟した理論がないため、簡単な説明はありません。(アインシュタインとファインマンが言ったように、大学の新入生にあなたの考えを説明できない場合、あなたはそれを本当に理解していません。)ForthやPostScriptのようなこれらの言語のいくつかを勉強することは、優れた時間の使い方、「連結」と言ったときに人々が何を意味するのかを正確に理解しようとすることは、おそらくあなたの時間の無駄です。