<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=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""></div><div class=""><blockquote type="cite" class="">That's not a concern with the `let` case that Robert brought up, since you can't mutate a `let` array at all.<div class=""><br class=""></div><div class="">The big thing is that unconstrained escape analysis is uncomputable. Since Swift array storage is COW, any function that receives the array as a parameter is allowed to take a reference on its storage. If the storage lives on the stack and that reference outlives the stack frame, you've got a problem. It's the same problem that motivated @escaping for closures.</div><div class=""><br class=""></div><div class="">You could allow storage to be on the stack by forcing user to make a pessimistic copy, which is possibly not an improvement.</div></blockquote></div><div class=""><br class=""></div><div class="">Good point. If this is only problematic when multiple threads are accessing an array, then it could still be worthwhile if all accesses are (provably) on the thread that created the array. And pessimistic copying might still be worth it for arrays below a certain size — for instance, copying an Array&lt;Int&gt; of length 1 (and recall that the array in question is a constant so its size is known at compile time) would definitely be worth not having that array in heap memory.</div><div class=""><br class=""></div><div class="">Going back to the literal notion of FSAs — fixed size arrays not necessarily on the stack — I think that simply copying Array’s implementation sans RangeReplaceableCollection conformance is not a bad way to go. Any optimizations used for `let` Arrays could probably be applied to this type of FSA.</div><div class=""><br class=""></div><div class="">On Aug 4, 2017, at 2:15 PM, John McCall via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 4, 2017, at 1:19 PM, 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="">That's not a concern with the `let` case that Robert brought up, since you can't mutate a `let` array at all.<div class=""><br class=""></div><div class="">The big thing is that unconstrained escape analysis is uncomputable. Since Swift array storage is COW, any function that receives the array as a parameter is allowed to take a reference on its storage. If the storage lives on the stack and that reference outlives the stack frame, you've got a problem. It's the same problem that motivated @escaping for closures.</div><div class=""><br class=""></div><div class="">You could allow storage to be on the stack by forcing user to make a pessimistic copy, which is possibly not an improvement.</div></div></div></blockquote><div class=""><br class=""></div>Right. &nbsp;I think maybe the name people keeping using for this feature is misleading; a better name would be "inline arrays" or "directly-stored arrays". &nbsp;Having a fixed size is a necessary condition for storing the array elements directly, but the people asking for this feature are really asking for the different representation, not just the ability to statically constrain the size of an array.</div><div class=""><br class=""></div><div class="">That representation difference comes with a lot of weaknesses and trade-offs, but it's also useful sometimes.</div><div class=""><br class=""></div><div class="">John.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><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=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">Le 4 août 2017 à 09:21, Taylor Swift via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">No, that doesn’t work. In many cases you want to mutate the elements of the array without changing its size. For example, a Camera struct which contains a matrix buffer, and some of the matrices get updated on each frame that the camera moves. The matrix buffer also stores all of the camera’s stored properties, so what would be conceptually stored properties are actually computed properties that get and set a Float at an offset into the buffer. Of course this could all be avoided if we had fixed layout guarantees in the language, and then the Camera struct could <i class="">be</i> the matrix buffer and dispense with the getters and setters instead of managing a heap buffer.<br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="">So, I’m getting into this thread kind of late, and I’ve only skimmed most of it, but…<div class=""><br class=""></div><div class="">A special FSA on the stack seems like the wrong direction. Wouldn’t it make more sense to have *all* value types that don’t change in size — including `let` Arrays — live on the stack? In which case, FSA would merely act like a normal `let` Array, without RangeReplaceableCollection conformance, whose elements could be changed via subscripting. I know nothing about the underlying implementation details of Swift, so I may be way off base here.</div><div class=""><div class="h5"><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 4, 2017, at 2:18 AM, David Hart &lt;<a href="mailto:david@hartbit.com" target="_blank" class="">david@hartbit.com</a>&gt; wrote:</div><br class="m_-711745297369886882Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class="">Don’t small arrays live on the stack?<div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-711745297369886882Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class=""><div class="">As far as I can tell, currently, all arrays live on the heap.</div><br class=""><div class=""><blockquote type="cite" class=""><div class="">Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="m_-711745297369886882Apple-interchange-newline"><div class=""><div dir="auto" class=""><div class=""></div><div class="">Where do constant Arrays currently live? I hope the answer is on the stack, since their size doesn’t change.</div><div class=""><br class="">On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><span class=""><div class=""><blockquote type="cite" class=""><div class=""><div 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" class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">The root cause, of course, is that the VLAs require new stack allocations each time, and the stack is only deallocated as one lump when the frame ends.</div></div></div></blockquote><div class=""><br class=""></div><div class="">That is true of alloca(), but not of VLAs.&nbsp; VLAs are freed when they go out of scope.</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""></span><div class="">Learned something today.</div><div class=""><br class=""></div><div class="">Anyway, if the goal is stack allocation, I would prefer that we explored other ways to achieve it before jumping to a new array-type. I’m not really a fan of a future where [3; Double] is one type and (Double, Double, Double) is something else, and Array&lt;Double&gt; is yet another thing.</div></div></blockquote><div class=""><br class=""></div><div class="">They are completely different things. <br class=""><br class=""></div><div class="">[3; Double] is three <i class="">contiguous</i> Doubles which may or may not live on the stack. <br class=""><br class=""></div><div class="">(Double, Double, Double) is three Doubles bound to a single variable <i class="">name</i>, which the compiler can rearrange for optimal performance and may or may not live on the stack. <br class=""><br class=""></div><div class="">Array&lt;Double&gt; is an vector of Doubles that can dynamically grow and always lives in the heap.<br class=""></div><div class="">&nbsp;</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" class=""><div class=""><br class=""></div><div class="">From what I’ve read so far, the problem with stack-allocating some Array that you can pass to another function and which otherwise does not escape, is that the function may make an escaping reference (e.g. assigning it to an ivar or global, or capturing it in a closure).</div><div class=""><br class=""></div><div class="">How about if the compiler treated every Array it receives in a function as being potentially stack-allocated. The first time you capture it, it will check and copy to the heap if necessary. All subsequent escapes (including passing to other functions) use the Array known to be allocated on the heap, avoiding further checking or copying within the function.</div><div class=""><br class=""></div><div class="">The same goes for Dictionary, and really any arbitrary value-type with COW storage. The memory that those types allocate is part of the value, so it would be cool if we could treat it like that.</div></div>
<br class=""></blockquote></div><br class=""></div><div class="gmail_extra">This is not true. FSAs have nothing to do with automatic storage, their static size only makes them <i class="">eligible</i> to live on the stack, as tuples are now. The defining quality of FSAs is that they are static and contiguous. <br class=""></div></div>
</div></blockquote><blockquote type="cite" class=""><div class=""><span class="">______________________________<wbr class="">_________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a></span><br class=""></div></blockquote></div>______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class=""></div></blockquote></div><br class=""></div>______________________________<wbr class="">_________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div></div><br class="">______________________________<wbr class="">_________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a><br class="">
<br class=""></blockquote></div><br class=""></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><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=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></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></body></html>