[Swift-devel] Re: [Swift-user] assigning file variables

Ben Clifford benc at hawaga.org.uk
Thu Feb 26 05:34:55 CST 2009


On Thu, 26 Feb 2009, Michael Wilde wrote:

> foreach p, pn in protein {                                                      
>  file result[][]                                                               
>    <simple_mapper; prefix=@strcat("output/",p,"/"),suffix=".pdt">;             
>  iterate i {                                                                   
>    result[i] = doRound(p,i);                                                   
>  } until (roundDone(result[i],pn) == 1);                                       
> }                                                                               
                                                                                
> But, that test was over-simplified, because it didnt handle the fact 
> that these returns are really 6-file structs, which motivated me to try 
> ext mapper.

Assuming the above is working, what breaks when you change file into a 
6-member struct?

> - ext-mapper cant pre-map a dynamic output structure with any dimensions whose
> size cant be passed to the mapper (I think?)

yes.

> - arrays can only be closed via return from functions

no. Not since r1536 | benc at CI.UCHICAGO.EDU | 2008-01-03

Since that commit, there is static analysis of source code, and when no 
more assignments are left to make to an array, its regarded as closed.

However, in the case of multidimensional arrays, this only happens when 
the entire top level array has no more assignments at all, not as each 
subarray happens to become finished.

Static analysis of arrays (and even runtime analysis to discover when no 
more assignments may happen to a particular piece) is extremely hard 
because you're allowed to construct your own indicies, and you're allowed 
to use them in a way that isn't single assignment; I think they're a 
fairly poor structure to have in SwiftScript the way its going.

For example, in the code fragment:

>  file result[][]                                                             
>    <simple_mapper; prefix=@strcat("output/",p,"/"),suffix=".pdt">;           
>  iterate i {                                                                 
>    result[i] = doRound(p,i);                                                 
>  } until (roundDone(result[i],pn) == 1);

You can look at that and reason that result[i] won't get assigned any more 
after the iterate statement for that i, but in general that i can be any 
expression. In the general case, how do you know that result[2] will never 
get any more assignments?

There are other ways of doing things, for example Haskell's map, fold and 
unfold, that I think would be much easier to analyse in this case.

(hey I get to mention map/reduce here!)

foreach in that case could look like this map (making up ugly syntax)
with syntax:  output =  map (range) (code)

   file results[] = map proteins (p -> { analyse(p); return p})

This means the same as:

file results[];
foreach p,i in results {
  results[i] = analyse(p);
}

What is different is there is now only a single assignment to results. The 
idea of "array closing" collapses down to "has a single assignment been 
made?"

Iterate would look more like an unfoldr:

output = unfold seed step terminateCondition

file results[] = unfold initalStep (\prev -> { evaluate(prev); return prev}

Again, you know when results is fully assigned, because there is now only 
a single statement assigning to it.

In addition, in both of these, you know exactly when a member of the array 
has been assigned - for any element of results, in both the map and unfold 
case, there is exactly one 'iteration' of the map or unfold which can 
assign to that element, and that is easily known to Swift because it knows 
how map/unfold work.

These should be nestable, and in the case of a multidimensional array, you 
known when any particular sub-array has been assigned, because you know 
which iteration of the outer map/unfold generates that value.

> - files and structs with files have limitations on assignments

yes.

Its easy to implement struct assignment, for structs where the members 
have defined assignment semantics already.

for files, see other thread.

> - I cant set a mapping any time I want on any member (field or element) of any
> structure.

Yes.

> Here's a related question: Is it the case that if a function returns an array,
> that array *must* be declared and mapped in the calling function, *not* in the
> called function?  Eg, I cant dynamically declare and map an array *within* a
> function and return that array out? (I'll try this in the morning).

By function, you mean procedure, I think (code referenced without a @ 
prefix). In that case, yes - procedure call semantics are that you pass in 
where the output belongs.

> This makes me more determined to re-open the discussion on the nature of 
> object, variables, handles, scope, and lifetime, as it seems to me that 
> part of the problem comes from an object model thats almost, but not 
> quite, as regular as it should be.

yes, its riddled with prototypiness from before; mostly from 
imperativeness conflicting with data flow dependencies. Its substantially 
more consistent than it was a few years ago, though.

-- 



More information about the Swift-devel mailing list