Является ли добавление производного типа изменением интерфейса? - PullRequest
2 голосов
/ 16 апреля 2020

На странице 324 «Программирование в Ada 2012» Джона Барнса он заявляет, что неопределенный вызов тега будет компилироваться, если существует только один тип, определяющий задействованные примитивы. Итак, учитывая:

root.ads:

package root is

   type object is tagged null record;

   function is_further (X, Y: Object) return boolean;
   function unit return object;

   -- type circle is new object with null record;

end root;

Вызов is_further(unit, unit) скомпилируется. Однако, если мы позже добавим производный тип, такой как окружность, к этому интерфейсу, вызов будет неоднозначным:

main.adb:8:14: ambiguous expression (cannot resolve "is_further")
main.adb:8:14: possible interpretation (inherited) at other.ads:4
main.adb:8:14: possible interpretation at root.ads:5
main.adb:8:25: ambiguous call to "unit"
main.adb:8:25: interpretation at other.ads:4
main.adb:8:25: interpretation at root.ads:6
gprbuild: *** compilation phase failed

Насколько я знаю, это делает Ada единственным языком программирования, где добавление производного типа является изменение интерфейса ломается. Поскольку это ужасная перспектива, есть ли способ заставить данное выражение всегда терпеть неудачу, даже с одним типом?

Неуклюжим решением является определение частного производного типа, который не используется, для каждого листа (под) тип, который я выставляю. (хотя я не могу заставить клиентов не использовать его, позже я не буду расширять этот тип, поэтому проблема не возникнет)

Обратите внимание, что проблема не только в root тип. Это проблема для всех типов листа (т.е. без какого-либо производного от него типа). Например, если мы позже расширим объект в другом пакете:

with root; use root;

package circles is

   type round_thing is new object with null record;

   procedure turn_around( R : round_thing );

   type ambiguate_indeterminate_calls_for_round_thing is new round_thing with null record;

end circles;

Я на самом деле хотел просто определить round_thing и оставить возможность позже добавить овал. Но без неиспользуемого производного типа кто-то мог бы написать turn_around(unit) в то же время, поэтому, когда я добавлю свой овальный тип, он столкнется с ambiguous expression (cannot resolve "turn_around").

Мне кажется, что в Аде есть недостаток, заключающийся в том, что разрешены неопределенные вызовы тегов, поэтому есть ли хороший способ запретить их, либо изменив код в пакете, либо добавив флаг компилятора?

...