Discussion:
type extension across separate modules
(too old to reply)
nojb
2011-04-01 02:17:43 UTC
Permalink
Hello,

Is it possible to extend a record type defined in an imported module
in Oberon-07?

Thanks!
N
Chris Burrows
2011-04-01 04:52:24 UTC
Permalink
Post by nojb
Hello,
Is it possible to extend a record type defined in an imported module
in Oberon-07?
Yes - it is. We supply a pair of example modules Extensions.mod and
Lists.mod with Astrobe which demonstrate just that.

Lists declares a type:

Item* = POINTER TO RECORD
next: Item
END;

Extensions imports the Lists module and declares several extensions of this
type including:

Shape = POINTER TO RECORD(Lists.Item)
Area: PROCEDURE(self: Shape): REAL
END;

Rectangle = POINTER TO RECORD(Shape)
width, height: REAL
END;

Square = POINTER TO RECORD(Rectangle)
END;

Ellipse = POINTER TO RECORD(Shape)
diameter, height: REAL
END;

Circle = POINTER TO RECORD (Ellipse)
END;

You can download an evaluation copy of Astrobe v3.3 from our website if you
want to look at the complete sources and investigate further:

http://www.astrobe.com/download.htm

Regards,
Chris Burrows
CFB Software
http://www.astrobe.com
August Karlstrom
2011-04-26 17:49:47 UTC
Permalink
On 2011-04-01 06:52, Chris Burrows wrote:
[...]
Post by Chris Burrows
Item* = POINTER TO RECORD
next: Item
END;
Extensions imports the Lists module and declares several extensions of this
Shape = POINTER TO RECORD(Lists.Item)
Area: PROCEDURE(self: Shape): REAL
END;
Looking at this post again I notice that you use a pointer type as the
base type for Shape. I didn't know you could do that. ETH Oberon 2.4
allows it but 002C 2.1.11 does not. The language report says that
"pointer types inherit the extension relation of their base types",
though I have always thought it was applicable only in the context of
assignment and parameter compatibility. Is this more explicitly stated
somewhere?

/August
--
The competent programmer is fully aware of the limited size of his own
skull. He therefore approaches his task with full humility, and avoids
clever tricks like the plague. --Edsger Dijkstra
Chris Burrows
2011-04-28 10:53:16 UTC
Permalink
Post by August Karlstrom
[...]
Post by Chris Burrows
Item* = POINTER TO RECORD
next: Item
END;
Extensions imports the Lists module and declares several extensions of this
Shape = POINTER TO RECORD(Lists.Item)
Area: PROCEDURE(self: Shape): REAL
END;
Looking at this post again I notice that you use a pointer type as the
base type for Shape. I didn't know you could do that. ETH Oberon 2.4
allows it but 002C 2.1.11 does not. The language report says that "pointer
types inherit the extension relation of their base types", though I have
always thought it was applicable only in the context of assignment and
parameter compatibility. Is this more explicitly stated somewhere?
A good question - you may well be right. All the examples shown in section
11.2.1 'Extension of pointer types' in Programing in Oberon by Reiser and
Wirth certainly show the pointer / record declarations split into pairs. In
my case I wasn't aware that you shouldn't do it, rather than knowing that
you could.

My example then becomes:

Item* = POINTER TO ItemDesc;
ItemDesc* = RECORD
next: Item
END;

Shape = POINTER TO ShapeDesc;
ShapeDesc = RECORD(Lists.ItemDesc)
Area: PROCEDURE(self: Shape): REAL
END;

Regards,
Chris

--
Chris Burrows
CFB Software
Astrobe v3.3: ARM ARM Oberon-07 Development System
http://www.astrobe.com
August Karlstrom
2011-04-28 11:59:12 UTC
Permalink
Post by Chris Burrows
A good question - you may well be right. All the examples shown in section
11.2.1 'Extension of pointer types' in Programing in Oberon by Reiser and
Wirth certainly show the pointer / record declarations split into pairs. In
my case I wasn't aware that you shouldn't do it, rather than knowing that
you could.
A related case where OO2C and ETH Oberon disagree is whether the
following declaration is valid or not:

