19

私は現在、継続的な環境でプログラミングするための新しい言語を開発しています (電気工学と比較してください)。特定の言語構築についていくつかのアイデアがあります。

機能を説明で説明し、次に定義で説明しましょう。

x = a U b;

ここxで は変数で、abは他の変数 (または静的値) です。aこれはとの間の結合のように機能しbます。重複も特定の順序もありません。

with(x) {
    // regular 'with' usage; using the global interpretation of "x"
    x = 5;
    // effectively will do:
    // x = a U b U 5;
    // a = 5;
    // b = 5;
    // Thus, when "a" or "b" changes, "x" is still equal to "5".
}
with(x = a) {
    // this code block is executed when the "x" variable
    // has the "a" variable assigned. All references in
    // this code-block to "x" are references to "a". So saying:
    x = 5;
    // would only change the variable "a". If the variable "a"
    // later on changes, x still equals to 5, in this fashion:
    // 'x = a U b U 5;'
    // '[currentscope] = 5;'
    // thus, 'a = 5;'
}
with(x = b) {
    // same but with "b"
}
with(x != a) {
    // here the "x" variable refers to any variable
    // but "a"; thus saying
    x = 5;
    // is equal to the rewriting of
    // 'x = a U b U 5;'
    // 'b = 5;' (since it was the scope of this block)
}
with(x = (a U b)) {
    // guaranteed that "x" is 'a U b'; interacting with "x"
    // will interact with both "a" and "b".
    x = 5;
    // makes both "a" and "b" equal to 5; also the "x" variable
    // is updated to contain:
    // 'x = a U b U 5;'
    // '[currentscope] = 5;'
    // 'a U b = 5;'
    // and thus: 'a = 5; b = 5;'.
}
// etc.

上記では、すべてのコードブロックが実行されますが、「スコープ」は各ブロックでどのようxに解釈されるかが変わります。最初のブロックでxは、 であることが保証されていますa: したがって、xそのブロック内での相互作用は で相互作用しaます。2 番目と 3 番目のコード ブロックは、この状況でのみ等しくなります (なぜならnot a: しか残っていないからですb)。x最後のブロックは、少なくともaまたはであることを保証しbます。

さらに; Uは「ビットごとの or 演算子」ではありませんが、「and/or」演算子と呼んでいます。その定義は次のとおりです。

"U" = "and" U "or"

