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

Reply via email to