<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=""><div class=""><div class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-kerning: none" class="">John,</span></div><div style="margin: 0px; line-height: normal; min-height: 14px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-kerning: none" class="">Sure, that is the pattern most commonly adopted for these cases but it does in fact create a considerable amount of boilerplate code. My hope was to reduce the amount of boilerplate and the burden to create such a common pattern of functionality.</span></div><div style="margin: 0px; line-height: normal; min-height: 14px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-kerning: none" class="">I do understand that the implementation would be complex. I am imagining that these observers would get magically called when someone adds or removes the collection. The wrinkle I think you’re referring to is the fact that there are a variety of ways in which a collection can be 'added to' and 'removed from’. Is that the complexity you are referring to?</span></div><div style="margin: 0px; line-height: normal; min-height: 14px;" class=""><span style="font-kerning: none" class=""></span><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-kerning: none" class="">Sean</span></div></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-kerning: none" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Mar 30, 2017, at 2:58 PM, John McCall <<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On Mar 30, 2017, at 2:37 PM, Sean Alling via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><span class="" style="text-decoration: underline; -webkit-font-kerning: none;"><b class="">PROPOSAL:</b></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">I propose the addition of the following new property observers applicable to all Collection types (Dictionary, Set, and Array):</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">–<span class="Apple-converted-space"> </span><b class="">willAdd(newValue) { … }</b></span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">–<span class="Apple-converted-space"> </span><b class="">didAdd(newValue) { … }</b></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">–<span class="Apple-converted-space"> </span><b class="">willRemove(oldValue) { … }</b></span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">–<span class="Apple-converted-space"> </span><b class="">didRemove(oldValue) { … }</b></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">where, `</span><span class="" style="text-decoration: underline; -webkit-font-kerning: none;">newValue</span><span class="" style="-webkit-font-kerning: none;">` and `</span><span class="" style="text-decoration: underline; -webkit-font-kerning: none;">oldValue</span><span class="" style="-webkit-font-kerning: none;">` are<span class="Apple-converted-space"> </span><b class="">immutable</b>.</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">This would allow one to perform additional work or observer logic to values added and removed from collections. This model is consistent with Swift syntax and may perhaps minimize the use of NSNotifications in some situations.</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">Currently, in order to perform this functionality some filtering and comparison logic would have to be performed from within a `willSet { … }` and `didSet { …}` call. This change would not only ease that burden but promote a more visible and explicit expression that can further improve readability and traceability of functionality.</span></div></div></div></blockquote><div class=""><br class=""></div>Figuring out that an arbitrary change to a collection is an "add" or a "remove" of a specific element is, well, let's just say it's complex. If you're imagining that these observers would just get magically called when someone called the add or remove method on the property, that's not really how these language features work together.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">The property behaviors proposal would let you do things like automatically computing differences and calling these observers, if you really want to do that. But the better solution is almost certainly to (1) make the collection property private(set) and (2) just declare addToList and removeFromList methods that do whatever you would want to do in the observer.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">John.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="text-decoration: underline; -webkit-font-kerning: none;"><b class="">EXAMPLE USAGE:</b></span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">var list = [objects]() {</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>willAdd(newValue) {</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">                </span>… </span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>}</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>didAdd(newValue) {</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">                </span>…</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>}</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">var list = [key : object]() {</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>willRemove(oldValue) {</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">                </span>…</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>}</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>didRemove(oldValue) {</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">                </span>…</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;"><span class="Apple-tab-span" style="white-space: pre;">        </span>}</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">}</span></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal; min-height: 14px;"><span class="" style="-webkit-font-kerning: none;"></span><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">-----</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="-webkit-font-kerning: none;">Sean Alling</span></div><div class="" style="margin: 0px; line-height: normal; color: rgb(0, 105, 217);"><span class="" style="text-decoration: underline; -webkit-font-kerning: none;"><a href="mailto:allings@icloud.com" class="">allings@icloud.com</a></span></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></div></blockquote></div></div></blockquote></div><br class=""></body></html>