Hi Ben,<br><div style="text-align: left;"> the way you describe it makes a lot more sense to me (I've spent the last couple of months teaching Haskell to undergrads so have been in that mindframe a lot). I was trying to reverse engineer the semantics from the actual behaviour of the implementation. Am I correct then in thinking that mixing array-wise and cell-wise assignment for the same element like below is invalid (or at least not an intended use case for swift)?<br>
<br></div>int a[][];<br>a[0] = b;<br>a[0][1] = 2<br><br>In the 1d array case swift sometimes seems ok with mixing the two, but sometimes is unhappy.<br>----------<br>int a[];<br>a[2] = 1;<br>a = f();<br><br>
(int r[]) f () {<br>
r[0] = 1;<br>
r[1] = 2;<br>
}<br><br>"Compile error in procedure invocation at line 5: variable a has multiple writers"<br>-----<br>but the following compiles and runs fine:<br><br>int a[];<br>a = f();<br>a[2] = 1;<br><br>- Tim<br><br><div class="gmail_quote">
On Fri, Nov 18, 2011 at 3:52 AM, Ben Clifford <span dir="ltr"><<a href="mailto:benc@hawaga.org.uk">benc@hawaga.org.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
The below is based on my gut feeling for how things *should* work, at least assuming the existence of array assignment syntax, not how the implementation does work.<br>
<br>
Remember this is a declarative language. So then:<br>
<div class="im"><br>
> I initially assumed that 2d arrays were effectively arrays of references to arrays, so that the semantics would be as follows:<br>
><br>
> int a[][];<br>
> int b[];<br>
><br>
> a[0] = b; // Pointer to b in first slot of array a<br>
> a[0][1] = 2; // insert into b<br>
<br>
</div>First you say "the value of a[0] is fully described by b" and then secondly you say "the value of a[0] is partially described by the statement 'element [1] is 2'". Those are contradictory statements.<br>
<br>
Maybe it would be ok to say:<br>
<br>
a[0]=b<br>
b[1]=2<br>
<br>
If you're using verbs like "insert" it suggests you haven't smoked enough swift-crack and are still thinking too imperatively...<br>
<div class="im"><br>
> a[1][1] = 2; // invalid because no array inserted into a[1]<br>
<br>
</div>One interpretation of this working is that declaring an array int a[][] means that you have a structure that is indexed by pairs of co-ordinates, rather than a structure indexed by one co-ordinate containing a bunch of other structures indexed by the other co-ordinate.<br>
<br>
So if you have tuple syntax (x,y) then you are really writing:<br>
<br>
a[(1,1)] = 2<br>
<br>
which is fine, just like a[(0,1)] = 2 is.<br>
<br>
But in that view, what does a[0] means? something like a[(0,?)] ? mostly I think it would mean "select the subset of values that have left co-ordinate 0": if you're using it for extracting a value, you get a 1d array out of it. If you're using it for setting values, then:<br>
<br>
a[0] = b<br>
<br>
would be something like:<br>
<br>
foreach i in b { a[0][i] = b[i]; }<br>
<br>
<br>
Whether this is implemented by copying a pointer to b or by copying individual values shouldn't affect the end result, as long as its implemented properly, and as long as you don't write invalid programs which are awkward to detect.<br>
<br>
In my opinion, your program below is invalid, because you are making two contradictory declarations of the value of a[0] - on that its entire value is determined by b, and another that one of its values is 30.<br>
<br>
If the above model is how things should work, then really you should get a runtime error when trying to do this:<br>
<div class="im"><br>
> a[0][3] = 30;<br>
> a[0] = b;<br>
<br>
</div>and non-deterministic outcome 2 below is incorrect.<br>
<br>
but that this:<br>
<div class="im"><br>
<br>
> a[1][0] = 123;<br>
<br>
</div>should work just fine - there is no concept of "declaring" a[1] to exist separate from using it.<br>
<br>
A slightly different way for this to work would be for a[0] = b to explicitly be a copy of b elements into a[0], which *would* allow you to assign other entries to other a[0][x] positions, as long as they did not conflict with elements that came from b. (the usual "can't assign an element twice" rule). But maybe that would be less efficient to implement.<br>
<br>
Sorry that the above sounds rather disconnected from implementation and abstract - but you are asking about abstract semantics ;) Feel free to demand I explain my views more...<br>
<br>
Ben<br>
<div><div class="h5"><br>
><br>
> But a[1][1] = 2 actually succeeds. As far as I can work out, what actually happens is:<br>
> • A[i][j] = x;<br>
> • A[i] is uninitialised, a new array C is created, and x assigned to C[j]<br>
> • A[i] is initialised with array C, x is assigned to C[j]<br>
> • A[i] = B;<br>
> • A[i] is uninitialised, A[i] is then a reference to B<br>
> • A[i] is initialised and points to array C, all members of B are copied to the corresponding index in C<br>
> Is this the intended behaviour? Am I understanding this correctly?<br>
><br>
> In the swift implementation I tested it on, this leads to some nondeterminism:<br>
><br>
> int a[][];<br>
> int b[] = [1,2,3];<br>
><br>
> a[0][3] = 30;<br>
> a[0] = b;<br>
> a[1][0] = 123;<br>
><br>
> trace(a[0][0]);<br>
> trace(a[0][3]);<br>
> trace(a[1][0]);<br>
><br>
><br>
> Nondetermistic outcome 1<br>
> ====================<br>
> SwiftScript trace: 1<br>
> SwiftScript trace: 123<br>
> Execution failed:<br>
> Invalid path ([3]) for a.[0][]/3<br>
><br>
> Nondetermistic outcome 2<br>
> ====================<br>
> SwiftScript trace: 1<br>
> SwiftScript trace: 30<br>
> SwiftScript trace: 123<br>
><br>
> - Tim<br>
</div></div>> _______________________________________________<br>
> Swift-devel mailing list<br>
> <a href="mailto:Swift-devel@ci.uchicago.edu">Swift-devel@ci.uchicago.edu</a><br>
> <a href="https://lists.ci.uchicago.edu/cgi-bin/mailman/listinfo/swift-devel" target="_blank">https://lists.ci.uchicago.edu/cgi-bin/mailman/listinfo/swift-devel</a><br>
<br>
</blockquote></div><br>