List = POINTER TO RECORD
item: INTEGER;
next: List
END;

You can argue that List is not visible inside the record definition as
List has not been (completely) declared yet. The language report tells
us that "The scope extends textually from the point of the
declaration...". The question is where "the point" is in this case.


/August
--
The competent programmer is fully aware of the limited size of his own
skull. He therefore approaches his task with full humility, and avoids
clever tricks like the plague. --Edsger Dijkstra
Chris Burrows
2011-04-29 22:30:29 UTC
Permalink
Post by Chris Burrows
A good question - you may well be right. All the examples shown in section
11.2.1 'Extension of pointer types' in Programing in Oberon by Reiser and
Wirth certainly show the pointer / record declarations split into pairs. In
my case I wasn't aware that you shouldn't do it, rather than knowing that
you could.
A related case where OO2C and ETH Oberon disagree is whether the following
List = POINTER TO RECORD
item: INTEGER;
next: List
END;
You can argue that List is not visible inside the record definition as
List has not been (completely) declared yet. The language report tells us
that "The scope extends textually from the point of the declaration...".
The question is where "the point" is in this case.
On further investigation, according to Section 9.2.1 'Extension of pointer
types' in 'Programming in Oberon' by Reiser and Wirth my definition of List
is invalid:

----------------------------------
...
Note that the node type (NodeDesc) must be explicit to avoid an illegal
recursive type definition of the form:

Node = POINTER TO RECORD key: Key; next: Node END;
...
----------------------------------

Regards,
Chris.
August Karlstrom
2011-04-29 23:46:30 UTC
Permalink
Post by Chris Burrows
On further investigation, according to Section 9.2.1 'Extension of pointer
types' in 'Programming in Oberon' by Reiser and Wirth my definition of List
----------------------------------
...
Note that the node type (NodeDesc) must be explicit to avoid an illegal
Node = POINTER TO RECORD key: Key; next: Node END;
...
----------------------------------
It's strange then that ETH Oberon, which I have considered to be the
reference implementation, allows it. Also, section 21 of Programming in
Oberon(1) (a PDF version different from the book) contains the following
declaration:

TYPE Item = POINTER TO RECORD
num: INTEGER; next: Item
END;

A PDF with slide notes from University of California, San Diego(2) also
discusses recursive records under the assumption that the above
construct is indeed valid; "Partly-declared records are okay as POINTER
types."

Note also that section 4 in the Oberon-2 report is a bit vague about
these forward declarations:

"A type T of the form POINTER TO T1 (see 6.4) can be declared at a point
where T1 is still unknown. The declaration of T1 must follow in the same
block to which T is local"

In the Oberon-07 report the word "identifier" has been added:

"If a type T is defined as POINTER TO T1 (see 6.4), the identifier T1
can be declared textually following the declaration of T, but it must
lie within the same scope."

Should we interpret this as a clarification in the Obeoron-07 report
that declarations like the one above are not valid?


/August


