В Oberon-report'e этот момент не уточнен (и вообще никак не описан), поэтому предлагаю обсудить, уточнить и договориться.
Итак, ситуация следующая - модуль A экспортирует указатель на структурный тип A.R, но сам A.R не экспортирует. Может ли модуль B импортирующий A.R создать в куче переменную типа A.R?
Код:
MODULE A;
TYPE
R = RECORD END;
P* = POINTER TO R;
END A.
MODULE B;
IMPORT A;
VAR
p : A.P;
BEGIN
NEW(p)
END B.
Технически мы это можем без проблем. Но в некоторых реализациях такое вот может быть не возможно, кроме того, если такое разрешить, то по сути мы лишаемся возможности создавать opaque-типы простым способом. Кроме того возникает логическое противоречие - почему то локальную переменную мы завести не можем, а переменную через NEW уже можем.
Поэтому предлагаю следующее:
1) Если импортирован только указательный тип, то с указателем можно делать все что обычно, но нельзя NEW. То есть новых экземпляров типа R пользователь заводить не может нигде.
2) Если импортирован еще и сам структурный тип (record or array), то создавать экземпляры (через NEW или иначе) можно, а доступ есть к тем полям которые экспортированны (помечены звездочкой), можно КОПИРОВАТЬ экземпляры (statement ":="). При этом конечно возможна ситуация когда тип экспортирован, но ни одного поля не экпортированно. Увы :-)
Ну и наконец есть особый случай, который тоже неоднозначен, и про который в репорте нет ничего:
MODULE A;
TYPE
P* = POINTER TO RECORD foo* : INTEGER END;
END A.
MODULE B;
IMPORT A;
VAR
p : A.P;
BEGIN
NEW(p); (* это можно? *)
p.foo := 42 (* а это? *)
END B.
Экспортирован тип-указатель на анонимную запись, причем у этой записи есть экспортированные поля. Таким образом переменную типа этой самой записи пользователь создать не может. Но, очевидно, он может обратиться к полю. Но может ли он создать через NEW новый экземпляр таковой безымянной записи?
Предлагаю создание экземпляра через NEW, в этом случае, также запретить. Таким образом у нас получается возможность создавать типы переменные которых могут создаваться ТОЛЬКО через фабрики (где они будут гарантированно инициализированны корректно), но при этом остается возможность прямого обращения к некоторым полям. (кроме того, опять таки, это логично, что если я не могу создать локальную переменную, то и через NEW тоже не могу её создать).
Как-то так. Какие будут мнения?