<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 Jun 11, 2016, at 5:18 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="ltr" style="font-family: Helvetica; font-size: 10px; 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="">On Fri, Jun 10, 2016 at 9:55 PM, Jonathan Hull via swift-evolution<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br 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-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class="">I really love this idea.&nbsp; My mental model of it is that it is exactly like ‘defer’, except it works on the lifetime of the object instance instead of a function/method.&nbsp; Same thing, different scope.</div><div class=""><br class=""></div><div class="">I like how the creation and destruction are right next to one another.&nbsp; It also solves a lot of potential issues with partial initialization, I believe.</div><div class=""><br class=""></div><div class="">I might spell it ‘deferToDeinit’ or 'deferUntilDeinit'</div><div class=""><br class=""></div><div class="">The only issue I see is accidentally capturing self strongly.&nbsp; Is there a way to mark a closure as implicitly unowned self so the end programmer doesn’t have to worry about it?</div></div></blockquote><div class=""><br class=""></div><div class="">I really like this idea as well. Does it need to be a regular closure? This is one of those things that can be built into the language itself, surely? Then the implicitly unowned self part would be taken care of...</div></div></div></div></div></blockquote><div><br class=""></div><div>This should be handled by the compiler and the code within the block should be used to create a deinit method.</div><div><br class=""></div><div>Several issues to deal with:</div><div><br class=""></div><div>- if there are deferred de-inits in init, is regular deinit {} allowed? If yes, does the deferred deinit code from init get called before or after?</div><div><br class=""></div><div>- what if there are several initializers and each has its own deferred de-inits? Would the instance need to keep the information which initializer was used and call proper deinit based on that?</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 10px; 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 class="gmail_extra"><div class="gmail_quote"><div class="">&nbsp;</div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class=""><div class=""><br class=""></div><div class="">Thanks,</div><div class="">Jon</div><div class=""><blockquote type="cite" class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class=""><span class="">Twitter tl;dr: 
&gt;<i class=""> Brent: So each instance must remember which init was used for it and then run the matching deinit code at deinit time?
</i>&gt;<i class=""> Me: In my version, the constructive act and destructive act are always paired, even redundantly, using a stack if needed
</i>&gt;<i class=""> Graham: so all your deferredDeinit blocks would run, no matter which init was invoked?
</i>&gt;<i class=""> Brent: Closure stack in the worst case. Might be able to optimize to something cheaper if no captures.  Degenerate case: `for i in 0..&lt;10 { deinit { print(i) } 
</i></span>
So continuing on from Twitter, assuming the compiler cannot optimize in the case of multiple inits, and init-redirections, how about allowing traditional deinit as well, and introduce compile-time optimization into traditional de-init if the compiler finds only one initialization path per class? We can also warn anyone using my version in a complicated degenerate way that it can be costly through education, manual, etc. It would also help if (especially in Cocoa), you could legally use shared initialization setup closures.

If I create an observer, I want to be able to handle its end-of-life at that point. If I allocate memory, ditto. Etc etc. Surely Swift should be able to support doing this.

-- E

&gt;<i class=""> On Jun 8, 2016, at 3:43 PM, Erica Sadun via swift-evolution &lt;<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">swift-evolution at swift.org</a>&gt; wrote:
</i><span class="">&gt;<i class=""> 
</i>&gt;<i class=""> I really like this idea. Spatially moving cleanup next to unsafe operations is good practice.
</i>&gt;<i class=""> 
</i>&gt;<i class=""> In normal code, I want my cleanup to follow as closely as possible to my unsafe act:
</i>&gt;<i class=""> 
</i>&gt;<i class=""> let buffer: UnsafeMutablePointer&lt;CChar&gt; = UnsafeMutablePointer(allocatingCapacity: chunkSize)
</i>&gt;<i class="">     defer { buffer.deallocateCapacity(chunkSize) }
</i>&gt;<i class=""> 
</i>&gt;<i class=""> (Sorry for the horrible example, but it's the best I could grep up with on a moment's notice)
</i>&gt;<i class=""> 
</i>&gt;<i class=""> I like your idea but what I want to see is not the deinit child closure in init you propose but a new keyword that means defer-on-deinit-cleanup
</i>&gt;<i class=""> 
</i>&gt;<i class=""> self.ptr = UnsafeMutablePointer&lt;T&gt;(allocatingCapacity: count)
</i>&gt;<i class="">     deferringDeInit { self.ptr.deallocateCapacity(count) }
</i>&gt;<i class=""> 
</i>&gt;<i class=""> Or something.
</i>&gt;<i class=""> 
</i>&gt;<i class=""> -- E
</i>&gt;<i class=""> p.s. Normally I put them on the same line with a semicolon but dang these things can be long
</i>&gt;<i class=""> 
</i></span><span class="">&gt;&gt;<i class=""> On Jun 8, 2016, at 10:54 AM, Graham Perks via swift-evolution &lt;<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">swift-evolution at swift.org</a> &lt;mailto:<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">swift-evolution at swift.org</a>&gt;&gt; wrote:
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> Teach init a 'defer'-like ability to deinit
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> 'defer' is a great way to ensure some clean up code is run; it's declaritive locality to the resource acquisition is a boon to clarity.
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> Swift offers no support for resources acquired during 'init'.
</i>&gt;&gt;<i class=""> 
</i></span>&gt;&gt;<i class=""> For an example, from <a href="https://www.mikeash.com/pyblog/friday-qa-2015-04-17-lets-build-swiftarray.html" target="_blank" class="">https://www.mikeash.com/pyblog/friday-qa-2015-04-17-lets-build-swiftarray.html</a> &lt;<a href="https://www.mikeash.com/pyblog/friday-qa-2015-04-17-lets-build-swiftarray.html" target="_blank" class="">https://www.mikeash.com/pyblog/friday-qa-2015-04-17-lets-build-swiftarray.html</a>&gt;
</i><div class=""><div class="h5">&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> init(count: Int = 0, ptr: UnsafeMutablePointer&lt;T&gt; = nil) {
</i>&gt;&gt;<i class="">     self.count = count
</i>&gt;&gt;<i class="">     self.space = count
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">     self.ptr = UnsafeMutablePointer&lt;T&gt;.alloc(count)
</i>&gt;&gt;<i class="">     self.ptr.initializeFrom(ptr, count: count)
</i>&gt;&gt;<i class=""> }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> deinit {
</i>&gt;&gt;<i class="">     ptr.destroy(...)
</i>&gt;&gt;<i class="">     ptr.dealloc(...)
</i>&gt;&gt;<i class=""> }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> Another 'resource' might be adding an NSNotificationCenter observer, and wanting to unobserve in deinit (no need in OS X 10.11, iOS 9, but for earlier releases this is a valid example).
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> Changing the above code to use a 'defer' style deinit block might look like:
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> init(count: Int = 0, ptr: UnsafeMutablePointer&lt;T&gt; = nil) {
</i>&gt;&gt;<i class="">     self.count = count
</i>&gt;&gt;<i class="">     self.space = count
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">     self.ptr = UnsafeMutablePointer&lt;T&gt;.alloc(count)
</i>&gt;&gt;<i class="">     self.ptr.initializeFrom(ptr, count: count)
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">     deinit {
</i>&gt;&gt;<i class="">         ptr.destroy(...)
</i>&gt;&gt;<i class="">         ptr.dealloc(...)
</i>&gt;&gt;<i class="">     }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class="">     // NSNotificationCenter example too
</i>&gt;&gt;<i class="">     NSNotificationCenter.defaultCenter().addObserver(...)
</i>&gt;&gt;<i class="">     deinit { 
</i>&gt;&gt;<i class="">         NSNotificationCenter.defaultCenter().removeObserver(...)
</i>&gt;&gt;<i class="">     }
</i>&gt;&gt;<i class=""> }
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> The need to provide a separate implemention of deinit is gone. Reasoning for 'defer' applies here. There is good locality between what was initialized and what needs cleaning up.
</i>&gt;&gt;<i class=""> 
</i>&gt;&gt;<i class=""> Considerations:
</i>&gt;&gt;<i class=""> 1. Should deinit blocks be invoked before or after code in an explicit deinit method?
</i>&gt;&gt;<i class=""> 2. Should deinit blocks be allowed in other methods; e.g. viewDidLoad()?
</i>&gt;&gt;<i class=""> 3. How should deinit blocks be prevented from strongly capturing self (thus preventing themselves from ever running!)?
</i>&gt;<i class=""> </i></div></div></pre></blockquote><div class=""><br class=""></div></div></div><br 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/mailman/listinfo/swift-evolution</a><br class=""><br class=""></blockquote></div><br class=""></div></div><span style="font-family: Helvetica; font-size: 10px; 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="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 10px; 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=""><span style="font-family: Helvetica; font-size: 10px; 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="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 10px; 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=""><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 10px; 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="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 10px; 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=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica; font-size: 10px; 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="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></body></html>