The Hyper Programming Language |
home | language reference | compiler | hyper on launchpad |
Open arrays are a necessary feature to be able to work decently with arrays. This will be a little difficult to imagine for those that only know Java, because in Java the size of an array is only known at runtime. But users of other languages that use arrays in a more traditional way, know that open arrays are necessary to have flexibility for procedures or functions that accept array parameters.
This brings us to a first difference between open arrays in Hyper and in other languages. In other languages (at least as far as I know) you can only use open arrays in parameters of procedures and functions. In Hyper, you can use them in many different places. Another difference is that in for example C++, you can only leave out the size of the first dimension in a parameter. In Hyper, you can even leave out all dimension sizes if you like.
The declaration of open arrays is trivial if you already know how to declare a regular array. You just declare the array as usual, but leave out the size of the dimension. This will often look as some empty "[]", for a two-dimensional array "[][]", or "[,]" in the case you like the 'merged' notation etc.
Now it's time for some rules. You can't just leave out dimension sizes just anywhere you want. The thing you have to take into account is that the array you want to make open must be pointed to. This can be an array as the base type of a pointer type, or an array parameter that is passed by reference (see procedures and arrays).
Variables that are declared as a pointer to an open array can simply be initialized by a pointer to another array that has the same base type, whose number of dimensions is the same, and whose dimension sizes match all not omitted sizes from the open array.
Elements of an open array can be accessed with the regular array operator, but of course the compiler can't do range checking then. So you have to be extra careful that you don't go outside the array. You will have to use the procedure(s) of the array to know the size of each dimension of the array.
This is a generalization of the 'sum 5 items' example from the page about arrays in general:
procedure p() var list : [5] int arr[0] = 152 arr[1] = -45 arr[2] = 6 arr[3] = -21 arr[4] = 99 system.out.printLn(sumItems(list)) end procedure sumItems(arr : [ ] int) : int var currentSum : int = 0 iterate i : nat from 0 count arr.size currentSum += arr[i] end return currentSum end
Now an example using more dimensions. If executed, the example code will print the following to the console:
[[321.5, -42.51] [32422, -512]] [[1, 2, 3] [12, 24, 36] [75, 50, 25]]
procedure test() var matrix : [2][2] single matrix[0][0] = 321.5 matrix[0][1] = -42.51 matrix[1][0] = 32422 matrix[1][1] = -512 printMatrix(matrix) var matrix2 : [3][3] single matrix2[0][0] = 1 matrix2[0][1] = 2 matrix2[0][2] = 3 matrix2[1][0] = 12 matrix2[1][1] = 24 matrix2[1][2] = 36 matrix2[2][0] = 75 matrix2[2][1] = 50 matrix2[2][2] = 25 printMatrix(matrix2) end procedure printMatrix(m : [ , ] single) system.out.print("[") iterate y : int from 0 count m.size0 system.out.print("[") iterate x : int from 0 count m.size1 if x > 0 then system.out.print(", ") end system.out.print(m[y, x]) end if y = m.size0 - 1 then system.out.printLn("]]") else system.out.printLn("]") end end end
The following example shows the use of open arrays in variables. The 'matrix' which is used here is in fact not a two-dimensional array, but a one-dimensional array of pointers to one-dimensional arrays. This makes it easy to swap two rows in the matrix, as is shown below.
procedure swapMatrixRows(inout m : [] * [] const int, row1_index & row2_index : nat) var temp : * [] int = m[row1_index] m[row1_index] =$ m[row2_index] m[row2_index] =$ temp end