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
>          
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to