[Swift-devel] playing with array closing.

Ben Clifford benc at hawaga.org.uk
Tue Nov 20 00:04:59 CST 2007


I spent some time at the weekend and today playing with 'the array closing 
problem'.

The array-closing problem is what happens when we combine 
single-assignment semantics (which say that you will only write a=foo; 
once for each variable a) with our array assignment semantics (which say 
that arrays are populated by multiple assignments, a[0]=foo; a[1]=bar;).

Below, exhibit A, is a program which does not work in the present 
trunk implementation - instead it hangs after executing 
top-level statements R,S,T and before executing statement W.

Statement W will not be executed until the array name 'array' is closed, 
that is, until it is known that there are no further writes to the array.

So I prototyped some compile-time dataflow analysis (a bit like the 
present input marking code that already exists) to see that statements 
R,S,T write (or potentially write to) 'array' and that no other statements 
do.

Armed with this knowledge, the compiled karajan code is modified so that:
 i) when datasets are created (using vdl:new) they are labelled with a 
list of statements that may write to them.
 ii) those statements are modified so that they notify the appropriate 
datasets when they have finished.

So each statement issues a partial close on the datasets it writes to, and 
each dataset is aware which partial closes to expect.

When a dataset has received partial closes (at runtime) from everything it 
is expecting (which is determined at compile time), it becomes fully 
closed.

In the example code, that means that statement W's dependency on the array 
being closed is now satisfied, and so it is executed, and so this workflow 
ends.

Its not so straightforward - for example, statement U writes to the array 
several times, and we don't want the first write to do the corresponding 
partial close. So the above processing happens only for statements in the 
same scope as the declaration. In the case of sub-scopes, such as inside a 
foreach, partial closes don't happen, but the enclosing statement (foreach 
in the example below) are treated as a single statement which completes 
and closes only when the whole loop is finished.

I think this is the right approach to pursue for this problem.

Also, I think that this implementation could join up with the present 
dataset marking code (which is used to determine what is an input and what 
is not), and also be used for better compile time type checking and 
related things (eg. checking for variables declared multiple times, 
variables assigned to multiple times when they shouldn't be, ...)

==== EXHIBIT A, being a program which does not work in the present trunk 
implementation ====
type file;

(file f) writefile(int s) {
  app {
    echo s stdout=@f;
  }
}


(file f) listvals(file array[]) {
  app {
    echo @filenames(array) stdout=@f;
  }
}

file array[];                    (Q)

array[0]=writefile(99999);       (R)
array[1]=writefile(10000);       (S)

foreach i in [2:5] {             (T)
  array[i]=writefile(i+80);      (U)
}

file out <"out">;                (V)

out = listvals(array);           (W)





More information about the Swift-devel mailing list