<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 23, 2017, at 12:04 PM, Taylor Swift <<a href="mailto:kelvin13ma@gmail.com" class="">kelvin13ma@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sun, Jul 23, 2017 at 3:08 AM, Daryle Walker <span dir="ltr" class=""><<a href="mailto:darylew@mac.com" target="_blank" class="">darylew@mac.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;" class=""><div class=""><span class="gmail-"><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">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 class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">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 class=""><br class=""></div><div class="">Nested arrays are not my solution for multi-coordinate indexing; use multi-dimensional arrays for that. I mention nested arrays because:</div><div class=""><br class=""></div><div class=""><ul class="gmail-m_-2788489614445174710MailOutline"><li class="">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 class="">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 class=""></div></div></div></div></div></blockquote><div><br class=""></div><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><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><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 style="overflow-wrap: break-word;" class=""><div class=""><div class=""><ul class="gmail-m_-2788489614445174710MailOutline"><li class="">I need the definition to explain the “inner non-array type”</li><ul class=""><li class="">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 class="">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="gmail-"><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><span style="font-family:monospace,monospace" class="">```<br class="">let a = [;1, 2, 3, 4]<br class="">assert(a[0] == 1)<br class="">assert(a[1] == 2)<br class="">assert(a[2] == 3)<br class="">assert(a[3] == 4)<br class="">let b = a as [2, 2; Int]<br class="">assert(b[0, 0] == 1)<br class="">assert(b[0, 1] == 2)<br class="">assert(b[1, 0] == 3)<br class="">assert(b[1, 1] == 4)<br class="">let c = a as [2; [2; Int]]<br class="">assert(c[0][0] == 1)<br class="">assert(c[0][1] == 2)<br class="">assert(c[1][0] == 3)<br class="">assert(c[1][1] == 4)<br class="">```</span><br class=""><br class=""></div><div class="">There’s three syntaxes which accomplish two unique things. I lean towards disallowing FSA nesting and instead allowing <i class="">incomplete</i> index lists to partially unnest multidimensional FSAs. Let’s reserve “<span style="font-family:monospace,monospace" class="">[][][]...</span>” for flexible array chained dereferencing.<br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">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 class=""><br class=""></div><div class="">Incomplete indexing means <br class=""><br class=""></div><div class=""><span style="font-family:monospace,monospace" class="">let fsa:[5, 2; Int] = [5, 2; 2, 4, 3, 5, 4, 6, 5, 7, 6, 8]<br class=""></span></div><div class=""><span style="font-family:monospace,monospace" class="">fsa[3] // [2; 5, 7]<br class=""><br class=""></span></div><div class=""><span style="font-family:arial,helvetica,sans-serif" class="">this would be the same as writing </span><span style="font-family:monospace,monospace" class=""><br class=""></span><br class=""><div class=""><span style="font-family:monospace,monospace" class="">let fsa:[5; [2; Int]] = [5; [2; 2, 4], </span><span style="font-family:monospace,monospace" class=""><span style="font-family:monospace,monospace" class="">[2; </span>3, 5], </span><span style="font-family:monospace,monospace" class=""><span style="font-family:monospace,monospace" class="">[2; </span>4, 6], </span><span style="font-family:monospace,monospace" class=""><span style="font-family:monospace,monospace" class="">[2; </span>5, 7], </span><span style="font-family:monospace,monospace" class=""><span style="font-family:monospace,monospace" class="">[2; </span>6, 8]]<br class=""></span></div><span style="font-family:monospace,monospace" class="">fsa[3] // [2; 5, 7]</span></div><div class=""> <br class=""></div><div class="">in your current system. This would obviate the need to nest FSAs for the purpose of extracting entire rows of data.<br class=""></div></div></div></div></div></blockquote><div><br class=""></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 <-> 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 class=""></div><div>func removeRow<Dimension: Int, M…: Int, N…: Int, P: Int, T>(array: […M, P, …N; T], row: Int) -> […M, …N; T] where #lengthof(M) == Dimension</div><div><br class=""></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><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 style="overflow-wrap: break-word;" class=""><div class=""><span class="gmail-"><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">11. This should have defined behavior:</div></div></div></blockquote></span><span class="gmail-"><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><span style="font-family:monospace,monospace" class=""><br class="">let data = [2, 2; 1, 2, 4, 8]<br class="">for (i, x) in data.enumerated()<br class="">{<br class=""> total += x<br class="">}</span><br class=""></div></div></div></blockquote><div class=""><br class=""></div></span><div class="">FSAs are compound types, not named types, so there are no methods. (Just like tuples, FSAs don’t follow any protocols.) But since they’re a built-in, I can customize the “for-in” loop to cover all the elements in an implementation-optimized order. (The implementation has the option of multi-threading if it can see there’s no cross-iteration contamination.) Since you can’t control the order without manual looping, the “#indexOf” expression exists to let you know where you are during an iteration loop.</div><div class=""><br class=""></div><div class="">I first used the iteration variable as the operand to “#indexOf” to determine which array instance to track. Then I saw that the for-loop implements its iteration variable as a pattern in the grammar instead of something simpler. And what happens if a wildcard is used as the iteration variable? And would people question why when the pattern has multiple iteration variables, all are equally valid for “#indexOf”? I moved the operand to be the label because we usually don’t have multiple labels on statements (Is that even legal in Swift?) and can optimize which loops need to be indexable.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I really dislike the addition of magical builtin variables. Iterating through a FSA should just take the FSA down one dimension level, so<br class=""><br class=""><span class="gmail-"><span style="font-family:monospace,monospace" class="">let data = [2, 3; 1, 2, 3, 4, 8, 12]<br class="">for x:[3;] in data<br class="">{<br class=""> total += x[0] + x[1] + x[2]<br class="">}<span class=""><br class=""><br class=""></span></span></span></div><div class=""><span class="gmail-"><span style="font-family:arial,helvetica,sans-serif" class=""><span class="">would be the pattern.</span></span><span style="font-family:monospace,monospace" class=""><span class=""><br class=""></span></span></span></div></div></div></div></div></blockquote><div><br class=""></div><div>I’m assuming that automatic incomplete indexing would happen here, instead of a flat loop.</div><div><br class=""></div><div>The point of the flat for-loop is to eliminate the drudgery of nesting per-dimension for-loops (and re-editing whenever a dimension value or the dimension count changes) and to let the implementation optimize traversal (especially if a processor vector type is used).</div><div><br class=""></div></div><div class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">— </div><div class="">Daryle Walker<br class="">Mac, Internet, and Video Game Junkie<br class="">darylew AT mac DOT com </div><div class=""><br class=""></div></div></div></div></body></html>