> -- adimetrius писал(а):
> Тогда, пожалуй, и типы-синонимы тоже - структурно, а не номинально совместимы:Нет, ведь, TYPE не вводит новые типы сам по себе, а  всего лишь"Описание типа связывает идентификатор с типом", поэтому ссылаясь в правой части на уже имеющееся имя он вводит не синоним, а ещё одно имя-псевдоним. А создаются типы соответствующими конструкторами - ARRAY и RECORD. Разница тонкая, но существенная. Для создания нового типа-синонима(или почти синонима) в Oberon нет специальной конструкции, потому что для этого всего-то и нужно объявить массив из одного элемента или запись с одним элементом. Разве что вернуть из функции значение такого типа нельзя.

## Код:
```
TYPE 
  Pixels = ARRAY 1 OF INTEGER; 
  Units = ARRAY 1 OF INTEGER;

(* Pixels и INTEGER почти совместимы, Units и INTEGER почти совместимы, Pixels и Units несовместимы, требуют явного приведения *)

PROCEDURE (rd: Rider) DrawRect (l, t, r, b: Pixels);
PROCEDURE (f: Frame) DrawRect (l, t, r, b: Units);

PROCEDURE P (f: Frame; rd; Rider; x, y: Units);
VAR px, py: Pixels;
BEGIN
  f.DrawRect(Unit0, Unit0, x, y);
  f.UnitToPixel(x, px);  f.UnitToPixel(y, py); 
  rd.DrawRect(Pixel0, Pixel0, px, py);
  rd.DrawRect(Pixel0, Pixel0, x, y)  (* недопустимо, ошибка компиляции *)
END P;
```
