NEW нужен для отлавливания опечаток. без него можно опечататься в имени метода для записи-расширения, и компилятор молча это соберёт.
Код:
TYPE
R0 = EXTENSIBLE RECORD END;
R1 = RECORD (R0) END;
PROCEDURE (VAR r: R0) Something; BEGIN … END Something;
(* а вот тут мы хотели переопределить `Something`, но опечатались в одной букве *)
PROCEDURE (VAR r: R1) Someting; BEGIN … END Someting;
без NEW этот код соберётся, но делать будет явно не то, что программист задумал. с NEW же компилятор сразу выругается.
атрибут EMPTY — это реально просто замена пустого тела. нужен в основном для того, чтобы при чтении кода различать случаи, когда метод следует реализовать в наследниках, или у нас валидная пустая реализация. или точнее: EMPTY обозначает опциональные интерфейсы, которые можно не реализовывать.
LIMITED-записи нельзя больше расширять, поэтому обойти не получится.
экспорт типа «implementation-only» очень широко используется в фабриках. например, у записи есть метод `Init`, который имеет право вызывать только фабрика, а пользователь — не имеет. поэтому мы объявляем его в интерфейсе как «implementation-only export». фабрика может его вызывать, потому что интерфейс описан в том же модуле; а вот пользователи уже не могут, и мы застрахованы от ошибок повторной инициализации.
Еще раз вернусь к этому вопросу. Без атрибута NEW метод Someting будет делать то, что хочет программист, за исключением одного - он не сможет вызвать супервызов, но это будет отловлено на этапе компиляции. И запись R1 будет содержать не один метод, а два, что увеличит расход памяти на один указатель.