[Oberon] Clarifying type compatibility in Oberon-07
Chris Burrows
chris at cfbsoftware.com
Thu Oct 12 14:17:17 CEST 2017
> ---------------------------------------------------
> On Fri Oct 6 12:40:42 CEST 2017 Jörg Straube:
>
> Personally, I’m not indifferent ☺ > > I know that it can be done, but the question is WHY. Only because
> something can be done is a poor reason to do it.
>
> If you put a := b in your code, you do that as you know or assume
> a certain relationship between those two variables (they e.g. represent
> instances of the same or comparable thing). If this hold true,
> I don’t understand why you have to write two totally independent
> type declarations that (by accident) match structurally.
>
(Adapted from comp.lang.oberon)
Generally that is true. However, it became more of a need when working with open arrays after Oberon was changed to make array value parameters read-only. A local copy of the parameter was no longer automatically created for you. At the time, making a local copy of the parameter could only be done with an explicit loop or SYSTEM.COPY, neither of which are ideal. The former is significantly less efficient than the inline loop generated by an array assignment statement. Fortunately, in May 2016, the Oberon array assignment rule was relaxed with the addition of the following rule:
"9.1.4. An open array may be assigned to an array of equal base type."
Since that time you have been able to write:
PROCEDURE P(s: ARRAY OF CHAR);
VAR
local: ARRAY 255 OF CHAR;
BEGIN
local := s;
...
...
The downside of this is that the declaration of the local array has to be large enough to handle the largest array that might be passed to the procedure. This could lead to inefficient stack usage.
We support an extension in the Astrobe for ARM Cortex-M compilers that allows single-dimensional dynamic local array variables. This was originally implemented in Wirth's earlier ARM Oberon compiler but not in his RISC5 compiler. The NEW command in this case allocates space on the stack (not the heap) for the local array. This is elegant because it doesn't require any corresponding DISPOSE or garbage collection - the space is automatically reclaimed when the procedure is exited.
The example above then becomes:
PROCEDURE P(s: ARRAY OF CHAR);
VAR
local: ARRAY OF CHAR;
BEGIN
NEW(local, LEN(s));
local := s;
...
...
Another situation where I initially thought I would need to assign arrays of different types efficiently was when serialising / buffering data for the low level sector read / write routines in the SDHC file system I recently implemented. However, it turned out to be a more general problem which also required copying array slices and mapping record structures to arrays. I did use the ARRAY OF BYTE language extension for this but have realised since that SYSTEM.COPY would have been more appropriate.
Regards,
Chris Burrows
CFB Software
http://www.astrobe.com/RISC5
More information about the Oberon
mailing list