1

独自のプログラミング言語を設計していると想像してください。非常に特定の目的のための非常に単純な言語。関数、ループ、変数があります。また、変数の動的スコープを利用したいと考えています。

架空の例を考えてみましょう:

var x = "foo"
var count = 0

loop (/* condition */) {

    var x = "bar"
    // A new stack frame is created for 'x',
    // so inside the loop (and any subsequent function calls) it is bound to "bar",
    // but outside the loop 'x' is still bound to "foo"

    print (x) // output is "bar"

    var count = count + 1
}

print (x) // output is "foo"
print (count) // desired output is something above zero, but it's not !!!

私の質問は - ループ内に設定された「カウント」変数値を外部に表示する方法は? ユーザーにとってより自然な (または混乱を避ける) ようにするには、どうすればよいでしょうか?

  • 現在のスコープで新しい変数を定義するためのキーワードに加えて、外側のスコープから既存の変数に値を割り当てるための特別なキーワードを導入しますか? setvar、またはassingdefなどとしましょう。しかし、「外側のスコープ」とは何を意味するのでしょうか? 「count」がループの直前に定義されておらず、代わりに呼び出しスタックのどこかで定義されている場合はどうなりますか? 「set count = ...」は、親フレームの親の親から変数に値を割り当てますか?
  • 次のような記述ができるように、ループ文に戻り値 (またはタプル) を導入しますか?

    変数カウント = 0 変数カウント = ループ (条件 == 真) は [i] { 変数 i = i + 1 } を返します。

それは厄介に見えませんか?

  • あなたの解決策は?

知る限り、Perl はlocalキーワードを使用した動的スコープをサポートしています。動的スコープ変数のみを使用して、Perl でこのような例をどのように実装しますか?

ありがとうございました!

4

1 に答える 1

0

ここでケーキを食べたいみたいですね。内側のスコープで宣言された一部の変数は、外側のスコープで同一の変数を「隠す」必要がありますが、他の変数はそうすべきではありません。

私にはとても簡単に思えます。変数が外部スコープと同一の署名 (名前と型) で内部スコープで宣言されている場合、コンパイラはこの「構文糖衣」を許可し、中間コードのマッシュアップによって実際に参照される新しい変数を単純に作成する必要があります。使用されます (MSIL、JIL、アセンブリ)。次に、count から var 宣言を削除すると、メソッド内スコープに関するほとんどの標準により、これが思いどおりに機能します。オプションで、内側の変数宣言で「new」キーワードを使用して、外側のスコープ定義を「隠す」同じ名前の変数が本当に必要であることをコンパイラーに確認する必要があります。したがって、スニペットは次のようにのみ変更されます。

var x = "foo";
var count = 0;

loop (/* condition */) {

    var x = "bar"; //"hides" the outer x; maybe require "new" to confirm

    print (x); // "bar"

    count = count + 1; //works with the outer definition of count
}

print (x); // "foo"
print (count); // > 0
于 2010-09-29T16:10:35.250 に答える