<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 23, 2017 at 11:05 PM, Daryle Walker <span dir="ltr">&lt;<a href="mailto:darylew@mac.com" target="_blank">darylew@mac.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br><div style="word-wrap:break-word"><br><br><div style="word-wrap:break-word"><span class=""><blockquote type="cite"><div>On Jul 23, 2017, at 12:04 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank">kelvin13ma@gmail.com</a>&gt; wrote:</div><br class="m_-1054338649092305081Apple-interchange-newline"><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 23, 2017 at 3:08 AM, Daryle Walker <span dir="ltr">&lt;<a href="mailto:darylew@mac.com" target="_blank">darylew@mac.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><span class="m_-1054338649092305081gmail-"><div><br></div><blockquote type="cite"><div><div dir="ltr"><div>9. I don’t see the value in having both nested FSAs and multi-dimensional FSAs. Aren’t they the same thing? For example, in the code snippet<br></div></div></div></blockquote><div><br></div></span><div>Why does any language with multi-dimensional arrays (like Fortran or Ada) have them? By this standard, no language should have multi-dimensional arrays. They exist because of data modeling. Co-equal coordinates in the model should be co-equal in their representation in the program. Yes, they are implemented the same way underneath. We don’t copy C everywhere, so why not take this opportunity to do better. Also, just using nesting could imply that the intermediate array types have a meaning, but they might not if they’re just implementation quirks and not part of the abstract model.</div><div><br></div><div>Nested arrays are not my solution for multi-coordinate indexing; use multi-dimensional arrays for that. I mention nested arrays because:</div><div><br></div><div><ul class="m_-1054338649092305081gmail-m_-2788489614445174710MailOutline"><li>Nested arrays fundamentally cannot be banned. (What if an element type is hidden behind a type-alias and is conditionally an array type?)</li></ul></div></div></div></blockquote><div>Doesn’t Swift have to resolve the types at some point anyway? If it’s impossible to ban, we can allow it, but still make it unidiomatic. Nested arrays are much messier to write than multidimensional arrays.<br></div></div></div></div></div></blockquote><div><br></div></span><div>The new draft I’m writing downplays nested arrays a lot. They’re mentioned in the section discussing the core element type (nee the inner non-array type).</div><div><div class="h5"><div><br></div><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div><div><ul class="m_-1054338649092305081gmail-m_-2788489614445174710MailOutline"><li>I need the definition to explain the “inner non-array type”</li><ul><li>I need the inner non-array type to explain which pairings of FSAs for reshaping are legal. (And a similar reason for tuple conversion.) Note the two types can have different nesting levels.</li></ul><li>I need to explain that empty arrays cannot be an array element type. (Should this be changed? What happens with tuples or structures containing empty tuples/structures as members? What about empty tuples/sturctures in “Array”? Banning empty arrays means we don’t have to worry about every array element being at the same address. The other way to solve this is to make them one byte (or word) long.)</li></ul></div><span class="m_-1054338649092305081gmail-"><div><br></div><blockquote type="cite"><div><div dir="ltr"><div><span style="font-family:monospace,monospace">```<br>let a = [;1, 2, 3, 4]<br>assert(a[0] == 1)<br>assert(a[1] == 2)<br>assert(a[2] == 3)<br>assert(a[3] == 4)<br>let b = a as [2, 2; Int]<br>assert(b[0, 0] == 1)<br>assert(b[0, 1] == 2)<br>assert(b[1, 0] == 3)<br>assert(b[1, 1] == 4)<br>let c = a as [2; [2; Int]]<br>assert(c[0][0] == 1)<br>assert(c[0][1] == 2)<br>assert(c[1][0] == 3)<br>assert(c[1][1] == 4)<br>```</span><br><br></div><div>There’s three syntaxes which accomplish two unique things. I lean towards disallowing FSA nesting and instead allowing <i>incomplete</i> index lists to partially unnest multidimensional FSAs. Let’s reserve “<span style="font-family:monospace,monospace">[][][]...</span>” for flexible array chained dereferencing.<br></div></div></div></blockquote><div><br></div></span><div>I don’t understand what your incomplete index list idea is. And as I said, the chaining technique is less I desire it and more I can’t ban it and keep Swift features orthogonal.</div></div></div></blockquote><div><br></div><div>Incomplete indexing means <br><br></div><div><span style="font-family:monospace,monospace">let fsa:[5, 2; Int] = [5, 2; 2, 4, 3, 5, 4, 6, 5, 7, 6, 8]<br></span></div><div><span style="font-family:monospace,monospace">fsa[3] // [2; 5, 7]<br><br></span></div><div><span style="font-family:arial,helvetica,sans-serif">this would be the same as writing </span><span style="font-family:monospace,monospace"><br></span><br><div><span style="font-family:monospace,monospace">let fsa:[5; [2; Int]] = [5; [2; 2, 4], </span><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">[2; </span>3, 5], </span><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">[2; </span>4, 6], </span><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">[2; </span>5, 7], </span><span style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">[2; </span>6, 8]]<br></span></div><span style="font-family:monospace,monospace">fsa[3] // [2; 5, 7]</span></div><div> <br></div><div>in your current system. This would obviate the need to nest FSAs for the purpose of extracting entire rows of data.<br></div></div></div></div></div></blockquote><div><br></div></div></div><div>Allowing partial indexing as you show it privileges one dimension over the others, although they’re supposed to be co-equal and the reason a particular dimension is privileged is due to an implementation detail. Or would you allow incomplete indexing on other dimensions besides the first? Where the true-multi-dimensional &lt;-&gt; nested FSA equivalence wouldn’t help you (because the elements are dispersed in the whole array). With complete generics, this could be a library function:</div><div><br></div><div>func removeRow&lt;Dimension: Int, M…: Int, N…: Int, P: Int, T&gt;(array: […M, P, …N; T], row: Int) -&gt; […M, …N; T] where #lengthof(M) == Dimension</div><span class=""></span><div><br></div></div><span class=""></span></div></blockquote></div><br></div><div class="gmail_extra">I’m confused as to what the goals of FSAs are here. My understanding is that they are supposed to be a very low-level high-performance type that’s closely linked with the underlying memory representation. That’s why memory order initialization and flattened indexing is allowed, isn’t it? Partial indexing privileges one dimension over the others, precisely because one dimension <i>should</i> be privileged over the others, because it is much faster than a column slice. The partial indexing syntax is good because it emphasizes that this is an inherently <i>fast</i> operation. Whereas arbitrary row extraction should be a special function to emphasize that it is an inherently <i>slow</i> operation.<br></div></div>