<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 Aug 2, 2017, at 11:44 AM, Félix Cloutier via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">Le 31 juil. 2017 à 18:54, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>&gt; a écrit :</div><div class=""><div dir="ltr" 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;" class=""><div class="gmail_extra"><div class="gmail_quote"><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;" class=""><div class=""><ul class="m_-4735538757335822547MailOutline"><li class="">It doesn't allow you to specify the size of the array, it'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 class=""><br class=""></div><div class="">Shouldn't this be solved by improvements to tuples? It'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></div></div></blockquote><div class=""><br class=""></div><div class="">Of course, if this happens, the point is moot and we have the type of fixed-size arrays that I've been asking for. However, crystal-balling Chris's last comment on the matter, it looks like&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170724/038225.html" class="">it might not be happening too soon</a>.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" 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;" class=""><div class="gmail_extra"><div class="gmail_quote"><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;" class=""><div class=""><ul class="m_-4735538757335822547MailOutline"><li class="">`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't know what that size is.</li><li class="">Therefore, using a fixed-size array as a generic parameter (crucially, such as `fixed [fixed [Int]]`) is unlikely to work.</li><li class="">Even if that semantic hurdle is overcome, we'd still have no idea how much memory to allocate for the outer array's buffer to make it work.</li></ul></div></div></blockquote><div class=""><br class=""></div><div class="">As John McCall has replied, the array's bounds don't need to be statically known for fixed-size arrays to have benefits.</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">This (partially) applies to the first point, but it leaves a lot of holes. The size does not need to be statically known, but you need to know how much memory you're going to need ahead of allocating it. How much memory do you need for this?</div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">var foo = fixed [Int]()</div><div class="">for i in 0..&lt;param {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>foo.append(i)</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class="">Arrays can't work if elements don't have a fixed size. How big is an element in this example?</div></div></div></div></div></blockquote><div><br class=""></div>This is not the idea. &nbsp;The idea is more like</div><div><br class=""></div><div>&nbsp; let n = ...</div><div>&nbsp; var foo = [Int x n](repeating: 13)</div><div><br class=""></div><div>The bound value is still fundamentally part of the type of the variable; it's just that the actual value is not known statically.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">var foo = fixed [fixed [Int]]()</div><div class="">foo.append([1])</div><div class="">foo.append([2, 3])</div></blockquote></div><div class=""><br class=""></div><div class="">Where do you allocate this array's storage, and how big is it?</div><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">struct Foo {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>var array: fixed [Int]</div><div class="">}</div><div class=""><br class=""></div><div class="">var foo = Foo()</div><div class="">foo.array.append(4)</div></blockquote></div><div class=""><br class=""></div><div class="">In the general case, this makes `fixed` meaningful as a type annotation for parameters, but instantiating such an object in the first place would require you to give up a lot of flexibility in how it's populated. The unconstrained problem of finding how many elements you'll have in an array is uncomputable.</div><div class=""><br class=""></div><div class="">You could say that a fixed-size array stays as big as it was when it was instantiated, but this still causes problems with fixed-size arrays in structures (storage has already been allocated when the initializer runs), and with generic collections (you couldn't initialize a variable-sized array of fixed-size arrays, for instance).</div></div><blockquote type="cite" class=""><div dir="ltr" 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;" class=""><div class="gmail_extra"><div class="gmail_quote"><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;" class=""><div class=""><ul class="m_-4735538757335822547MailOutline"><li class="">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 class=""><br class=""></div><div class="">That's fair, but why at that point wouldn't you make your own Matrix type of fixed size, which uses an Array of fixed size as the underlying storage?</div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I'd do it if I needed to, but there are plenty of 2D arrays that are just that and don't need their own wrapper type to function, and I'd be happier to not do it.</div><blockquote type="cite" class=""><div dir="ltr" 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;" class=""><div class="gmail_extra"><div class="gmail_quote"><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;" class=""><div class=""><ul class="m_-4735538757335822547MailOutline"><li class="">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't achieve layout compatibility if the size is part of the data instead of part of the type.</li></ul></div></div></blockquote><div class=""><br class=""></div><div class="">For me, that'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'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></div></div></blockquote><div class=""><br class=""></div><div class="">I think that any template-based fixed-size array structure would still need that kind of (4 * CGFloat) syntax to be implemented, or some other facility to allocate a parameterized amount of automatic storage. With that said, if we can implement fixed-size arrays with just that without having to wait for the restrictions on anonymous types to be lifted, to me, it's a fully acceptable solution.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" 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;" class=""><div class="gmail_extra"><div class="gmail_quote"><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;" class=""><div class="">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're using them. I don'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't apply to just mutating functions because mutations that don't change the length of the array are fine.</div></div></blockquote><div class=""><br class=""></div><div class="">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'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></div></div></blockquote><div class=""><br class=""></div><div class="">There are more problems to this that you may be able to iron out but that make the story more complex still. How do you annotate MutableCollection-based algorithms, or any other protocol-based extension that doesn't directly accept an array? What's the syntax of an Array extension method, which doesn't have an explicit self parameter, to mean that the function is mutating but doesn't change the array's bounds?</div></div><div class=""><br class=""></div><div class=""><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>