<div dir="ltr">On Mon, Jul 31, 2017 at 11:45 AM, Félix Cloutier <span dir="ltr">&lt;<a href="mailto:felixcloutier@icloud.com" target="_blank">felixcloutier@icloud.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div></div></div></div></div></blockquote><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Sure, and hence my point: suppose now `foo` is a function in the stdlib, and the stdlib authors have annotated the function so that it is `func foo(arr: fixed [Int])`. Then, any user who writes `var array = ...` could benefit from a performance boost because the compiler will not longer have to be pessimistic about copying in order to maintain COW semantics. This is why I made an explicit analogy to the design proposed for ownership in Swift, where end users don&#39;t have to understand it in order to benefit from the feature because the functions they call can give sufficiently important hints to help the compiler avoid unnecessary copying.</div></div></div></div></div></blockquote><blockquote type="cite"> <br></blockquote><div><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"><div style="word-wrap:break-word"><div><div></div></div></div></blockquote><blockquote type="cite"><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"><div style="word-wrap:break-word"><div><div>I don&#39;t think that you claimed that this should be a solution to the fixed-size array problem, but just in case, also note that it&#39;s not. We can&#39;t make any [Int] layout-compatible with C fixed-size arrays because the length has to be encoded in the type (as it cannot be encoded in the data itself).</div></div></div></blockquote><div><br></div><div>I don&#39;t understand this point. Can you elaborate on what you mean here? Why does it have to be layout-compatible?</div></blockquote></div><div><br></div></span><div>Then it seems that I have stricter requirements for fixed-size arrays than you do, and I&#39;d be curious to hear what you want to get out of fixed-size arrays. If we compare a hypothetical `fixed [int]` to a hypothetical `FixedSizeArray&lt;T, N&gt;`, these are some of the things that matter to me which `fixed` can&#39;t offer:</div><div><br></div><div><ul class="m_-4735538757335822547MailOutline"><li>It doesn&#39;t allow you to specify the size of the array, it&#39;s just a promise that the array is some immutable size. For instance, a `fixed [CGFloat]` would be a terrible type to represent a vector, but a FixedSizeArray&lt;CGFloat, 4&gt; would be appropriate, at least for the backing storage. A raw tuple would be a poor choice because dynamically indexing into them is painful.</li></ul></div></div></blockquote><div><br></div><div>Shouldn&#39;t this be solved by improvements to tuples? It&#39;s a highly desired feature (by me and at least a few others) to allow tuples to conform to protocols, whether fixed-size arrays are added or not. I expect that conforming homogeneous tuples to Collection and enabling subscripting is simply a matter of time.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><ul class="m_-4735538757335822547MailOutline"><li>`fixed` is only useful when the compiler can determine the size of the array statically. This makes it mostly useless as a storage qualifier if you received the array as a parameter (*even* if you received a `fixed` array), because you know that it has a constant size but you don&#39;t know what that size is.</li><li>Therefore, using a fixed-size array as a generic parameter (crucially, such as `fixed [fixed [Int]]`) is unlikely to work.</li><li>Even if that semantic hurdle is overcome, we&#39;d still have no idea how much memory to allocate for the outer array&#39;s buffer to make it work.</li></ul></div></div></blockquote><div><br></div><div>As John McCall has replied, the array&#39;s bounds don&#39;t need to be statically known for fixed-size arrays to have benefits.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><ul class="m_-4735538757335822547MailOutline"><li>Even if `fixed [fixed [Int]]` could work, then each inner array could still have a different size, which is almost certainly not what you intend by nesting two fixed-size arrays.</li></ul></div></div></blockquote><div><br></div><div>That&#39;s fair, but why at that point wouldn&#39;t you make your own Matrix type of fixed size, which uses an Array of fixed size as the underlying storage?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><ul class="m_-4735538757335822547MailOutline"><li>Layout compatibility is important if you want to use fixed-size arrays to replace the clunky tuples that currently represent fixed-size arrays in structs exported from C (which is probably my one single biggest motivation for fixed-size arrays). You can&#39;t achieve layout compatibility if the size is part of the data instead of part of the type.</li></ul></div></div></blockquote><div><br></div><div>For me, that&#39;s an anti-goal, as IMO tuples are the most sensible way of bridging a lot of these fixed-size arrays from C. Quite simply, I&#39;d argue that the most idiomatic way to represent four CGFloat instances is `(CGFloat, CGFloat, CGFloat, CGFloat)`. The solution to certain operations being clunky with tuples is to improve the ergonomics of tuples. For instance, if we need a shorthand to avoid typing all those `CGFloat`s, then add one: `(4 * CGFloat)`. If we need subscripting, then add it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Besides, attaching fixed-size array semantics to an inherently variable-size Array is awkward. For `fixed` to be effective, it needs to disable methods that change the size of the array, or warn that you&#39;re using them. I don&#39;t like the cross-concern impact: now a keyword needs to know about method implementations to restrict them. It also has to work with extension methods on the Array type, and it shouldn&#39;t apply to just mutating functions because mutations that don&#39;t change the length of the array are fine.</div></div></blockquote><div><br></div><div>The idea is that all facilities which would benefit from knowing that an array is of a fixed count would opt into that benefit by indicating as such. That is, all stdlib array methods that are guaranteed to preserve the size of the array would be annotated as such. Again, by analogy to the ownership manifesto&#39;s design where functions that take shared arguments could be optimized on the basis of such annotation. The rest would fall out naturally.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>What would you use `fixed [Int]` for? Only as an optimization tool?</div></div></blockquote><div><br></div><div>Yes. </div></div></div></div>