6

我想知道为什么Ada中没有像+=, -=, ++, -=, <<=or x ? y : z(not an augmented assignment ...) 这样的运算符?许多其他语言(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 中的赋值运算符是:=而不是=(所以+=-> +=:)?
4

1 回答 1

24

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

赋值不是运算符

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

这很重要 - 严格遵守对“运算符”的理解,并且您可以进行很多优化,因为语义更可预测。本质上,运营商没有副作用。您可以重复它们或排除重复的那些,并且您有更多的自由来重新排序表达式而不改变它们的结果。

如果您将分配误认为是操作员,...好吧,基本上您就完蛋了。只有一个具有副作用的“操作员”意味着您会失去所有操作员的宝贵属性……为什么?一些符号上的便利,一个非常肥沃的错误滋生地,没有额外的性能或效率。

顺便说一句,当我最近不得不在 GCC 内部闲逛时,我在其表达式分析器中发现了一个函数,该函数显式破坏了 (intermediate representation for)a++并在内部将其转换为 (intermediate representation for)a = a + 1;所以较短的形式确实看起来没有任何效率!

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

这也是 Ada 既有函数又有过程的原因:函数、运算符和表达式本质上是相似的(理想情况下,无状态且无副作用);过程、赋值和语句是一个单独的类别(过程调用和赋值是语句的形式)。

分离概念并为每项任务使用适当的概念对于制作清晰的程序大有帮助,您可以理解并可能按照您的意图进行操作......

哦,Ada-2012 终于用 if 和 case 表达式赶上了 VHDL-2008 和 Algol-W (1963)……

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 回答