<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="" applecontenteditable="true">It seems like the main complaints about NSProgress revolve around KVO, which there is no question about not being right for Swift in many ways. I’m aware of that. I think the right answer there is instead to improve KVO in Swift, not to replace all KVO in the SDK on a case-by-case basis with ad-hoc observation mechanisms. I acknowledge that improving KVO is not a small task.<div class=""><br class=""></div><div class="">Responding to some of the other notes in your description:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">* KVO</div><div class=""><br class=""></div><div class="">NSProgress does not use KVO to update its parent progress objects. You can actually see this in the swift-corelibs-foundation version of NSProgress. It does post notifications for its properties this way though.</div><div class=""><br class=""></div><div class="">* Implicit tree composition</div><div class=""><br class=""></div><div class=""><div class="">I agree that implicit tree composition is not a great idea except in very controlled circumstances. That’s why I introduced the explicit API.</div></div><div class=""><br class=""></div><div class="">* Explicit tree composition</div><div class=""><br class=""></div><div class="">It looks like you’ve used this incorrectly. The reason the ProgressReporting protocol exists is for types to expose a progress that the caller can then compose into their own progress tree. There is no requirement to use it, but it establishes the pattern.</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">// disclaimer:&nbsp;typed in Mail</font></div><div class=""><font face="Menlo" class="">class X {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var progress: Progress {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; let p = Progress.discreteProgress(totalUnitCount: 10)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; // start with some progress</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; p.completedUnitCount = 5</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">var x = X()</font></div><div class=""><font face="Menlo" class="">var p = Progress.discreteProgress(totalUnitCount: 2)</font></div><div class=""><font face="Menlo" class="">var childA = Progress(totalUnitCount: 4, parent: p, pendingUnitCount: 1) // childA is 50% of p</font></div><div class=""><font face="Menlo" class="">p.addChild(x.progress, pendingUnitCount: 1) // x.progress is 50% of p</font></div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">p.fractionCompleted // 0.25</font></div><div class=""><div class=""><br class=""></div><div class="">* Updating progress in a tight loop</div><div class=""><br class=""></div><div class="">No matter how efficient you make updating the properties (and, again, I acknowledge that KVO support adds a cost here), the fact that progress forms trees and the trees are designed to be arbitrarily large, means that you should always consider the cost of updating too frequently. Reducing the cost per update is still a noble goal. As is reducing autoreleases.</div><div class=""><br class=""></div><div class="">* Updating completedUnitCount atomically</div><div class=""><br class=""></div><div class="">The best practice here is to keep the progress object thread local. I think that updating one progress from multiple threads could be a code smell. Perhaps then you are doing several parts of the work and you should instead form a tree. This also leads in a direction where completed unit count is either 100% handed out to children or 100% controlled by your work-update-progress loop. Mixing the two leads to easy confusion about who is responsible for which portion. If you follow this rule, you never have to get the completed unit count, which means the race you describe does not exist.</div><div class=""><br class=""><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Feb 21, 2017, at 2:25 PM, Charles Srstka 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=""><blockquote type="cite" class="">On Feb 21, 2017, at 3:52 PM, Rod Brown &lt;<a href="mailto:rodney.brown6@icloud.com" class="">rodney.brown6@icloud.com</a>&gt; wrote:<br class=""></blockquote><div class=""><blockquote type="cite" class=""><div class=""><br class=""></div></blockquote><blockquote type="cite" class=""><div class=""><span 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; float: none; display: inline !important;" class="">It still holds the fundamental oddities of NSProgress that I find weird. Like "current progress" always strikes me as very odd concept.</span><br 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=""></div></blockquote><div class=""><br class=""></div><div class="">The “current progress” bit is there mainly for source compatibility. I’d expect it would not be the norm for new code.</div><br class=""><blockquote type="cite" class=""><div class=""><span 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; float: none; display: inline !important;" class="">I'd be interested to see what Tony Parker and the Core Team think!</span></div></blockquote></div><br class=""><div class="">So would I.</div><div class=""><br class=""></div><div class="">Charles</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=""></div></div></div></body></html>