[swift-evolution] async void
Yuta Koshizawa
koher at koherent.org
Fri Nov 10 03:38:05 CST 2017
> I’m not sure how the proposed design handles type checking for async
> closures. Is async part of the type? Can I declare a local closure variable
> as async? What are the rules for conversion between async and non-async
> closures? Is it a warning or error to use a closure literal without an async
> keyword that is assigned to an async closure variable or passed as an async
> closure argument?
It has been already realized for `throws`.
```
// This works in Swift 4
func foo(_ f: (Bar) throws -> Baz)
// This can be checked in the same way
func foo(_ f: (Bar) async -> Baz)
```
Proposed `async/await` in Swift are analogous to `throws/try`. So a
lot of things about `async/await` can be imagined when we think about
`throws/try`. It is also true for `(Foo) async -> Void`. We can use it
in the same way as we use `(Foo) throws -> Void`.
`async/await` as an analogy to `throws/try` works well because both of
them can be mapped to monads. `throws` is similar to `Result` and
`async` is similar to `Promise` ( `Future` ).
```
// `a` and `b` are similar
func a() throws -> Int
func b() -> Result<Int>
// `c` and `d` are similar
func c() async -> Int
func d() -> Promise<Int>
// `a` : `b` == `c` : `d`
// `a` : `c` == `b` : `d`
```
`try` and `await` are also similar to `flatMap`. ( I think most
popular `Promise` is one in JavaScript. Although it does not have
`flatMap`, its `then` method can be considered as `flatMap`. )
```
let x = try a()
// uses `x` here
b().flatMap { x in
// uses `x` here
}
let y = await c()
// uses `y` here
d().flatMap { y in
// uses `y` here
}
```
So `throws` : `try` : `Result` == `async` : `await` : `Promise` and
`throws` : `async` == `try` : `await` == `Result` : `Promise`. I think
those relations are beautiful and proposed `async/await` fits well to
Swift because we have already had `throws/try`.
--
Yuta
2017-11-10 6:45 GMT+09:00 Adam Kemp via swift-evolution
<swift-evolution at swift.org>:
>
> On Nov 9, 2017, at 11:02 AM, Wallacy <wallacyf at gmail.com> wrote:
>
> So for me, this:
>
> func OnButtonClicked(_ sender:AnyObject) {
>
> let button = sender as! UIButton
> button.isEnabled = false
> beginAsync {
> await DoSomethingAsync()
> button.isEnabled = true
> }
> }
>
>
> Does not make any sense... Because await will not block the thread we can
> assume (like the exemple on proposal) that compiler will actually do the
> same what we will do using GDC and pick everyone to until the context ends
> and encapsulate as completion handle to the away call.
>
>
> I don’t understand what you’re saying here. In terms of GCD the above code
> is basically equivalent to this:
>
> func buttonClicked(_ sender:AnyObject) {
> let button = sender as! UIButton
> button.isEnabled = false
> doSomethingAsync { // completion callback, assume it’s on the main queue
> button.isEnabled = true
> }
> }
>
>
> And this one:
>
> @IBAction func buttonDidClick(sender:AnyObject) {
> beginAsync {
> let image = await processImageData()
> // Do the update on the main thread/queue since it owns imageView.
> mainQ.async {
> imageView.image = image
> }
> }
> }
>
>
>
> Does not make any sense too.
>
> The only way to await to do not block the thread is make a early return like
> beginAsync and encapsulate as completion handle the rest of the code.
>
>
> This is why “await” can only be used in a function that is marked as
> “async”. The “async” keyword tells the compiler that this function will be
> broken up into parts, and its return value will be produced asynchronously.
>
> One thing that might be confusing is that in the examples using “beginAsync”
> the trailing closure is the async function. That’s not obvious because
> there’s no “async” keyword, but it’s there in the signature of the closure
> argument:
>
> func beginAsync(_ body: () async throws -> Void) rethrows -> Void
>
>
> I’m not sure how the proposed design handles type checking for async
> closures. Is async part of the type? Can I declare a local closure variable
> as async? What are the rules for conversion between async and non-async
> closures? Is it a warning or error to use a closure literal without an async
> keyword that is assigned to an async closure variable or passed as an async
> closure argument?
>
> C# dodges all of these issues because async isn't part of the type system.
> Closures that don’t return anything can be declared async just like void
> functions, and code that uses void-returning closures doesn’t need to care
> whether the implementation is async or not.
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
More information about the swift-evolution
mailing list