Абсолютно согласен, Иван, в процедуре можно реализовать двояко:
TYPE
bas=POINTER TO EXTENSIBLE RECORD
a:INTEGER;
END;
ras1=POINTER TO RECORD (bas)
b:REAL;
END;
ras2=POINTER TO RECORD (bas)
b:ARRAY 8 OF CHAR;
END;
VAR
p_bas:bas;
p_ras1:ras1;
p_ras2:ras2;

PROCEDURE TestType (p: bas);
BEGIN
p.a:=1;
Log.Int(p.a);
Log.Ln;
IF p IS ras1 THEN
p(ras1).b:=2.2222222;
Log.Real(p(ras1).b);
Log.Ln;
ELSIF p IS ras2 THEN
p(ras2).b:='Hello';
Log.String(p(ras2).b);
Log.Ln;
ELSE
END;
END TestType;

Или так

PROCEDURE TestType (p: bas);
BEGIN
p.a:=1;
Log.Int(p.a);
Log.Ln;
WITH p: ras1 DO
p.b:=2.2222222;
Log.Real(p.b);
Log.Ln; |
p: ras2 DO
p.b:='Hello';
Log.String(p.b);
Log.Ln;
ELSE
END;
END TestType;

Просто мне второй способ более понятен из-за того, что вместо p(ras1).b:=2.2222222; можно писать p.b:=2.2222222;
Но это дело вкуса.