(1) http://www-old.oberon.ethz.ch/WirthPubl/ProgInOberon.pdf
(2) http://cseweb.ucsd.edu/~sorourke/cse131b/0128.pdf
--
The competent programmer is fully aware of the limited size of his own
skull. He therefore approaches his task with full humility, and avoids
clever tricks like the plague. --Edsger Dijkstra
Chris Burrows
2011-04-30 23:05:59 UTC
Permalink
Post by August Karlstrom
Post by Chris Burrows
On further investigation, according to Section 9.2.1 'Extension of pointer
types' in 'Programming in Oberon' by Reiser and Wirth my definition of List
----------------------------------
...
Note that the node type (NodeDesc) must be explicit to avoid an illegal
Node = POINTER TO RECORD key: Key; next: Node END;
...
----------------------------------
It's strange then that ETH Oberon, which I have considered to be the
reference implementation, allows it.
Allows it or does not prohibit it? That is the real question. This is one of
those cases where the declaration is syntactically correct, but (possibly)
not semantically correct.
Post by August Karlstrom
Also, section 21 of Programming in Oberon(1) (a PDF version different from
TYPE Item = POINTER TO RECORD
num: INTEGER; next: Item
END;
That is a different book altogether and does not have Martin Reiser as
co-author with Wirth. It is actually an Oberon version of the primary
Modula-2 reference book 'Programming in Modula-2' (a.k.a. PIM). I would
consider the Oberon translation to be a very rough draft as it contains many
inaccuracies. You should use it as a guide not a definitive reference.
Strangely though, the 1982 Modula-2 version that I have does have the extra
declaration:

ListPtr = POINTER TO Item;

and 'next' is a ListPtr.
Post by August Karlstrom
original A PDF with slide notes from University of California, San
Diego(2) also discusses recursive records under the assumption that the
above construct is indeed valid; "Partly-declared records are okay as
POINTER
types."
Note also that section 4 in the Oberon-2 report is a bit vague about these
"A type T of the form POINTER TO T1 (see 6.4) can be declared at a point
where T1 is still unknown. The declaration of T1 must follow in the same
block to which T is local"
"If a type T is defined as POINTER TO T1 (see 6.4), the identifier T1 can
be declared textually following the declaration of T, but it must lie
within the same scope."
Should we interpret this as a clarification in the Obeoron-07 report that
declarations like the one above are not valid?
Possibly.

I have recently formed the opinion that any particular advantage that
anonymous pointer types might have, may not be worth the additional
implementation effort. Also the advantages may well be negated by the
disadvantages as they can cause the sort of confusion / vacillation
evidenced in this discussion.

If you are interested in others' opinions try posting your questions in the
Oberon Community Platform Forum as well. There seems to be more activity
there:

http://www.ocp.inf.ethz.ch/forum/

and also on the ETH Mailing list:

https://lists.inf.ethz.ch/mailman/listinfo/oberon

Regards,
Chris
August Karlstrom
2011-05-02 16:09:36 UTC
Permalink
Post by Chris Burrows
Post by August Karlstrom
Also, section 21 of Programming in Oberon(1) (a PDF version different from
TYPE Item = POINTER TO RECORD
num: INTEGER; next: Item
END;
[...]
Post by Chris Burrows
Strangely though, the 1982 Modula-2 version that I have does have the extra
ListPtr = POINTER TO Item;
and 'next' is a ListPtr.
That's interesting. I find it hard to believe that this change happened
by accident in the translation from Modula-2 to Oberon. Maybe Prof.
Wirth has not made up his mind about this.

[...]
Post by Chris Burrows
If you are interested in others' opinions try posting your questions in the
Oberon Community Platform Forum as well. There seems to be more activity
http://www.ocp.inf.ethz.ch/forum/
https://lists.inf.ethz.ch/mailman/listinfo/oberon
OK, thanks for the info.


August
--
The competent programmer is fully aware of the limited size of his own
skull. He therefore approaches his task with full humility, and avoids
clever tricks like the plague. --Edsger Dijkstra
August Karlstrom
2011-06-10 13:30:01 UTC
Permalink
Post by Chris Burrows
On further investigation, according to Section 9.2.1 'Extension of pointer
types' in 'Programming in Oberon' by Reiser and Wirth my definition of List
----------------------------------
...
Note that the node type (NodeDesc) must be explicit to avoid an illegal
Node = POINTER TO RECORD key: Key; next: Node END;
...
----------------------------------
After reading section 26.1 and 26.3 of "An Oberon Compiler for the ARM
Processor" by Niklaus Wirth I conclude that in Oberon-07 declarations
like these are all valid:

TYPE
P0 = POINTER TO RECORD END;
P1 = POINTER TO RECORD (P0) END;
P = POINTER TO RECORD x: P END;

http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon.ARM.Compiler.pdf


August
--
The competent programmer is fully aware of the limited size of his own
skull. He therefore approaches his task with full humility, and avoids
clever tricks like the plague. --Edsger Dijkstra
Loading...