为什么在Ada中没有(扩充赋值)运算符如+ =, - =或++?

时间:2013-01-22 21:49:16

标签: operators ada

我想知道为什么没有+=-=++-=<<=x ? y : z等运营商(不是增强的作业 ...)在Ada?许多其他语言(C,C ++,C#,Java,Perl)都有它们。

- 示例(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'

- 示例(Ada):

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中的赋值运算符为:=而不是=(所以+= - &gt; +=:)?

1 个答案:

答案 0 :(得分:21)

因为Ada的设计比其他语言更接近于数学......所以......

作业不是运营商

操作员具有特定属性 - 它们对返回结果的数量进行操作 - 同时保持数量本身不变。

这很重要 - 严格遵守对“运算符”的理解,并且您可以进行大量优化,因为语义更容易预测。从本质上讲,运营商没有副作用。您可以重复它们或将重复的因子分解出来,并且您可以更自由地重新排序表达式而无需更改结果。

如果你错误地为操作员分配,......好吧,基本上你被搞砸了。 只有一个带有副作用的“操作员”意味着你失去了所有操作员的宝贵财产......为了什么?一些符号方便,一个非常肥沃的虫子滋生地,没有额外的性能或效率。

顺便说一句,当我不得不最近在GCC内部发现时,我发现它的表达式分析器中的一个函数明确地破坏了a++的中间表示,并将其内部转换为({1}}的{​​中间表示}所以较短的形式似乎没有更高效!

相同的基本原理(Ada比VHDL严格来说)适用于函数 - 它们只是另一种形式的运算符和纯函数(在VHDL中,每个函数在其声明中没有“不纯”这个词!)没有副作用。

这也是Ada同时具有功能和程序的原因:函数,运算符和表达式基本相似(理想情况下,无状态和无副作用);程序,作业和陈述是一个单独的类别(程序调用和作业是陈述的形式)。

分离概念并为每项任务使用适当的概念对于制定明确的程序是很有帮助的,这些程序可以理解并且可能按照您的意图进行...

哦,Ada-2012终于赶上了VHDL-2008和Algol-W(1963)的if-和case-expressions ......

a = a + 1;

很明显,这里的作业仍然是陈述......

只是为了确保:

作业不是运营商

Ada的设计师有一个令人印象深刻的,通常非常清楚地掌握了什么是可能的,而不会影响完整性,什么会导致一团糟。虽然添加了更新的语言功能,但随着编译器技术的发展足以使它们变得可靠,它始终是一个谨慎的过程,而Ada-83子集仍然几乎完好无损。