> 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] 
>> <mailto:[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 
>> <https://itunes.apple.com/app/apple-store/id922793622?pt=814382&mt=8&ct=how_i_email>
>>  is how I Email now
>> 
>> 
>>> On Sep 13, 2016 at 11:07 am, <Benjamin Spratling via swift-evolution 
>>> <mailto:[email protected]>> 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 <mailto:[email protected]>
>>> [email protected] <mailto:[email protected]>
>>> https 
>>> <mailto:[email protected]>://lists.swift.org/mailman/listinfo/swift-evolution
>>>  <http://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