<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Sep 26, 2017, at 2:59 AM, Xiaodi Wu 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=""><div dir="auto" 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="">On Tue, Sep 26, 2017 at 00:15 Jonathan Hull &lt;<a href="mailto:jhull@gbis.com" class="">jhull@gbis.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" 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; 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="">As he says, it is an in-place equivalent of filter, so the use-cases would be similar.&nbsp; I could see this being extremely useful.&nbsp; Off the top of my head:<div class=""><br class=""></div><div class=""><span class="m_6311531772765348523Apple-tab-span" style="white-space: pre-wrap;">        </span>views.remove(where: {$0.isHidden}) //Remove all views which are hidden from the list.</div></div></blockquote><div dir="auto" 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=""><br class=""></div><div dir="auto" 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="">Is such a method ever going to be different (in performance, say) from:</div><div dir="auto" 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=""><br class=""></div><div dir="auto" 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="">views = Views(views.lazy.filter { $0.isHidden })</div></div></blockquote></div><br class=""><div class="">Potentially yes, in a few different ways:</div><div class=""><br class=""></div><div class="">In-place removal doesn’t require an additional storage allocation. Assuming the Views type is like Array (or if it is an Array or backed by an Array) then with the filter approach, the old buffer would need to be freed, and the new buffer allocated.</div><div class=""><br class=""></div><div class="">.lazy.filter is a good way to avoid allocating a temporary array. But you still have the issue of not being able to pre-allocate the right amount of storage in the target. So either two passes are needed to keep to 1 allocation, or the target array will need to reallocate its buffer multiple times as it grows.</div><div class=""><br class=""></div><div class="">When a small number of elements need to be removed, an in-place remove can skip to the first element to remove and shuffle the remainder over the top of the removed elements. In the extreme version of the above, if there’s nothing to remove, then other than that initial scan, the in-place remove is a no-op. By contrast, the filter/copy approach is a full copy of every element even when there’s nothing to remove.</div><div class=""><br class=""></div><div class="">For in-place removal, a type like Array that is backed by raw memory can potentially perform memory moves to shuffle the elements down in-place, helping to avoid things like unnecessary arc traffic. When composing the operation from higher-level types, you’re relying on the optimizer to eliminate unnecessary reference counting. And the more you layer in (like .lazy) the tougher it is for the optimizer to do that – it might not even be possible if the type is defined behind a barrier like a module boundary etc.</div><div class=""><br class=""></div><div class="">It’s for these reasons I pitched&nbsp;<a href="https://github.com/apple/swift-evolution/pull/675" class="">https://github.com/apple/swift-evolution/pull/675</a> previously, but it didn’t make it into Swift 4 as we ran out of time. I took an action in the core team meeting recently to revisit it wrt to the naming and symmetry with filter. I’ll open up a separate thread.</div><div class=""><br class=""></div><div class=""><br class=""></div></body></html>