[M3devel] ARRAY OF ARRAY (Re: A bizarre language quirk)

Henning Thielemann lemming at henning-thielemann.de
Sat Mar 24 19:49:30 CET 2018


On Fri, 23 Mar 2018, Rodney M. Bates wrote:

> On 03/21/2018 02:57 PM, Henning Thielemann wrote:
>> 
>> On Wed, 21 Mar 2018, Rodney M. Bates wrote:
>> 
>>> Modula3, 2.6.3 (Designators), concerning subscripting says:
>>> 
>>> An expression of the form a[i_1, ..., i_n] is shorthand for 
>>> a[i_1]...[i_n].
>> 
>> I think I wrote earlier about this shorthand ...
>> 
>> I found the following problem:
>> 
>> ARRAY OF ARRAY OF Something
>> 
>> is syntactically not quite a 2D-array since as it is written it suggests 
>> that the sub-arrays may have different sizes.
>
> It never occurred to me that this syntax could suggest it could be a 
> ragged array, probably because I was already familiar with the (fixed) 
> array-of-array concept being truly 2D in Pascal and Modula2.

I did not have problems in understanding the Modula-3 report, instead I 
consider it a flaw in the syntax and it has practical consequences. Why 
can I choose in ARRAY OF ARRAY only the size of the outer array freely and 
the sizes of the inner arrays are constrained? Where is the composability 
of type constructors? And what is the size of the inner arrays if there 
are no inner arrays? What else would be the type of a ragged array, if not 
ARRAY OF ARRAY OF T?

In Haskell "Array Int (Array Int a)" would be actually a ragged array (in 
Haskell all objects are actually pointers to objects) and a rectangular 
2D-array would have the type "Array (Int,Int) a".


>> This has practical consequences. It would be no problem to have a 0-by-n 
>> array. But Modula-3 fails
>> to determine the size of the second dimension of a 0-by-n array, because 
>> LAST(a[0]) is a range
>> violation in the first dimension.
>
> But a[0] doesn't exist, so what would be a meaningful definition of its 
> size or bounds?  Even if you could somehow define and discover it, you 
> can't do anything else with a[0] either.

I want to get the extent of the 2D array without accessing any element. 
The array size must be stored separated from the elements anyway.

I encountered the problem when working with (row-major) matrices with zero 
columns. E.g. this simple loop

FOR i:=FIRST(a[0]) TO LAST(a[0]) DO
   sum:=0;
   FOR j:=FIRST(a) TO LAST(a) DO
     sum:=sum+a[j,i];
   END;
   b[i]:=sum;
END;

fails for a 0-by-n array because of the access to a[0]. But technically 
there is no need to reference a[0] because the size of a[0] is not stored 
in a[0] or any other a[i], but in 'a'.

Syntax suggests that NUMBER(a[0]) and NUMBER(a[1]) could be different but 
they cannot. The syntax of 2D arrays in Modula-3 actually corresponds to 
ragged arrays.

A syntax for rectangular two-dimensional arrays might be like:

ARRAY *,* OF T

or even mixed:

ARRAY *,[0..9],* OF T

A 3D array with ragged arrays in the last dimension would be:

ARRAY *,* OF ARRAY OF T

Elements might be accessed by

a[i,j]

It would still be useful to let a[i] denote a slice of the array. Then 
a[i][j] would still be allowed. Also NUMBER(a[i]) would still be allowed 
but it should not be necessary to access a[i]. Instead there might be a 
variation of NUMBER, like:

NUMBER(a,0) and NUMBER(a,1)

to access the extents in the two dimensions without accessing a 
potentially non-existent slice. The above loop would become:

FOR i:=FIRST(a,1) TO LAST(a,1) DO
   sum:=0;
   FOR j:=FIRST(a,0) TO LAST(a,0) DO
     sum:=sum+a[j,i];
   END;
   b[i]:=sum;
END;

and it would work for 0-by-n arrays, too.


More information about the M3devel mailing list