for i in array_liml(X), array_limh(X) cross j in array_liml(X[i]), array_limh(X[i]) q := deep_thought(x, i, j) returns array of q end forThis sort of thing can be very useful when dealing with ragged arrays. For instance, the situation often develops in the modeling of physical systems that a system array with unchanging boundaries must be evolved and returned with the original boundaries. In the following example, we will use the Sisal operator for array concatenation, "||".
let new_core := evolve(system_array); % new system with no boundaries top_indx := array_liml(system_array); % positions of top and bottom btm_indx := array_limh(system_array); % boundaries from old system new_top := system_array[top_indx]; % actual top boundary new_btm := system_array[btm_indx]; % actual bottom boundary left_indx := array_liml(system_array[1]); % positions of left and right right_indx := array_limh(system_array[1]); % boundaries from old system % (all rows have same indices) long_core := for row in core at i % add side boundaries to all rows left_bound_elt := system_array[ i, left_indx ]; left_bound_array := array [ 1: left_bound_elt ]; right_bound_elt := system_array[ i, right_indx ]; right_bound_array := array [ 1: right_bound_elt ] returns array of left_bound_array || row || right_bound_array end for; long_tall := new_top || long_core || new_btm % add top and bottom in long_tall % The newly evolved system, complete with boundaries. end letThis elegant bit of code builds a new system array in three steps. First, function "evolve" is invoked with the old system array as its argument, and the new system array is returned. Then the short rows of the new array are made the correct length by concatenating the boundaries from the rows of the old system array onto them in a for-loop. In the loop we see that the values left_bound_elt and right_bound_elt are made into arrays of one element. This is necessary, as the concatenation operator requires that both its arguments be arrays. Finally, the top and bottom rows of the old system array are concatenated onto the widened core of the new system array. The result of these steps is an array the same size and shape as the old system array.
This example also includes a use of the hybrid range generator "row in core at i". Use of this form of generator relieves us of the need to specify the index range of the array core, and yet still gives us an index value to use in the array index expressions within the loop.
These techniques are so powerful and useful that we will explore them further in an exercise.