Realistically, there are still going to be large changes to Swift.
  

  
I expect conditional conformances, for example, to basically transform huge 
amounts of Swift code, including the standard library.
  
  
  
  
  
  

 Karl   

  
>   
> On Jul 15, 2016 at 7:53 PM,  <Charles Srstka via swift-evolution 
> (mailto:[email protected])>  wrote:
>   
>   
>   
>  Won’t that involve source breakage, though? The grammar for calling 
> asynchronous APIs will have changed.
>
> Charles
>
> >  On Jul 14, 2016, at 11:54 PM, Chris Lattner  <[email protected] 
> > (mailto:[email protected])>  wrote:
> >   
> >  When/if we get an async/await like feature, of course we’ll try to pull 
> > completion handlers automatically into the model. We can do that post swift 
> > 3.
> >   
> >  -Chris
> >   
> >>  On Jul 14, 2016, at 3:30 PM, Charles Srstka via swift-evolution  
> >> <[email protected] (mailto:[email protected])>  wrote:
> >>   
> >>  Right, but since this would affect the Obj-C importer and thus would be a 
> >> source-breaking change, it would probably not be possible anymore after 
> >> Swift 3.
> >>   
> >>  Charles
> >>   
> >>>  On Jul 14, 2016, at 4:57 PM, Dan Stenmark  <[email protected] 
> >>> (mailto:[email protected])>  wrote:
> >>>   
> >>>  I’d say it’s a little premature to be talking about this; the team has 
> >>> made it very clear that the discussion on Native Concurrency in Swift 
> >>> won’t begin for another couple months.
> >>>   
> >>>  Dan
> >>>   
> >>>>  On Jul 14, 2016, at 10:54 AM, Charles Srstka via swift-evolution  
> >>>> <[email protected] (mailto:[email protected])>  wrote:
> >>>>   
> >>>>  I know it’s late, but I was wondering what the community thought of 
> >>>> this:
> >>>>   
> >>>>  MOTIVATION:
> >>>>   
> >>>>  With the acceptance of SE-0112, the error handling picture looks much 
> >>>> stronger for Swift 3, but there is still one area of awkwardness 
> >>>> remaining, in the area of returns from asynchronous methods. 
> >>>> Specifically, many asynchronous APIs in the Cocoa framework are declared 
> >>>> like this:
> >>>>   
> >>>>  - (void)doSomethingWithFoo: (Foo *)foo completionHandler: (void (^)(Bar 
> >>>> * _Nullable, NSError * _Nullable))completionHandler;
> >>>>   
> >>>>  This will get imported into Swift as something like this:
> >>>>   
> >>>>  func doSomething(foo: Foo, completionHandler: (Bar?, Error?) ->  ())
> >>>>   
> >>>>  The intention of this API is that either the operation will succeed, 
> >>>> and something will be passed in the Bar parameter, and the error will be 
> >>>> nil, or else the operation will fail, and then the error parameter will 
> >>>> be populated while the Bar parameter is nil. However, this intention is 
> >>>> not expressed in the API, since the syntax leaves the possibility that 
> >>>> both parameters could be nil, or that they could both be non-nil. This 
> >>>> forces the developer to do needless and repetitive checks against a case 
> >>>> which in practice shouldn’t occur, as below:
> >>>>   
> >>>>  doSomething(foo: foo) { bar, error in
> >>>>  if let bar = bar {
> >>>>  // handle success case
> >>>>  } else if let error = error {
> >>>>  self.handleError(error)
> >>>>  } else {
> >>>>  self.handleError(NSCocoaError.FileReadUnknownError)
> >>>>  }
> >>>>  }
> >>>>   
> >>>>  This results in the dreaded “untested code.”
> >>>>   
> >>>>  Note that while it is possible that the developer could simply 
> >>>> force-unwrap error in the failure case, this leaves the programs open to 
> >>>> crashes in the case where a misbehaved API forgets to populate the error 
> >>>> on failure, whereas some kind of default error would be more 
> >>>> appropriate. The do/try/catch mechanism works around this by returning a 
> >>>> generic _NilError in cases where this occurs.
> >>>>   
> >>>>  PROPOSED SOLUTION:
> >>>>   
> >>>>  Since the pattern for an async API that returns an error in the Cocoa 
> >>>> APIs is very similar to the pattern for a synchronous one, we can handle 
> >>>> it in a very similar way. To do this, we introduce a new Result enum 
> >>>> type. We then bridge asynchronous Cocoa APIs to return this Result type 
> >>>> instead of optional values. This more clearly expresses to the user the 
> >>>> intent of the API.
> >>>>   
> >>>>  In addition to clarifying many Cocoa interfaces, this will provide a 
> >>>> standard format for asynchronous APIs that return errors, opening the 
> >>>> way for these APIs to be seamlessly integrated into future asynchronous 
> >>>> features added to Swift 4 and beyond, in a way that could seamlessly 
> >>>> interact with the do/try/catch feature as well.
> >>>>   
> >>>>  DETAILED DESIGN:
> >>>>   
> >>>>  1. We introduce a Result type, which looks like this:
> >>>>   
> >>>>  enum Result<T>  {
> >>>>  case success(T)
> >>>>  case error(Error)
> >>>>  }
> >>>>   
> >>>>  2. Methods that return one parameter asynchronously with an error are 
> >>>> bridged like this:
> >>>>   
> >>>>  func doSomething(foo: Foo, completionHandler: (Result<Bar>) ->  ())
> >>>>   
> >>>>  and are used like this:
> >>>>   
> >>>>  doSomething(foo: foo) { result in
> >>>>  switch result {
> >>>>  case let .success(bar):
> >>>>  // handle success
> >>>>  case let .error(error):
> >>>>  self.handleError(error)
> >>>>  }
> >>>>  }
> >>>>   
> >>>>  3. Methods that return multiple parameters asynchronously with an error 
> >>>> are bridged using a tuple:
> >>>>   
> >>>>  func doSomething(foo: Foo, completionHandler: (Result<(Bar, Baz)>) ->  
> >>>> ())
> >>>>   
> >>>>  and are used like this:
> >>>>   
> >>>>  doSomething(foo: foo) { result in
> >>>>  switch result {
> >>>>  case let .success(bar, baz):
> >>>>  // handle success
> >>>>  case let .error(error):
> >>>>  self.handleError(error)
> >>>>  }
> >>>>  }
> >>>>   
> >>>>  4. Methods that return only an error and nothing else are bridged as 
> >>>> they are currently, with the exception of bridging NSError to Error as 
> >>>> in SE-0112:
> >>>>   
> >>>>  func doSomething(foo: Foo, completionHandler: (Error?) ->  ())
> >>>>   
> >>>>  and are used as they currently are:
> >>>>   
> >>>>  doSomething(foo: foo) { error in
> >>>>  if let error = error {
> >>>>  // handle error
> >>>>  } else {
> >>>>  // handle success
> >>>>  }
> >>>>  }
> >>>>   
> >>>>  5. For the case in part 2, the bridge works much like the do/try/catch 
> >>>> mechanism. If the first parameter is non-nil, it is returned inside the 
> >>>> .success case. If it is nil, then the error is returned inside the 
> >>>> .error case if it is non-nil, and otherwise _NilError is returned in the 
> >>>> .error case.
> >>>>   
> >>>>  6. For the case in part 3, in which there are multiple return values, 
> >>>> the same pattern is followed, with the exception that we introduce a new 
> >>>> Objective-C annotation. I am provisionally naming this annotation 
> >>>> NS_REQUIRED_RETURN_VALUE, but the developer team can of course rename 
> >>>> this annotation to whatever they find appropriate. All parameters 
> >>>> annotated with NS_REQUIRED RETURN_VALUE will be required to be non-nil 
> >>>> in order to avoid triggering the error case. Parameters not annotated 
> >>>> with NS_REQUIRED RETURN_VALUE will be inserted into the tuple as 
> >>>> optionals. If there are no parameters annotated with NS_REQUIRED 
> >>>> RETURN_VALUE, the first parameter will be implicitly annotated as such. 
> >>>> This allows asynchronous APIs to continue to return optional secondary 
> >>>> values if needed.
> >>>>   
> >>>>  Thus, the following API:
> >>>>   
> >>>>  - (void)doSomethingWithFoo: (Foo *)foo completionHandler: (void (^)(Bar 
> >>>> * _Nullable NS_REQUIRED_RETURN_VALUE, Baz * _Nullable 
> >>>> NS_REQUIRED_RETURN_VALUE, NSError * _Nullable))completionHandler;
> >>>>   
> >>>>  is bridged as:
> >>>>   
> >>>>  func doSomething(foo: Foo, completionHandler: (Result<(Bar, Baz)>) ->  
> >>>> ())
> >>>>   
> >>>>  returning .success only if both the Bar and Baz parameters are non-nil, 
> >>>> whereas this API:
> >>>>   
> >>>>  - (void)doSomethingWithFoo: (Foo *)foo completionHandler: (void (^)(Bar 
> >>>> * _Nullable NS_REQUIRED_RETURN_VALUE, Baz * _Nullable, NSError * 
> >>>> _Nullable))completionHandler;
> >>>>   
> >>>>  is bridged as:
> >>>>   
> >>>>  func doSomething(foo: Foo, completionHandler: (Result<(Bar, Baz?)>) ->  
> >>>> ())
> >>>>   
> >>>>  returning .success whenever the Bar parameter is nil. An API containing 
> >>>> no parameter annotated with NS_REQUIRED_RETURN_VALUE will be bridged the 
> >>>> same as above.
> >>>>   
> >>>>  FUTURE DIRECTIONS:
> >>>>   
> >>>>  In the future, an asynchronous API returning a Result could be bridged 
> >>>> to an async function, should those be added in the future, using the 
> >>>> semantics of the do/try/catch mechanism. The bridging would be additive, 
> >>>> similarly to how Objective-C properties declared via manually written 
> >>>> accessor methods can nonetheless be accessed via the dot syntax. Thus,
> >>>>   
> >>>>  func doSomething(_ completionHandler: (Result<Foo>) ->  ())
> >>>>   
> >>>>  could be used as if it were declared like this:
> >>>>   
> >>>>  async func doSomething() throws ->  Foo
> >>>>   
> >>>>  and could be used like so:
> >>>>   
> >>>>  async func doSomethingBigger() {
> >>>>  do {
> >>>>  let foo = try await doSomething()
> >>>>   
> >>>>  // do something with foo
> >>>>  } catch {
> >>>>  // handle the error
> >>>>  }
> >>>>  }
> >>>>   
> >>>>  making asynchronous APIs convenient to write indeed.
> >>>>   
> >>>>  ALTERNATIVES CONSIDERED:
> >>>>   
> >>>>  Leaving the somewhat ambiguous situation as is.
> >>>>   
> >>>>  Charles
> >>>>   
> >>>>  _______________________________________________
> >>>>  swift-evolution mailing list
> >>>>   [email protected] (mailto:[email protected])
> >>>>   https://lists.swift.org/mailman/listinfo/swift-evolution
> >>>   
> >>   
> >>  _______________________________________________
> >>  swift-evolution mailing list
> >>   [email protected] (mailto:[email protected])
> >>   https://lists.swift.org/mailman/listinfo/swift-evolution
> >   
>
> _______________________________________________
> 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