(私のブログhttp://cplang.wordpress.com/2009/12/19/binop-and-or/には、この演算子に関する (数学的な) 背景情報があります。集合に大まかに基づいています。異なる構文を使用すると、この質問で変更しました。)

更新: より多くの例。

print = "Hello world!" U "How are you?"; // this will print
                                         // both values, but the
                                         // order doesn't matter.
// 'userkey' is a variable containing a key.
with(userkey = "a") {
    print = userkey; // will only print "a".
}
with(userkey = ("shift" U "a")) {
    // pressed both "shift" and the "a" key.
    print = userkey; // will "print" shift and "a", even
                     // if the user also pressed "ctrl":
                     // the interpretation of "userkey" is changed,
                     // such that it only contains the matched cases.
}
with((userkey = "shift") U (userkey = "a")) {
    // same as if-statement above this one, showing the distributivity.
}

x = 5 U 6 U 7;
y = x + x; // will be:
// y = (5 U 6 U 7) + (5 U 6 U 7)
//   = 10 U 11 U 12 U 13 U 14

somewantedkey = "ctrl" U "alt" U "space"
with(userkey = somewantedkey) {
    // must match all elements of "somewantedkey"
    // (distributed the Boolean equals operated)
    // thus only executed when all the defined keys are pressed
}
with(somewantedkey = userkey) {
    // matches only one of the provided "somewantedkey"
    // thus when only "space" is pressed, this block is executed.
}

Update2: より多くの例といくつかのコンテキスト。

with(x = (a U b)) {
    // this
}
// can be written as
with((x = a) U (x = b)) {
    // this: changing the variable like
    x = 5;
    // will be rewritten as:
    // a = 5 and b = 5
}

背景情報: Java が「プラットフォームに依存しない」ように、「時間に依存しない」言語を構築しています。言語で述べられていることはすべて「そのまま」であり、継続的にアクティブに実行されます。これの意味は; プログラマーは、要素がどの順序で (構造を使用して明示的に記述されていない限り)、いつステートメントが実行されるかを知りません。言語は「時間」の概念から完全に分離されています。つまり、継続的に実行されます。

with(true) {
    a = 0; // only runs once (lazy execution)
}

with(a < 5) {
    a++;
} // this is a loop-structure;
  // how and when it's executed isn't known however.

with(a) {
    // everytime the "a" variable changes, this code-block is executed.
    with(true) {
        b = 3; // only 5 times (again lazy execution, but it's a sub-with)
    }
    with(b < 2) { // dependent on "b"
        // runs only 3 times * 5 times = 15 times.
    }
    with(b > 1) { // dependent on "b"
        b = b - 1; // runs 4 times * 5 times = 20 times.
    }
}

更新 3:

この言語機能の種類を熟考した後。これは、Netbeans プラットフォームの Lookup によく似ています。ここで、同期されたエージェントの各「with」ステートメントは、オブジェクトの特定の「フィルター」に取り組んでいます。型ベースではなく、変数ベースです (基本的にはまったく同じで、オブジェクトを識別する方法が異なるだけです)。

非常に洞察に満ちた情報と、私が研究できる素晴らしいトピックへのリンク/ヒントを提供してくれた皆さんに心から感謝します. ありがとう。

この構造がすでに存在するかどうかはわかりません。それが私の質問です。この言語機能はすでに存在しますか?

4

10 に答える 10

4

正直なところ、あなたの説明と例を理解するのは難しいと思います(更新:あなたのブログははるかに優れており、Statement Orderingを読んで、データフロープログラミングの形式を目指しているとさらに確信しています)。

ただし、最終的な説明:

言語で述べられていることはすべて「そのまま」であり、継続的にアクティブに実行されます。これの意味は; プログラマーは、要素がどの順序で (構造を使用して明示的に記述されていない限り)、いつステートメントが実行されるかを知りません。この言語は「時間」の概念から完全に分離されています。つまり、言語は継続的に実行されます。たとえば、「a」は「b」であり、「b」は「a」であると言うのは単純なループ構造です。

.. あなたが検索している一般的な用語はデータフロー プログラミングであると思わせてくれます(データフロー プログラミングのより単純なインスタンスではループが許可されていなくても)。ウィキペディアからの引用:

Dataflowは、変数の値を変更すると、その値に依存する変数の値が自動的に再計算されるという考えに基づくソフトウェア アーキテクチャです。

リアクティブプログラミング関数型リアクティブプログラミングは、理解しているように、同じテーマのバリエーションです。

Icon のゴール指向評価は、範囲がより制限されています (このA Brief Introduction to Icon を参照してください:ゴール指向評価メカニズムによって暗示されるバックトラッキングは、それが発生する式に限定されます)。

Stackoverflow: Dataflow Programming Languagesに関するこの質問も参照してください。

更新: Pindatjuh がコメントで質問しています。私はそう思いますが、問題は実際には定義に関するものであり、コンセンサスに関するものです。データフロー言語に関する最近の調査、「データフロー プログラミング言語の進歩」( ACM Computing Surveys、第 36 巻、第 1 号、2004 年 3 月に発行) で、著者は次のように書いています (10 ページ)。

データフロー言語を構成する機能の最良のリストは、Ackerman [1982] によって提唱され、Whiting と Pascoe [1994] および Wail と Abramson [1995] によって繰り返されました。このリストには次のものが含まれます。

  1. 副作用からの自由、
  2. 効果の局所性、
  3. スケジューリングに相当するデータの依存関係
  4. 変数の単一代入、
  5. 機能 1 と 4 による反復の通常とは異なる表記
  6. 手順における履歴の感度の欠如。

私はあなたのブログをすべて読んだわけではありませんが、軽く読んだだけなので、あなたのプログラミング言語について判断するのは私よりもあなたの方が適切です (とにかく、これは移動するターゲットです)。

更新:あなたの質問の「... this language is a new variant on...」の「新しい」という単語を無意識のうちに見逃していました。これは難しい作業です。これまでに発明されたすべてのデータフロー言語を検討し、それらのセマンティクスを詳細に注意深く調べて、アプローチの新規性を見つける必要があります。現時点では、必要な知識が確かにありません。

于 2010-03-25T00:41:53.180 に答える
4

これを理解するのは難しいと思いますが、次のことを意味していますか?

x == a | b 

シンタックス シュガーは次と同等です。

(x == a) || (x == b)

ブログ投稿で、次の例を示します。

1 + (2|3)

したがって、その式の型は、値 3 と 4 を持つ整数のペアであり、それぞれが可能な値の 1 つを表します。したがって、次のようにも言えます。

4 == (1 + (2|3)
3 == (1 + (2|3)

どちらも true と評価されます。したがって、演算子==は値を一種の値のベクトルと比較でき、ベクトルtrue内のいずれかの値が最初の値と等しい場合に比較されます。

これは、いくつかの言語で演算子のオーバーロードを使用して実装できます (ただし、単純な値を操作する前に、単純な値をラッパー型に明示的に「持ち上げる」必要があります)。

2 つのセットの和集合と実質的に同じではなく、== は「のメンバーである」と解釈されますか? そして演算子は + のように持ち上げられるので、セットのすべてのメンバーに適用されます。

そして、(1|2) + (4|8) を実行すると、(5|9|6|10) に相当する結果が得られます。これらは 4 つの可能な結果だからです。

さて、あなたが追加したさらなる例から==、実際には、単に重なり合うのではなく、左側と右側が同じセットである必要があることがわかります。しかし、あなた|は単に2つのセットの結合であるという印象を今でも受けています. これが何を意味するか (または意味するか) は、セットを処理するために言語の他のすべての機能に何をするかによって異なります。

あなたの声明について:

言語は「時間」という概念から完全に切り離されている

Haskell のような純粋関数型言語をよく調べましたか? プログラムは、既知の実行順序のない一連の定義です。副作用のない純粋な関数しか記述できないため、インタープリターは、本当に必要なときに値が利用可能である限り、好きなように実行を順序付けることができます。

アップデート:

これを質問に追加しました:

if(x == a | b) {
    // this 
}
// can be written as
if((x == a) | (x == b)) {
    // this
}
// which can be written as
if(x == a) {
    // this
}
if(x == b) {
    // with this
}

それがどのように明るくなると思うのだろうか!

問題は、最初の 2 つのバージョンでは、if の下に 1 つのコード ブロックがあることです。したがって、3 番目の拡張バージョンに 2 つのブロックがある場合、それらは同じブロックである必要があります。つまり、これは単なる別の書き方です。

if (x == a || x == b) {
    // this
}

どこで || 従来のブール OR です。これはまさに私が最初に尋ねた質問です。

わかりました、もう一度... 構文を変更して、共用体と交差を行っていることを示しました。しかしその後:

if(userkey I ("shift" U "a")) {
    // pressed both "shift" and the "a" key.

つまりI、2 つのセットの交点を取ることを意味します...しかしif、どのような状況でコード ブロックを実行しますか? 交差点が空でない場合は?またはI、実際には「右側のセットのすべてのメンバーは左側のセットのメンバーですか」と尋ねていuserkeyます。ブロックのスコープ内で、実際には右側のセットだけである別の値に置き換えられるヒントがあります。

私はベッドに行くよ。

于 2010-03-24T23:22:23.397 に答える
3

あなたの例とあなたの数学はどちらもいくつかの作業を使用する可能性がありますが、ブログの例の少なくとも 1 つでは、 の使用はIcon プログラミング言語|の同じ演算子 (「代替」と呼ばれていると思います) の使用によく似ています 。

この分野で言語設計に取り組む予定がある場合は、必ず以下をお読みください。

于 2010-03-24T23:32:31.420 に答える
3

あなたの言語機能は、Perl 6 のジャンクションに似ています。

Perl 5 には、Quantum::Superpositionsモジュールがあります。

于 2010-03-25T01:01:58.660 に答える
3

C# には、あなたが説明している機能は確かにありません。あなたが話していることは、ロビン・ミルナーの円周率計算を幾分連想させるようです。並行プロセスを記述するための言語を定義することがすべてです。まだ調査していない場合は、調査を行うことを検討してください。

于 2010-03-24T23:45:46.163 に答える
2

たとえ例であっても、独自のシンボルを発明する必要があります。

スコープ定義の必要に応じて動的に変化する変数参照を実行しようとしているようです。これは非常に微妙なテクニックであり、私はそれを行う言語を知りません。ほとんどの言語では、これを明示的に行う必要がありますが、クロージャー、ジェネレーター、およびバックトラッキングとの類似点を見ることができます。

この異常な方法を推進している状況を説明していただけますか? あなたのブログのリンクはあまり役に立ちませんでした。また、「連続プログラミング」という用語も定義も説明もされていません。

アップデート:

さて、あなたの編集された例を見ると、似たようなものとして Icon を指すことができます。それはあなたが求めていると思うものとはまったく異なり、一般的ではありませんが、近いようで、より明確に定義されています。それは目標指向評価と呼ばれます。

多くの言語要素は、要求された場合に多くの選択肢を提供できるジェネレーターを提供または構築できるようにします。あなたの例と Icon の主な違いは、言語が代替案を試し続けるためにコンテキストを提供する必要があることです。割り当てはそれを行いませんが、比較は行います。ジェネレーターが提供できる値を使い果たすと、失敗します。これは、通常の比較が機能する方法でもあり、機能全体がより広い言語にうまく統合されます。(私は時々、これを小さな例外のようなものだと説明します。)

Python と Ruby のyieldメカニズムは非常に似ており、ほぼ間違いなく Icon のジェネレーターの影響を受けています。

于 2010-03-24T23:31:58.853 に答える
0

その言語機能を追加しないことをお勧めします。次のような「テスト」を行うと、x の意味が変わることは、プログラマには非常に不明確です。

if( x != a ) { ... }
于 2010-03-24T23:32:02.767 に答える
0

あなたは一度にいくつかのアイデアを探し回っているようです:

  • あなたが何かをするリスト構文 5 | 6 | 7
  • あなたが書いてきた外積を使って ::list:: + ::list::
  • 一方または両方の引数がリストの場合、等値、不等値、代入などの演算子の意味を慎重に定義します。つまり::scalor:: == ::list::、「の要素である」などを実装する

これらのアイデアを組み合わせた単一の構文機能を認識していませんが、実際には幅広い経験がありません...

于 2010-03-24T23:48:24.050 に答える
0

「with」はas3に存在します:

private var _a:Number = 0.0;
public function get a():Number{
// Do stuff
    return _a;
}
public function set a(value:Number):void{
// Do stuff
    _a=value;
}
于 2010-03-25T21:12:31.607 に答える
0

Inform IF オーサリング言語には、この機能がありました。DMから:

if (alpha == 3 or 4) print "Scott";

orただし、解析するのは少し奇妙で (各/|演算子を特定の所有者==/!=コンパレーターに関連付ける必要があります)、最新のスクリプト言語では次のようなものに簡単に置き換えることができるため、実際にはあまり普及していません。

if alpha in (3, 4):
    print 'Scott';

(Python の例)

于 2010-03-24T23:33:09.127 に答える