6

Ada に、、、、、または (拡張代入ではない ...)のような演算+=子が-=ないのはなぜでしょうか? 他の多くの言語 (C、C++、C#、Java、Perl) にはそれらがあります。++-=<<=x ? y : z

-- 例 (C/C++/...):

int a = 3;

a += 4; /* A */
// long: a = a + 4

a++; /* B */
// long: a = a + 1

a = ( a > 3 ? 10 : 5 ); /* C */
// long: ' if a > 3 then a = 10 else a = 5'

-- 例 (エイダ):

a : integer := 3;

a := a + 4;   -- A --
a := a + 1;   -- B --

if a > 3 then -- C --
    a := 10;
else
    a := 5;
end if;

(例は意味がありません - デモンストレーションのみ)

それは...

  • 演算子のオーバーロード (ただし、C++ にもそのようなメカニズムがあります)?
  • 読みやすさ?
  • 技術的な理由/制限?
  • これらの式を短くするための単なるトリックであり、プログラミングには実際には必要ありませんか?
  • Ada の代入演算子 is :=and not =(so +=-> +=:)?
4

1 に答える 1

24

Ada の設計は、他の言語よりも数学に密接に基づいているため...そして...

代入は演算子ではありません

演算子には特定のプロパティがあります。演算子は、結果を返す量に作用しますが、量自体は変更されません。

これは重要です。この「演算子」の理解に厳密に従うと、セマンティクスがはるかに予測可能になるため、多くの最適化が可能になります。基本的に、演算子には副作用がありません。それらを繰り返したり、繰り返されたものを除外したりできます。また、結果を変更せずに式を自由に並べ替えることができます。

演算子の割り当てを間違えた場合、... まあ、基本的にあなたはめちゃくちゃです。副作用のあるたった 1 つの「演算子」は、すべての演算子の貴重なプロパティを失うことを意味します...何のために? いくつかの表記上の利便性、非常に肥沃なバグの繁殖地、余分なパフォーマンスや効率はありません。

ちなみに、最近GCCの内部をいじる必要があったとき、式アナライザーで明示的に壊れた(中間表現の)関数を見つけ、内部的a++に(中間表現の)に変換したためa = a + 1;、短い形式は実際にはこれ以上効率的ではないようです!

同じ論理的根拠が関数にも当てはまります (VHDL よりも Ada の方が厳密ではありません)。関数は別の見方をすれば単なる演算子であり、純粋な関数 (VHDL では、宣言に「不純」という言葉がないすべての関数です!) には副作用がありません。

これが、Ada が関数と手続きの両方を持っている理由でもあります。プロシージャ、割り当て、およびステートメントは別のカテゴリです (プロシージャの呼び出しと割り当てはステートメントの形式です)。

概念を分離し、各タスクに適切な概念を使用することは、理解しやすく、おそらく意図したとおりに実行できる明確なプログラムを作成するのに大いに役立ちます...

ああ、Ada-2012 はついに VHDL-2008 と Algol-W (1963) に if 式と case 式で追いつきました...

a := (if a > 3 then 10 else 5);
-- to my eyes MUCH more readable than ?: especially in multiple if-exprs!

b := (case a is 
      when 3 => 5;
      when 6|7 => 10;
      when others => 0);

ここでの割り当てがまだステートメントであることは明らかです...

念のため:

代入は演算子ではありません

Ada のデザイナーは、完全性を損なうことなく何が可能で、何が混乱につながるかについて、印象的で通常は非常に明確に把握していました。新しい言語機能が追加されましたが、信頼できるものにするためにコンパイラ技術が十分に開発されたため、それは常に慎重なプロセスであり、Ada-83 サブセットは実質的に無傷のままです。

于 2013-01-22T22:44:20.527 に答える