Going along with the "self." / "self?." from my previous message, perhaps "self!." For unowned?
That said, if there were only an unowned convenience, I would not use it. I'm not going to have that debate here, since I think the value of "weak" is obvious to most developers. Sent from my iPad > On Sep 13, 2016, at 12:38 PM, Kevin Nattinger <[email protected]> wrote: > > >> On Sep 13, 2016, at 10:29 AM, Benjamin Spratling via swift-evolution >> <[email protected]> wrote: >> >> Well, then also add an unowned convenience. >> But I’ve never been handed a story from UX that said, “As a user, when ____ >> I want the app to crash.” >> Using weak, the compiler can tell me when I’ve missed a possible case where >> it’s nil. > > Honestly, I’d be fine with / prefer only allowing unowned (at all) if it’s > @noescape, if that, requiring strong or weak for anything that escapes. That > seems to go along with swift’s emphasis on safety. > >> But the point here is to get closure references that don’t create retain >> cycles. Obviously, there’s desire for both weak and unowned variants >> without the syntactic overhead of a full closure. >> >>> On Sep 13, 2016, at 12:22 PM, Karl Wagner <[email protected]> wrote: >>> >>> Weak references can have a non-trivial amount of overhead in >>> high-performance code. In some cases you can guarantee that a pointer >>> should never be null - and that if it is, a serious logic error has >>> occcurred and you *should* crash. >>> >>> I prefer crashing to running in an inconsistent state. Who knows what can >>> happen in the latter case - data corruption? I'd prefer to crash, get a >>> report and fix the bug. >>> >>> Karl >>> >>> This is how I Email now >>> >>> >>>> On Sep 13, 2016 at 11:07 am, <Benjamin Spratling via swift-evolution> >>>> wrote: >>>> >>>> Nick, I like where you’re headed with the instance-methods-as-closures >>>> idea. Here’s where I’m headed with it: >>>> >>>> Closures are too often used to write the contents of what should be >>>> another function, producing code similar to the “pyramid of doom” avoided >>>> by guard. I now generally write as little code as possible in a closure, >>>> and use it merely to dispatch out to a private function as quickly as >>>> possible. This means I really do want classes to reference their own >>>> functions. I look at closures more as providing the captured scope as the >>>> "void* context" that goes along with an old C function reference, as >>>> opposed to being the scope in which the code should be written. >>>> >>>> I loved the “get a closure to implicit self using nothing but the function >>>> name” feature of Swift, but after running over a dead line by spending 1.5 >>>> days with 3 other developers trying to find a retain cycle caused by its >>>> use, we added it to our list of reasons to not merge code, hereafter >>>> referred to as “the list". This from a guy who used to write flawless >>>> manual retain/release code, back in the day. >>>> >>>> Incidentally, we also put “unowned" on "the list". We always use “weak” >>>> instead. The bottom line is unowned CAN crash, and weak can’t. There is >>>> no way to know if a call to unowned will crash or not. So we prefer to >>>> write code that can’t crash. (No, we don’t force-unwrap weak optionals, >>>> “!” is on "the list”, and we nicknamed it the “Russian Roulette operator”) >>>> So instead of “something like [unowned self] syntax...”, I’m suggesting >>>> “something like [weak self] syntax..." >>>> >>>> So I’d prefer something like “weakself?.functionName” to produce a closure >>>> which wraps a weak-self reference and a call to the given method if self >>>> isn’t nil. This seems like a trivial task for the compiler when return >>>> types are Void or Optional. Given the expectations of optional chaining, >>>> and the zeroing behavior of any not-owned relationship, I’m not sure it >>>> makes sense to demand a non-optional return type for a call to a parent. >>>> So I don’t think such a feature even needs to worry about what if the >>>> expected return type isn’t optional. >>>> >>>> I’d be happy to see any of the following syntaxes: >>>> >>>> weakself.functionName >>>> weakself?.functionName >>>> ?functionName >>>> welf.functionName >>>> self?.functionName >>>> weak(self)?.functionName >>>> >>>> Obviously, one work around is to declare a protocol, and pass self, >>>> letting the receiving class store a weak reference. But declaring >>>> protocols for every single closure reference is a bit tedious. Literally >>>> just the back and forth on naming them is a waste of time. And there’s >>>> the running joke that we’d just tack “able” on the end of the method name. >>>> >>>> Another work around is to create several generic classes which generate >>>> closures which weakly capture self and an unapplied method reference, and >>>> overloaded functions or operators to provide the correct class. >>>> Unfortunately, this still requires writing “self” explicitly, and also >>>> explicitly writing the type of self to obtain an unapplied method >>>> reference. >>>> >>>> Given our experience, I would consider giving a warning when an >>>> implicit-self closure goes into an @escaping context. >>>> >>>> class SomeClass { >>>> var someFunction:(()->())? >>>> func setup() { >>>> prepare(closure: trigger) //this should probably be a >>>> warning >>>> } >>>> func prepare(closure:@escaping()->()) { >>>> someFunction = closure >>>> } >>>> func trigger() { >>>> } >>>> } >>>> >>>> Self is already required when used inside an closure, for exactly this >>>> reason. >>>> Perhaps we should require the developer to write explicit “self” or >>>> “self?” to indicate strong or weak capture of self. >>>> prepare(closure: self.trigger) //ok, strong self >>>> prepare(closure: self?.trigger) //ok, weak self >>>> Or if they would like to use unowned, >>>> prepare(closure: RussianRoulette(self).trigger) // ;-) >>>> >>>> In the end, however, closures do occasionally capture >>>> non-instance-property scope, which would need to be adapted in the >>>> wrapping closure around the call to another method, so the number of >>>> no-adapting-needed methods may be quite low. I expect given current >>>> priorities that this wouldn’t make it in to Swift 3.1. But given the >>>> severity of the consequences and the simplicity of the implementation, I >>>> would hope it would make it by Swift 4. >>>> >>>> -Ben Spratling >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
