<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 2 Jun 2017, at 07:38, Robert Bennett &lt;<a href="mailto:rltbennett@icloud.com" class="">rltbennett@icloud.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""></div><div class="">My favorite proposal so far is one that was posted a while ago, [Int * 4]. <span style="background-color: rgba(255, 255, 255, 0);" class="">I think that this syntax looks pretty Swifty. There isn't an oddball subscript operator like with Int[4], and there isn't a need to allow generics to support values as parameters.&nbsp;</span>It's clear that [Int * 4] will be array-like and contain four Ints. For multidimensional arrays we could use [Int * (2,3)]. For an array of tuples, [(x: Int, y: Int) * 4]. I'm not sure why nested static arrays would be needed when multidimentionality is provided out of the box, but presumably the syntax would support them; you would just need to subscript the arrays one at a time instead of with a single subscript operator, e.g., a[i][j] instead of a[i, j].</div><div class=""><br class=""></div><div class="">I'm imagining this syntax working like [T] does now as a shorthand for Array&lt;T&gt;, although I'm not sure what [Int * 4] should be short for (StaticArray&lt;Int, 4&gt;? Vector4&lt;Int&gt;? ...). Constructors for static arrays would be called using [Int * 4](args). I'm thinking the constructors would be [T * 4](filledWith: T), [T * 4](filledBy: (Int)-&gt;T), and an initializer taking a Sequence that fails in some manner on a dimension mismatch.</div></div></div></blockquote><div><br class=""></div><div><div>Even with that syntax I'd say there should be a means of handling it in a general purpose way.</div><div><br class=""></div><div>For example, let's say you defined that syntax as an operator:</div><div><br class=""></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>func * &lt;T&gt;(lhs: T.self, rhs: Int) -&gt; (type: T.self, size:Int) { return (type: lhs, size: rhs) }</font></div><div><br class=""></div><div>Now you have an explicit tuple describing what it is you want to do, which the compiler can now pass to a type during compilation to do with as it pleases. In this case it would pass to some FixedArray type which can use the type and size to optimise itself. Not sure on the specifics of how just yet, but point being to try to make this a part of the language that others can use, rather than simply being some form of compiler magic.</div><div><br class=""></div><div>My reasoning being that it may be useful to have other type operators in future, and/or other types able to take and use the same information.</div><div><br class=""></div><div><br class=""></div><div>For example, I briefly discussed once the possibility of a Float variant whose compatibility would be limited by its target precision, and use ± as an operator so that I could define for example:</div><div><br class=""></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>var a:Float±0.1 = 0.5</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>var b:Float±0.5 = 5.0</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>a = b // error; precision mismatch (b's precision is too low to guarantee accuracy)</font></div><div><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>b = a // this is fine, as a is "more precise" than b</font></div><div><br class=""></div><div><br class=""></div><div>Now put aside whether that idea is actually useful or not; my point is that I'd like support for fixed-size arrays to be general purpose, as there are other possible uses for the same basic capabilities (i.e- type variables).</div><div><br class=""></div><div>The key thing really is that we need some way for the compiler to recognise that a type is being refined somehow, and compile it separately as appropriate. I mentioned generics style variable passing because to me this is the most logical way to pass information into a type, not because I want it to be the default syntax at the call site; I fully support other shorthands for the actual passing of data, the key for me is being able to leverage the same kind of type-refining capabilities in my own types, rather than this whole thing just being focused solely on fixed-sized arrays implemented with compiler magic.</div></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">On Jun 1, 2017, at 7:36 AM, Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class="">Just wanted to add my two-cents to this discussion, but in terms of syntax I think that the basic method for specifying size should be with some kind of type variables, like so:<br class=""><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>struct MyFixedArray&lt;T, size:Int&gt; { … }</font></div><div class=""><br class=""></div><div class="">The idea being that we can then use size as a variable anywhere within the code for MyFixedArray, but unlike other variables it is determined at compile time, so should be optimised accordingly. As with generics, setting a type variable effectively creates a variant type so for example, a MyFixedArray&lt;Int, size:3&gt; and a MyFixedArray&lt;Int, size:4&gt; would no longer be directly compatible as they may differ internally.</div><div class=""><br class=""></div><div class="">This would be useful not just for fixed arrays, but other possibly type variations as well. Ideally it should be possible to specify a default value for type variables; while this wouldn't be useful for fixed arrays, it may be useful for other type variants.</div><div class=""><br class=""></div><div class="">To better suit the specific use-case of arrays, we could also add some useful attributes or keywords, for example, reusing subscript could give us:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">struct MyFixedArray&lt;T, subscript size:Int&gt; { … }</font></div><div class=""><font face="Monaco" class="">let foo:MyFixedArray[4] = [1, 2, 3, 4] // with T being inferred, this is a shorthand for specifying a size of 4</font></div></blockquote><font face="Monaco" class=""><br class=""></font>Type variables could also be usable with generics, like-so:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-family: Monaco;" class="">// only accept fixed arrays of same or smaller size:</span></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">func myMethod&lt;FA&gt;(values:FA) where FA:FixedArray, FA.size &lt;= Self.size { … }&nbsp;</font></div></blockquote><div class=""></div><div class=""><div class=""><br class=""></div><div class="">These are the kind of general purpose capabilities I'd like to see at some point, as the usefulness extends beyond just fixed-size arrays.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">However, on the &nbsp;subject of fixed-size arrays specifically, one other possibility to explore is the concept of Tuple repetition and subscripting. For example, it would be interesting if we could do things like:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var foo:(Int)[4] = 0 // Initialises four Ints, all set initially to zero</font></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>for i in 0 ..&lt; 4 { foo[i] = i } // values are no 0, 1, 2, 3</font></div><div class=""><br class=""></div><div class="">This can be especially interesting when you get into more complex tuples like so:</div><div class=""><br class=""></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var bar:(x:Int, y:Int)[10] = (x: 0, y: 0) // Initialises 10 pairs of Ints, all initially set to zero</font></div></div><div class=""><font face="Monaco" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>for i in 0 ..&lt; 10 { bar[i].x = i; bar[i].y = i } // here we need to use .x and .y to access the values of each pair</font></div><div class=""><br class=""></div><div class="">Of course this would have the same performance characteristics as standard tuples, but it's an interesting means for creating quick, fixed-size arrays in a flexible way. Part of the idea here is that by subscripting tuples, we avoid the need for a general subscript on all types, keeping that available for use-cases like the above.</div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></blockquote></div><br class=""></body></html>