Я понимаю там в хаскелле/сишарпе forward declarations не нужны -- весь модуль/класс просматривается при поиске нужной процедуры, переменной или типа , но в обероне...
Жестокое упрощение языка...
Дык лишняя сущность же!
Ну, на самом деле, если ослабить вот это требование: "The scope extends textually from the point of the declaration to the end of the block (procedure or module) to which the declaration belongs and hence to which the object is local." до "whole block (procedure or module)", то получится язык поприятнее для кодописателя (и чуть менее приятный для компилятороклепателя, хотя и тут выигрыш таки в итоге будет, ибо компилятор железно перестает быть однопроходным).
Даже если этого не делать, не следует по крайней мере разрешать видимость в процедуре внешнего к ней идентификатора, до того места где внутри процедуры будет (если будет) объявлен локальный идентификатор с тем же именем. Все идентификаторы внешние к процедуре следует импортировать в процедуру
явно, возможно по псевдониму, и объявлений в процедуре идентификаторов с теми же именами/псевдонимами быть не должно. Хотя такой импорт расширяет синтаксис.
Да? А как? Вот у меня процедура Foo, которая использует другую процедуру которая определена где-то далеко внизу. Вопрос - как за один проход такое компилировать?
Никак. Просто потому, что в общем случае нельзя "угадать" сигнатуру - оберон допускает неявные преобразования типов аргументов. Например f('A') может быть как вызовом "PROCEDURE f(c: CHAR)" так и "PROCEDURE f(s: ARRAY OF CHAR)". Кроме того, передача VAR-аргументов тоже влияет на генерируемый код в точке вызова.
Неуверен, что невозможность без заглядывания вперед "угадать" сигнатуру вызываемой процедуры влечет невозможность генерировать готовый код такого вызова. Для ссылочных типов это получается.
Почему только вызовы процедур делают невозможным генерировать код с одного прохода при таких правилах видимости? Ведь есть еще константы и типы. Когда объявляется константа, тип или переменная, это тоже требует генерации кода. И если это объявление сделано до того как объявлены используемые им другие константы или не стоящие под ссыкой типы, то немедленная генерация готового кода здесь тоже будет невозможна. Конечно, у констант находящихся в вызовах процедур тип всегда будет известен без заглядывания вперед.
Начиная с версии 2011 литералы литер (тип CHAR) и строк (тип Srtring) проходят одним нетерминалом и задаются через литерные цепочки только с двойными кавычками либо через число с суффиксом "X". Но неясно, можно ли однолитерные литерные цепочки использовать как литеры.
В версии 07 литералы литер, помимо числа с суффиксом "X", задаются через литерные цепочки с одинарными кавычками (в переводе Бурцева в репорте написано: CharConst = """ character """ | digit {hexDigit} "X", но примеры идут: 'A' '%' 22X), но строковые литералы задаются через литерные цепочки и с двойными кавычками и с одинарными. В версии 1 литералы и литер и строк могут задаваться литерными цепочками только с двойными кавычками (в репорте для литер нет примеров).
Есть и другой пример невозможности угадать сигнатуру без заглядывания вперед, если идентификаторы видны всюду в блоке, а не только впереди от точки своего объявления.
Фактический параметр может быть не только литералом неясного типа, тип которого требуется уточнять типом формального параметра, но и объектом, чей тип объявлен позже чем сделано обращение к объекту. Поскольку, вызов процедуры "f", происходящий когда обработаны еще не все декларативные области модуля (включая локальные), возможен только внутри другой процедуры "h", т.е. локально, и поскольку после такого вызова далее объявляются лишь процедуры (внешние по отношению к "h"), указанный пример возможен, если фактический параметр есть идентификатор некоторой нелокальной процедуры "g" или вычисляется на основе таких процедур.
То есть, если в теле некоторой процедуры "h" идет вызов "f(g)" или например "f(g(0)+g(1))" некоторой процедуры "PROCEDURE f(a: T)", где процедуры "f" и "g" объявлены после точки этого вызова, то в этой точке тоже невозможно угадать сигнатуру "f" без заглядывания вперед.