ZPL is an evolving language. As such, there are a number of changes that have taken place since the publication of the User's Guide and the last binary release. This page summarizes these changes.
Procedures Overloading
Procedures can now be overloaded on the type and number of their arguments. Ambiguities are not allowed by the compiler.
User-Defined Reductions
Reductions are no longer limited to the nine built-in operators. See this page for more details.
Improved Halt Statements
Halt statements can now optionally take an argument list that is interpreted identically to a write/writeln statement so that the reason that a halt was reached can be printed out. This is only guaranteed to work with scalar expressions.
Rank Change
Assignment between arrays of different rank is now possible using the remap operator (formerly gather/scatter). See below.
First-Class Directions and Regions
ZPl now supports declaring directions and regions using normal constant and variable declaration syntax rather than the "direction" and "region" keywords. Support for changing directions and regions is not yet available. Reference page coming.
Unconstrained Variables
Initial support for unconstrained variables, scalar variables that can have different values on different processors, has been added. Reference page coming.
Grids and Distributions
Language-level support for processor sets (grids) and distributions has been initiated. Reference page coming.
New Timers
A new, richer timer interface now exists. For convenience, the old timers are still supported. Reference page coming.
Little "indexi" Variables
These are similar to the Indexi variables available for parallel arrays. Thus, given a declaration like:
var x: array [1..2, 1..3] of array [1..4] of double;
The following indices can be used:
index1[1]
for the 1..2 dimensionindex1[2]
for the 1..3 dimensionindex2[1]
for the 1..4 dimensionindex2
for the 1..4 dimension (arrays with a single
dimension may elide the subscript)Anonymous Direction Literals
Inlined directions are now legal everywhere named directions are.
Character Concatenation
A character can be concatenated to a string via
+=
assignment.
Gather/Scatter Syntax Change
The old and poorly designed gather/scatter operators (<## and >##) have been replaced with a single remap operator (#) that can be applied to the right- or left-hand side of an expression. Thus, a scatter transpose would now be written:
[R] A#[Index2, Index1] := B;
While a gather transpose would be written:
[R] A := B#[Index2, Index1];
No Implicit Storage
Arrays no longer have implicit storage allocated for them. Thus, code like:
var A: [R] float; [east of R] wrap A;
no longer extends A's storage to include the east boundary. The user must now extend A's storage explicitly. This is to simplify the language and make it more comprehensible and implementable.
@ and # Usage
The location of where the @ operator should be placed in an expression has moved. It used to be placed directly next to the parallel array part of the expression, but now must be placed after all indexed array references and field accesses. Thus, in the old scheme, given:
var X: [R] array [1..3] of record x, y: float; end; var Y: array [1..3] of [R] record x, y: float; end; var Z: array [1..3] of record x, y: [R] float; end;
users would write:
... X@dir[1].x ...; ... Y[1]@dir.x ...; ... Z[1].x@dir ...;
Now, they would write:
... X[1].x@dir ...; ... Y[1].x@dir ...; ... Z[1].x@dir ...;
The reasons for this are esoteric and not worth discussing here.
No Multi-Directions, Multi-Regions, Multi-Arrays
Multi-directions, -regions, and -arrays are now gone from the language. Added the ability to declare arrays of directions, regions, and arrays which accomplishes the same task. Thus, where one might have once, regrettably, declared:
region R{0..nl} = [1..n, 1..n] by 2^{};
they would now write:
var R: array [0..nl] of region = [1..n, 1..n] by 2^index1;
No Multiple Active Regions
There used to be a separate region stack for each rank of region, but now there is a single region stack. Period. Thus, while:
region R1 = [1..n]; region R2 = [1..n, 1..n]; var A1: [R1] float; var A2: [R2] float; [R1] begin [R2] begin A1 := 0.0; A2 := 0.0; end; end;
used to be legal (because R1 would be the top of the 1D region stack and R2 would be the top of the 2D region stack), it no longer would be. In the new interpretation, the region stack would have R2 at the top, eclipsing R1, making the assignment to A1 illegal (since the current region is 2D rather than the 1D region it requires).
Procedure Blocks
Procedure bodies now require a begin and an end, but a region can still be prepended to the first begin.
Exponentiation Precedence
The precedence of exponentiation, with respect to unary
plus/minus, has increased. Thus while -2^2
used to be 4
, it is now -4
.
Config Const
Config Vars can now be changed. A new addition, config consts, cannot be changed and have the old behavior of config vars. This change makes vars and consts more orthogonal to the notion of config.