[Oberon] concrete use of open array

Aubrey.McIntosh at Alumni.UTexas.Net Aubrey.McIntosh at Alumni.UTexas.Net
Thu Jun 24 21:55:47 MEST 2010

On Thu, Jun 24, 2010 at 10:49 AM, spir <denis.spir at gmail.com> wrote:
> Hello,
> I start to get a feeling of Oberon's style (I guess). Seems it requires programmers to build their toolkit, even for very basic, everyday, all-purpose, little tiny tasks (even more than eg Lua, which reputation reads "DIY"). Comments?

There are libraries in C, for example.  Things such as toupper, that
are primitive operations that are not part of the language, but part
of the environment.  These have to be supplied for very basic everyday
little tiny tasks.  To a programmer who is new to the C ecosystem,
these are mysterious and frustrating.

Oberon has its own libraries, and some of them are also very basic and
primitive.  If you want to do things the same way they are done in a
different ecosystem you both can and must port a lot of stuff to make
Oberon work that way.

Of course, people who have used Oberon for some time just want to cry
and bang their head against the wall whenever they face people who
want to take a step decades backward to those ways of doing things.
Oberon is both more powerful and much easier to use, provided that you
are working in the Oberon thought patterns, not trying to translate
everything back to patterns from some other language.

It is probable that the library exists that will allow you to program
a solution to whatever problem you are trying to solve.  The trick is
to read and become fluent in the knowledge of these libraries.  This
is true for any language choice.

> Some details still escape my understanding, esp. around open arrays -- again.

> -1- form of actual parameter
> Since one cannot have a VAR of open array type, what is the actual form of an open array parameter, in the call expression?
> I tried the "[...]" format used in some Pascal dialects to express open array constants, but it is refused.
> Side-question: is there a literal notation for arrays? for records? (eg like pascal consts, or var initialisation)

I just compiled and executed a program using open array types, see
below.  Sometimes it is necessary to keep a distinction between
pointers to open arrays, and var pointers to open arrays.  This is the
source of a lot of trouble in programming, and in Oberon the compiler
is kind enough to bring your attention immediately to the buggy code
and wait for you to fix it.  This strikes many of us as far better
than spending 3 weeks looking at core dump before we finally focus on
the equivalent line of code.

> -2- COPY vs assignment
> The following is accepted by obc but refused by oo2c [EDIT: the opposite, in fact!]. Note that t1 & t2 share a unique & named type. In the latter case, I need to use COPY instead of :=.
> MODULE trial;
> VAR     i       : INTEGER;
>        t1,t2   : ToChars;
>        NEW(t1,3) ; NEW(t2,3);
>        FOR i := 0 TO 2 DO t1[i] := CHR(97+i) END; t2[3] := 0X;
>        t2 := t1;       (* COPY(t1^,t2^); *)
>        (* output routine *)
> END trial.
> But COPY removes the last element by replacing it with 0X, whatever lies there in the source array. My use case is a flexible array, of which a char sequence is only a particuliar case, which holds a 'size field' (so that getting the size does not require sequence traversal). Also, arrays of chars are commonly used as byte sequences. (Even more on Oberon since there is no BYTE?)
> Is there a way to make assignement work between all kinfs of open arrays?

This code allocates space for two arrays, pointed to by t1 and t2.
It then orphans the array pointed to by t2, and makes both t1 and t2
point to the same memory.

The Oberon 2 Report discusses COPY in 10.3 Predeclared procedures.

My reading is that COPY works when the underlying array element is a
CHAR.  I suspect it stops at the first 0X character in most
implementations.  The whole Oberon system is expressed with strings
that don't contain an internal 0X character.

For other arrays, the iterating axillary variable is always used.  The
philosophy here is that the source code tells the human reader what is
going on in the machine code.  So your FOR loop over i is the usual
way to do this.  It compiles to very compact code, it is easy to read,
and no surprises happen due to a compiler optimization.

> -2- size & copy
> Assignment/copy between arrays of different sizes does not seems to be possible, or at least I could not have it work (neither is the case where dest >source, nore the opposite). About COPY, the report says the dest if truncated if necessary, but even this does not work with the compilers I use. Is there a way to express:
>    a2 := a1[i..j];
>    a2[i..j] := a1;
> ?

Again, this is expressed with explicit index variables.  Something like
  a2[k] := a1[k+i]
with guards for the beginning and ending values.

> -4- allocation
> Say I'm writing a func returning the indices of occurrences of a given element in a collection. I guess the only possible return type is a pointer to an open array. Correct? But how to allocate it (NEW(indices,size)), since its size is also a result of the process (collection traversal)?
> The only solution I found is two traverse twice ;-): once to count and then allocate, once to feed the array.

I would use a link list for this problem.  If you need to interface to
code that chose the array solution, then I usually create the link
list, and feed the array from the list, not a new traversal.

> off-topic:
> * is it possible to rename imported procs (eg "Write := Out.String" :-)?

Generally, anything that interferes with the ability to look at a page
of printout and understand things is not allowed.  If you obscure the
name of the module that does the importing or the procedure name, this
interferes with the "face of the document" interpretation.

> * alternatives to "(**)" such as "{}" or "//"? My editor deals badly with "(**)", transforming comments into visual pollution; and not permitting comment-in/out toggling.
> Denis
> ________________________________
> vit esse estrany ☣
> spir.wikidot.com
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon

MODULE test2;
		Array = ARRAY OF CHAR;
		RomValues = 'Example is good.';

		ramcopy : ARRAY 32 OF CHAR;
	PROCEDURE MakesChangeTo (VAR array : Array; ix : INTEGER);
		VAR aux : POINTER TO Array;
		NEW (aux, LEN(array));
		COPY(array, aux^);
		array [ix] := CAP(array[ix]);
		Out.String (array);
	END MakesChangeTo;
	PROCEDURE NoChangeTo (array : Array);
		array [6] := CAP (array[6]);
		Out.String (array);
	END NoChangeTo;
	ramcopy := 'Example is good.';
	NoChangeTo (RomValues);
	MakesChangeTo (ramcopy, 8);
	MakesChangeTo (ramcopy, 11);
END test2.

Aubrey McIntosh, Ph.D.
1502 Devon Circle
Austin TX 78723-1814

More information about the Oberon mailing list