The Hyper Programming Language

Open Arrays

General

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.

Declaring open arrays

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).

Arrays in expressions

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.

Examples

This is a generalization of the 'sum 5 items' example from the page about arrays in general:

procedure p()
  var list : [5int

  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][2single

  matrix[0][0] = 321.5
  matrix[0][1] = -42.51
  matrix[1][0] = 32422
  matrix[1][1] = -512

  printMatrix(matrix)

  var matrix2 : [3][3single

  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

See also


Valid HTML 4.01 Strict Valid CSS!