[Oberon] Clarifying type compatibility in Oberon-07

Stéphane Aulery saulery at legtux.org
Thu Oct 12 01:51:36 CEST 2017


Hello,

Disclaimer : Excuse my neophyte questions. Maybe I'm making mistakes. 
long post with some code at the end.

Le 11/10/2017 à 15:52, Andreas Pirklbauer a écrit :
>> As pointed out by Diego, ARRAY 12 OF INTEGER is a type constructor which
>> creates a new type, whereas INTEGER is the name of an existing type. So  > in code A the variables have different types, and in code B they have 
>  > the same type.
> 
> Understood. And... good point. But one still needs to *define* what the
> assignment rules should be in both cases. *One* sensible choice (which
> is the status quo in Oberon-07) is to assume structural equivalence for
> basic types and name equivalence for structured types such as arrays and
> records (except for open arrays). This particular choice kind of draws
> a(nother) clear distinction between the two, also when it comes to
> assignment rules. But it is not the only choice. Hence this discussion.

M and M2 are valid but M1, M3, M4 and M5 are invalid, so it seems 
inconsistent in fact. No?

Why M2, which is more complex and structured is valid and not the simple 
cases M2 and M1?

Wy M3 not allowed? I can loose data with M2 in assignment but I can't 
assign a base type variable to an extended type variable.


As for the discussion on type compatibility, it reminds me of the 
quarrel of the universals [1] (link to the French page because the 
English version is really poor). By analogy :

a) You can look the Type as an idea (Plato) and a variable like a being. 
In that case you can not mix beings because they come from really 
distinct ideas.

b) You can look the Type just as a conceptual name and allow full 
structural assignment.

c) You can look for a mixed way. It's the case in fact.

I think the are three things : variables, structures (RECORD, ARRAY, 
INTEGER...) and types. You can give a name to a variable and a type. 
What is missing is to be able to give names to a structure.

With a separate name for them you could declare a variable as an 
instance of a structure and use it from a structural perspective only, 
with record extension in consideration ; and declare a named type 
derived form a structure, that you instantiate with a variable : in that 
case no mix is allowed. It's like a kind of protected alias of the named 
structure.

Basics element types can be there own named structure and you can assign 
them some type name to not mix an unstructured variable.

For example:

TYPE
   Apple = Fruit;
   Orange = Fruit;
   AppleTree = Tree;
   Dot = INTEGER;

STRUCT
   BOOLEAN = BOOLEAN; (* Implicit, no need to declare that *)
   CHAR = CHAR; (* Implicit, no need to declare that *)
   INTEGER = INTEGER; (* Implicit, no need to declare that *)
   REAL = REAL; (* Implicit, no need to declare that *)
   BYTE = BYTE; (* Implicit, no need to declare that *)
   SET = SET; (* Implicit, no need to declare that *)
   Fruit: RECORD
       aa: INTEGER;
       bb: ARRAY 10 OF INTEGER;
   END;
   FruitJus: RECORD (Fruit)
       cc: INTEGER;
   END;
   Tree: ARRAY 300 OF Fruit;
   Shrub: ARRAY 30 OF Fruit;
   Bag: ARRAY OF Fruit;

VAR
   a: BOOLEAN;
   b, bb: CHAR;
   c: INTEGER;
   d: REAL;
   e: BYTE;
   f: SET;
   g, h: Fruit;
   i: Tree;
   j, r: Apple;
   k: Orange;
   l, m: AppleTree;
   n: Tree;
   o: Shrub;
   p: Bag;
   q: Dot;

b := bb; (* OK *)
g := h; (* OK *)
g := k; (* KO *)
j := k; (* KO *)
m := h; (* OK *)
h := m; (* OK *)
i := n; (* OK *)

j := r; (* OK *)
n := o; (* OK *)
o := n; (* OK *)
n := p; (* OK *)
p := n; (* OK *)
c := q; (* KO *)

-----------------------------------------------------------------------
MODULE M;
   TYPE
     Apple = INTEGER;
     Orange = INTEGER;

   VAR
     x: Apple;
     y: Orange;
BEGIN
   y := x
END M.
-----------------------------------------------------------------------
MODULE M1;
   TYPE
     Apple = ARRAY 10 OF INTEGER;
     Orange = ARRAY 10 OF INTEGER;

   VAR
     x: Apple;
     y: Orange;
BEGIN
   y := x
END M1.
-----------------------------------------------------------------------
MODULE M2;
   TYPE
     Tb = RECORD
       aa: INTEGER;
       bb: ARRAY 10 OF INTEGER;
     END;
     Te = RECORD (Tb)
       dd: INTEGER;
     END;
	
   VAR
     x: Tb;
     y: Te;
BEGIN
   x := y;
END M2.
-----------------------------------------------------------------------
MODULE M3;
   TYPE
     Tb = RECORD
       aa: INTEGER;
       bb: ARRAY 10 OF INTEGER;
     END;
     Te = RECORD (Tb)
       dd: INTEGER;
     END;
	
   VAR
     x: Tb;
     y: Te;
BEGIN
   y := x;
END M3.
-----------------------------------------------------------------------
MODULE M4;
   VAR
     x: ARRAY 10 OF INTEGER;
     y: ARRAY 10 OF INTEGER;
BEGIN
   x := y;
END M4.
-----------------------------------------------------------------------
MODULE M5;
   VAR
     x: RECORD aa: INTEGER; bb: INTEGER END;
     y: RECORD aa: INTEGER; bb: INTEGER END;
BEGIN
   x := y;
END M5.
-----------------------------------------------------------------------
[1] https://fr.wikipedia.org/wiki/Universaux

Regards,

-- 
Stéphane Aulery


More information about the Oberon mailing list