<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 11:20 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" class="">kelvin13ma@gmail.com</a>&gt; wrote:</div><div class=""><div class="gmail_extra" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><div class="gmail_quote">On Sun, Jul 23, 2017 at 11:05 PM, Daryle Walker<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:darylew@mac.com" target="_blank" class="">darylew@mac.com</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"><br class=""><div style="word-wrap: break-word;" class=""><div style="word-wrap: break-word;" class=""><span class=""><blockquote type="cite" class=""><div class="">On Jul 23, 2017, at 12:04 PM, Taylor Swift &lt;<a href="mailto:kelvin13ma@gmail.com" target="_blank" class="">kelvin13ma@gmail.com</a>&gt; wrote:</div></blockquote></span><div class=""><div class="h5"><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Incomplete indexing means<span class="Apple-converted-space">&nbsp;</span><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 class="Apple-converted-space">&nbsp;</span></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 class="Apple-converted-space">&nbsp;</span></span><span style="font-family: monospace, monospace;" class=""><span style="font-family: monospace, monospace;" class="">[2;<span class="Apple-converted-space">&nbsp;</span></span>3, 5],<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: monospace, monospace;" class=""><span style="font-family: monospace, monospace;" class="">[2;<span class="Apple-converted-space">&nbsp;</span></span>4, 6],<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: monospace, monospace;" class=""><span style="font-family: monospace, monospace;" class="">[2;<span class="Apple-converted-space">&nbsp;</span></span>5, 7],<span class="Apple-converted-space">&nbsp;</span></span><span style="font-family: monospace, monospace;" class=""><span style="font-family: monospace, monospace;" class="">[2;<span class="Apple-converted-space">&nbsp;</span></span>6, 8]]<br class=""></span></div><span style="font-family: monospace, monospace;" class="">fsa[3] // [2; 5, 7]</span></div><div class="">&nbsp;<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 class=""><br class=""></div></div></div><div class="">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 class=""><br class=""></div><div class="">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 class=""><br class=""></div></div><span class=""></span></div></blockquote></div><br class=""></div><div class="gmail_extra" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">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<span class="Apple-converted-space">&nbsp;</span><i class="">should</i><span class="Apple-converted-space">&nbsp;</span>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<span class="Apple-converted-space">&nbsp;</span><i class="">fast</i><span class="Apple-converted-space">&nbsp;</span>operation. Whereas arbitrary row extraction should be a special function to emphasize that it is an inherently<span class="Apple-converted-space">&nbsp;</span><i class="">slow</i><span class="Apple-converted-space">&nbsp;</span>operation.</div></div></blockquote></div><br class=""><div class="">My vision of FSAs is as a low-ish mid-level type, not a low-level type and definitely not a very-low-level type. Yes, use as implementing parts of an abstract data type is a goal, otherwise why not stick with Array. And performance is a goal. But FSAs should be usable outside of that. That’s one reason my FSAs support multiple dimensions; it’s the opposite of K&amp;R’s decision throwing out multiple dimensions in the original C when its contemporaries had them.</div><div class=""><br class=""></div><div class="">[Another reason for default support for multiple dimensions is that I don’t know if any processor vector-unit types model 2D arrays, or if all are 1D vectors. Limiting FSAs to one dimension means there’s no easy way to model 2D vector-type arrays. Using FSAs to bring processor vector-unit types to the user level is a core goal.]</div><div class=""><br class=""></div><div class="">Memory-order initialization for multi-dimensional arrays when not using explicit indexes is to save on needing to type out said indexes. And to help inform what elements are which when using static indexing. (Static indexing is flattened because my first attempt at making a multi-coordinate version of tuple’s anonymous member access looked dumb.)</div><div class=""><br class=""></div><div class="">By flattened indexing, do you mean the "withUnsafe*Flattening” functions? Those give the users a way to access the array as a collection. And it’s a way to handle functions that want an array of a particular element type, but for any length/shape, an adaptation of the “T[]” parameter type in C functions. The “T[]” parameter type let C programmers write a function for any array segment length, without specializations for “T[1],” “T[2],” “T[3],” and so on. (You have to pass the actual length separately.) This was before C++ templates and allowing function specializations per array length, but using the “T[]” saves on how many specializations are needed (just one instead of per array length used).</div><div class=""><br class=""></div><div class="">If you mean the “for-in” loop, the flattening is meant to be an abstraction. The C-style for loop was removed because we now abstract the iteration over collections so you don’t have to manually maintain an iteration counter. The flat for-loop removes having to manually write loop statements per dimension. If you don’t need the iterator-counter/iteration-coordinate, skipping the need to write the counter(s) anyway is a big savings. The new problem is what to do when you do want the iteration counter(s). For collections, use the “enumerated” method, which just returns a new sequence that is a pair of the original element and the would-have-been iteration counter. For FSAs, since iteration order is unspecified and copying to a bigger array is impractical, I use a new primary expression to get the counter.</div><div class=""><br class=""></div><div class="">To have partial indexing, and keep it only to the first (i.e. outermost) dimension, we can add a new set of global functions:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">func&nbsp;withUnsafePartialIndexing&lt;T,&nbsp;Result, M: Int, N…: Int&gt;(of&nbsp;arg:&nbsp;inout&nbsp;[M, …N; T],&nbsp;_&nbsp;body: (UnsafeBufferPointer&lt;[…N; T]&gt;)&nbsp;throws&nbsp;-&gt;&nbsp;Result)&nbsp;rethrows&nbsp;-&gt;&nbsp;Result</font></div></blockquote><div class=""><br class=""></div><div class="">both mutable and immutable. Or maybe add a variant to target a specific row:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">func withExtraction&lt;T, Result, M: Int, N…: Int&gt;(ofRow row: Int, from arg: inout [M, …N; T], body: ([…N; T]) throws -&gt; Result) rethrows -&gt; Result</font></div></blockquote><div class=""><br class=""></div><div class="">(where the mutable version takes an “inout […N; T]” in the closure). If you want to strip more than one dimension, then do the subsequent dimensions within the closures. These functions would have to wait for complete generics, though.</div><div class=""><br class=""></div><div class="">In fact, the lack of a “constexpr” (to use a C++ term) story really limits FSA declarations (Right now, bounds must be integer literals.), let alone on how much complete generics would help.<br class=""><br class=""></div><div class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">—&nbsp;</div><div class="">Daryle Walker<br class="">Mac, Internet, and Video Game Junkie<br class="">darylew AT mac DOT com&nbsp;</div><div class=""><br class=""></div></div></div></div><div class=""><br class=""></div></body></html>