Re: [swift-evolution] [Concurrency] Fixing race conditions in async/await example

2017-08-25 Thread Howard Lovatt via swift-evolution
My argument goes like this:

  1. You don't need async/await to write a powerful future type; you can
use the underlying threads just as well, i.e. future with async/await is no
better than future without.

  2. Since future is more powerful, thread control, cancel, and timeout,
people should be encouraged to use this; instead because async/await are
language features they will be presumed, incorrectly, to be the best way,
consequently people will get into trouble with deadlocks because they don't
have control.

  3. async/await will require some engineering work and will at best make a
mild syntax improvement and at worst lead to deadlocks, therefore they just
don't carry their weight in terms of useful additions to Swift.

Therefore, save some engineering effort and just provide a future library.

To turn the question round another way, in two forms:

  1. What can async/wait do that a future can't?

  2. How will future be improved if async/await is added?


  -- Howard.

On 26 August 2017 at 02:23, Joe Groff  wrote:

>
> On Aug 25, 2017, at 12:34 AM, Howard Lovatt 
> wrote:
>
>  In particular a future that is cancellable is more powerful that the
> proposed async/await.
>
>
> It's not more powerful; the features are to some degree disjoint. You can
> build a Future abstraction and then use async/await to sugar code that
> threads computation through futures. Getting back to Jakob's example,
> someone (maybe the Clang importer, maybe Apple's framework developers in an
> overlay) will still need to build infrastructure on top of IBActions and
> other currently ad-hoc signalling mechanisms to integrate them into a more
> expressive coordination framework.
>
> -Joe
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Howard Lovatt via swift-evolution
I think we would be better off with a future type rather than async/await
since they can offer timeout, cancel, and control over which thread
execution occurs on.

  -- Howard.

On 26 August 2017 at 00:06, Cavelle Benjamin via swift-evolution <
swift-evolution@swift.org> wrote:

> Disclaimer: not an expert
>
> Question
> I didn’t see any where the async is required to time out after a certain
> time frame. I would think that we would want to specify both on the
> function declaration side as a default and on the function call side as a
> customization. That being said, the return time then becomes an optional
> given the timeout and the calling code would need to unwrap.
>
> func loadWebResource(_ path: String) async -> Resourcefunc decodeImage(_ r1: 
> Resource, _ r2: Resource) async -> Imagefunc dewarpAndCleanupImage(_ i : 
> Image) async -> Image
> func processImageData1() async -> Image {
> let dataResource  = await loadWebResource("dataprofile.txt")
> let imageResource = await loadWebResource("imagedata.dat")
> let imageTmp  = await decodeImage(dataResource, imageResource)
> let imageResult   = await dewarpAndCleanupImage(imageTmp)
> return imageResult
> }
>
>
>
> So the prior code becomes…
>
> func loadWebResource(_ path: String) async(timeout: 1000) -> Resource?func 
> decodeImage(_ r1: Resource, _ r2: Resource) async -> Image?func 
> dewarpAndCleanupImage(_ i : Image) async -> Image?
> func processImageData1() async -> Image? {
> let dataResource  = guard let await loadWebResource("dataprofile.txt”) 
> else { // handle timeout }
> let imageResource = guard let await(timeout: 100) 
> loadWebResource("imagedata.dat”) else { // handle timeout }
> let imageTmp  = await decodeImage(dataResource, imageResource)
> let imageResult   = await dewarpAndCleanupImage(imageTmp)
> return imageResult
> }
>
>
>
> Given this structure, the return type of all async’s would be optionals
> with now 3 return types??
>
> .continuation // suspends and picks back up
> .value // these are the values we are looking for
> .none // took too long, so you get nothing.
>
>
>
> On 2017-Aug -17 (34), at 18:24, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi all,
>
> As Ted mentioned in his email, it is great to finally kick off discussions
> for what concurrency should look like in Swift.  This will surely be an
> epic multi-year journey, but it is more important to find the right design
> than to get there fast.
>
> I’ve been advocating for a specific model involving async/await and actors
> for many years now.  Handwaving only goes so far, so some folks asked me to
> write them down to make the discussion more helpful and concrete.  While I
> hope these ideas help push the discussion on concurrency forward, this
> isn’t in any way meant to cut off other directions: in fact I hope it helps
> give proponents of other designs a model to follow: a discussion giving
> extensive rationale, combined with the long term story arc to show that the
> features fit together.
>
> Anyway, here is the document, I hope it is useful, and I’d love to hear
> comments and suggestions for improvement:
> https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782
>
> -Chris
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Howard Lovatt via swift-evolution
I just don't see that async/await adds enough to warrant a language change.
You can write Future on top of GCD and a future type can do more, like
having a cancel, having a timeout, and giving control over what thread is
used.

  -- Howard.

On 26 August 2017 at 10:57, Florent Vilmart via swift-evolution <
swift-evolution@swift.org> wrote:

> Isn’t async / await an evolution over Promises / Tasks / Futures? AFAIK in
> JS, any function that returns a promise can be ‘await’ upon, and
> underneath, to be able to await, a function has to return a promise.
> Marking a function async in JS, tells the consumer that some await are
> going on inside, and it’s impossible to use await outside of an async
> marked function. I believe swift is going that direction too. Futures /
> Promises are the foundation on which async / await can truly express as it
> formalizes the boxing of the result types.
> What would be interesting is async being based on a protocol FutureType
> for example, so you can bring your own library and yet, leverage async /
> await
>
> On Aug 25, 2017, 20:50 -0400, Jonathan Hull , wrote:
>
>
> On Aug 25, 2017, at 3:38 PM, Trevör Anne Denise <
> trevor.anneden...@icloud.com> wrote:
>
> =
>
> Jonathan Hull jhull at gbis.com
>
> This looks somewhat similar to a future, but you can’t interact with it as
> a separate type of object.  The value above is just a UIImage, but with a
> compiler flag/annotation that forces me to call await on it before it can
> be accessed/used.  The compiler has a lot more freedom to
> optimize/reorganize things behind the scenes, because it doesn’t
> necessarily need to make an intermediate object.
>
>
> As for the message of Wallacy I'd be interested the pros and cons of
> hiding the implementation details ! :)
>
>
> To prove (or potentially disprove) my assertion that this is not just
> sugar, how would you accomplish the following under the current proposal?
>
> let a = async longCalculationA()
> let b = async longCalculationB() //b doesn’t wait for a to complete before
> starting
> let c = async longCalculationC() //c doesn’t wait for a or b
> let result = await combineCalculations(a: a, b: b, c: c) //waits until a,
> b, and c are all available
>
>
> Would this be implemented differently than with Futures? I don't have much
> experience with concurrency, but I don't see how this would be handled
> differently than by using Futures, internally ? (at least for this case)
>
>
> It looks/behaves very similar to futures, but would potentially be
> implemented differently.  The main difference is that the resulting type is
> actually the desired type (instead of Future) with a compiler flag
> saying that it needs to call await to be used.  Behind the scenes, this
> could be implemented as some sort of future, but the compiler has a lot
> more freedom to rearrange things to be much more efficient because there is
> no affordance for the user to introspect or cancel. So for example, it
> might actually change:
>
> let image = async downloadImage()
> let size = await image.size
>
> to:
>
> let size = await downloadImage().size
>
> This would depend on the other code around it, but the compiler has much
> more freedom to avoid creating intermediate values, or even to create
> different types of intermediate values which are more efficient for the
> situation at hand.
>
> Given that as a base, it would be trivial to create a framework offering
> true Futures (which allow cancelling, etc…)
>
> Thanks,
> Jon
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Florent Vilmart via swift-evolution
Isn’t async / await an evolution over Promises / Tasks / Futures? AFAIK in JS, 
any function that returns a promise can be ‘await’ upon, and underneath, to be 
able to await, a function has to return a promise. Marking a function async in 
JS, tells the consumer that some await are going on inside, and it’s impossible 
to use await outside of an async marked function. I believe swift is going that 
direction too. Futures / Promises are the foundation on which async / await can 
truly express as it formalizes the boxing of the result types.
What would be interesting is async being based on a protocol FutureType for 
example, so you can bring your own library and yet, leverage async / await

On Aug 25, 2017, 20:50 -0400, Jonathan Hull , wrote:
>
> > On Aug 25, 2017, at 3:38 PM, Trevör Anne Denise 
> >  wrote:
> >
> > =
> > > Jonathan Hull jhull at gbis.com
> > > This looks somewhat similar to a future, but you can’t interact with it 
> > > as a separate type of object.  The value above is just a UIImage, but 
> > > with a compiler flag/annotation that forces me to call await on it before 
> > > it can be accessed/used.  The compiler has a lot more freedom to 
> > > optimize/reorganize things behind the scenes, because it doesn’t 
> > > necessarily need to make an intermediate object.
> >
> > As for the message of Wallacy I'd be interested the pros and cons of hiding 
> > the implementation details ! :)
> >
> >
> > > To prove (or potentially disprove) my assertion that this is not just 
> > > sugar, how would you accomplish the following under the current proposal?
> > >
> > > let a = async longCalculationA()
> > > let b = async longCalculationB() //b doesn’t wait for a to complete 
> > > before starting
> > > let c = async longCalculationC() //c doesn’t wait for a or b
> > > let result = await combineCalculations(a: a, b: b, c: c) //waits until a, 
> > > b, and c are all available
> >
> > Would this be implemented differently than with Futures? I don't have much 
> > experience with concurrency, but I don't see how this would be handled 
> > differently than by using Futures, internally ? (at least for this case)
> >
>
> It looks/behaves very similar to futures, but would potentially be 
> implemented differently.  The main difference is that the resulting type is 
> actually the desired type (instead of Future) with a compiler flag 
> saying that it needs to call await to be used.  Behind the scenes, this could 
> be implemented as some sort of future, but the compiler has a lot more 
> freedom to rearrange things to be much more efficient because there is no 
> affordance for the user to introspect or cancel. So for example, it might 
> actually change:
>
> let image = async downloadImage()
> let size = await image.size
>
> to:
>
> let size = await downloadImage().size
>
> This would depend on the other code around it, but the compiler has much more 
> freedom to avoid creating intermediate values, or even to create different 
> types of intermediate values which are more efficient for the situation at 
> hand.
>
> Given that as a base, it would be trivial to create a framework offering true 
> Futures (which allow cancelling, etc…)
>
> Thanks,
> Jon
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Jonathan Hull via swift-evolution

> On Aug 25, 2017, at 3:38 PM, Trevör Anne Denise 
>  wrote:
> 
> =
>> Jonathan Hull jhull at gbis.com  
> 
>> This looks somewhat similar to a future, but you can’t interact with it as a 
>> separate type of object.  The value above is just a UIImage, but with a 
>> compiler flag/annotation that forces me to call await on it before it can be 
>> accessed/used.  The compiler has a lot more freedom to optimize/reorganize 
>> things behind the scenes, because it doesn’t necessarily need to make an 
>> intermediate object.
> 
> 
> As for the message of Wallacy I'd be interested the pros and cons of hiding 
> the implementation details ! :)
> 
> 
>> To prove (or potentially disprove) my assertion that this is not just sugar, 
>> how would you accomplish the following under the current proposal?
>> 
>>  let a = async longCalculationA()
>>  let b = async longCalculationB() //b doesn’t wait for a to complete 
>> before starting
>>  let c = async longCalculationC() //c doesn’t wait for a or b
>>  let result = await combineCalculations(a: a, b: b, c: c) //waits until 
>> a, b, and c are all available
> 
> 
> Would this be implemented differently than with Futures? I don't have much 
> experience with concurrency, but I don't see how this would be handled 
> differently than by using Futures, internally ? (at least for this case)
> 

It looks/behaves very similar to futures, but would potentially be implemented 
differently.  The main difference is that the resulting type is actually the 
desired type (instead of Future) with a compiler flag saying that it 
needs to call await to be used.  Behind the scenes, this could be implemented 
as some sort of future, but the compiler has a lot more freedom to rearrange 
things to be much more efficient because there is no affordance for the user to 
introspect or cancel. So for example, it might actually change:

let image = async downloadImage()
let size = await image.size

to:

let size = await downloadImage().size

This would depend on the other code around it, but the compiler has much more 
freedom to avoid creating intermediate values, or even to create different 
types of intermediate values which are more efficient for the situation at hand.

Given that as a base, it would be trivial to create a framework offering true 
Futures (which allow cancelling, etc…)

Thanks,
Jon

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Adam Kemp via swift-evolution
I’m not sure I understand. What is the connection between references and 
deadlocks?

> On Aug 25, 2017, at 1:07 PM, Marc Schlichte  
> wrote:
> 
> 
>> Am 25.08.2017 um 19:08 schrieb Adam Kemp via swift-evolution 
>> >:
>> 
>> I understand what you’re saying, but I just think trying to make 
>> synchronous, blocking actor methods goes against the fundamental ideal of 
>> the actor model, and it’s a recipe for disaster. When actors communicate 
>> with each other that communication needs to be asynchronous or you will get 
>> deadlocks. It’s not just going to be a corner case. It’s going to be a very 
>> frequent occurrence.
>> 
>> One of the general rules of multithreaded programming is “don’t call unknown 
>> code while holding a lock”. Blocking a queue is effectively the same as 
>> holding a lock, and calling another actor is calling unknown code. So if the 
>> model works that way then the language itself will be encouraging people to 
>> call unknown code while holding locks. That is not going to go well.
>> 
> 
> I would claim - without having a prove though - that as long as you don’t 
> invoke async actor methods on weak or unowned actor references and the code 
> is retain cycle free, no deadlocks will happen.
> 
> Cheers
> Marc
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving KeyPath

2017-08-25 Thread Joe Groff via swift-evolution
> On Aug 25, 2017, at 3:54 PM, Logan Shire  wrote:
> 
> How would you feel about wrapping the existing functions on 
> _KVOKeyPathBridgeMachinery:
> 
> @nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:AnyKeyPath) -> 
> String
> @nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:String?) -> 
> AnyKeyPath?
> 
> In extensions on String and AnyKeyPath respectively to instantiate strings 
> from KeyPaths and KeyPaths from Strings?

Those functions are designed for Cocoa interop only. They're not going to 
produce results that make sense for all Swift key paths.


-Joe

> https://github.com/apple/swift/blob/c5ff1f2cac8da6a14330f4b033b94c7c926d2126/stdlib/public/SDK/Foundation/NSObject.swift#L84
>  
> 
> 
> On Fri, Aug 25, 2017 at 11:43 AM Joe Groff  > wrote:
> 
> > On Aug 23, 2017, at 11:18 PM, Logan Shire via swift-evolution 
> > > wrote:
> >
> > Hey folks!
> >
> > Recently I’ve been working on a small library which leverages the Swift 4 
> > Codable protocol
> > and KeyPaths to provide a Swift-y interface to CoreData. (It maps back and 
> > forth between
> > native, immutable Swift structs and NSManagedObjects). In doing so I found 
> > a couple of
> > frustrating limitations to the KeyPath API. Firstly, KeyPath does not 
> > provide the name of the
> > property on the type it indexes. For example, if I have a struct:
> >
> >
> > struct Person {
> >let firstName: String
> >let lastName: String
> > }
> >
> > let keyPath = \Person.firstName
> >
> >
> > But once I have a keyPath, I can’t actually figure out what property it 
> > accesses.
> > So, I wind up having to make a wrapper:
> >
> >
> > struct Attribute {
> >let keyPath: AnyKeyPath
> >let propertyName: String
> > }
> >
> > let firstNameAttribute = Attribute(keyPath: \Person.firstName, 
> > propertyName: “firstName”)
> >
> >
> > This forces me to write out the property name myself as a string which is 
> > very error prone.
> > All I want is to be able to access:
> >
> >
> > keyPath.propertyName // “firstName”
> >
> >
> > It would also be nice if we provided the full path as a string as well:
> >
> >
> > keyPath.fullPath // “Person.firstName"
> >
> >
> > Also, if I want to get all of the attributes from a given Swift type, my 
> > options are to try to hack
> > something together with Mirrors, or forcing the type to declare a function 
> > / computed property
> > returning an array of all of its key path / property name pairings. I would 
> > really like to be able to
> > retrieve a type-erased array of any type’s key paths with:
> >
> >
> > let person = Person(firstName: “John”, lastName: “Doe”)
> > let keyPaths = Person.keyPaths
> > let firstNameKeyPath = keyPaths.first { $0.propertyName = “firstName” } as! 
> > KeyPath
> > let firstName = person[keypath: firstNameKeyPath] // “John"
> >
> >
> > And finally, without straying too far into Objective-C land, it would be 
> > nice if we could initialize key paths
> > with a throwing initializer.
> >
> >
> > let keyPath = try Person.keyPath(“firstName”) // KeyPath 
> > type erased to AnyKeyPath
> > let keyPath = AnyKeyPath(“Person.firstName”)
> >
> >
> > Let me know what you think about any / all of these suggestions!
> 
> These would all be great additional features to eventually add to key paths. 
> I think reflection mechanisms centered on key paths like what you describe 
> would be a superior replacement for most of what Mirror attempts to provide.
> 
> -Joe

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving KeyPath

2017-08-25 Thread Logan Shire via swift-evolution
How would you feel about wrapping the existing functions
on _KVOKeyPathBridgeMachinery:

@nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:AnyKeyPath) ->
String
@nonobjc fileprivate static func _bridgeKeyPath(_ keyPath:String?) ->
AnyKeyPath?

In extensions on String and AnyKeyPath respectively to instantiate strings
from KeyPaths and KeyPaths from Strings?

https://github.com/apple/swift/blob/c5ff1f2cac8da6a14330f4b033b94c7c926d2126/stdlib/public/SDK/Foundation/NSObject.swift#L84

On Fri, Aug 25, 2017 at 11:43 AM Joe Groff  wrote:

>
> > On Aug 23, 2017, at 11:18 PM, Logan Shire via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > Hey folks!
> >
> > Recently I’ve been working on a small library which leverages the Swift
> 4 Codable protocol
> > and KeyPaths to provide a Swift-y interface to CoreData. (It maps back
> and forth between
> > native, immutable Swift structs and NSManagedObjects). In doing so I
> found a couple of
> > frustrating limitations to the KeyPath API. Firstly, KeyPath does not
> provide the name of the
> > property on the type it indexes. For example, if I have a struct:
> >
> >
> > struct Person {
> >let firstName: String
> >let lastName: String
> > }
> >
> > let keyPath = \Person.firstName
> >
> >
> > But once I have a keyPath, I can’t actually figure out what property it
> accesses.
> > So, I wind up having to make a wrapper:
> >
> >
> > struct Attribute {
> >let keyPath: AnyKeyPath
> >let propertyName: String
> > }
> >
> > let firstNameAttribute = Attribute(keyPath: \Person.firstName,
> propertyName: “firstName”)
> >
> >
> > This forces me to write out the property name myself as a string which
> is very error prone.
> > All I want is to be able to access:
> >
> >
> > keyPath.propertyName // “firstName”
> >
> >
> > It would also be nice if we provided the full path as a string as well:
> >
> >
> > keyPath.fullPath // “Person.firstName"
> >
> >
> > Also, if I want to get all of the attributes from a given Swift type, my
> options are to try to hack
> > something together with Mirrors, or forcing the type to declare a
> function / computed property
> > returning an array of all of its key path / property name pairings. I
> would really like to be able to
> > retrieve a type-erased array of any type’s key paths with:
> >
> >
> > let person = Person(firstName: “John”, lastName: “Doe”)
> > let keyPaths = Person.keyPaths
> > let firstNameKeyPath = keyPaths.first { $0.propertyName = “firstName” }
> as! KeyPath
> > let firstName = person[keypath: firstNameKeyPath] // “John"
> >
> >
> > And finally, without straying too far into Objective-C land, it would be
> nice if we could initialize key paths
> > with a throwing initializer.
> >
> >
> > let keyPath = try Person.keyPath(“firstName”) // KeyPath
> type erased to AnyKeyPath
> > let keyPath = AnyKeyPath(“Person.firstName”)
> >
> >
> > Let me know what you think about any / all of these suggestions!
>
> These would all be great additional features to eventually add to key
> paths. I think reflection mechanisms centered on key paths like what you
> describe would be a superior replacement for most of what Mirror attempts
> to provide.
>
> -Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread BJ Homer via swift-evolution
> I'm not sure why it's understood as all or nothing, AFAICU, await is just a 
> way to block the current queue and wait for a result from an async function.
> beginAsync is a way to make sure we don't block the current execution queue.

Await does not block the current queue. You can imagine that it gathers up the 
rest of the function after the ‘await’ line and moves it into a callback. That 
is, it turns this:

let x = await somethingThatTakesALongTime()
print(“Congratulations, we got x”)
print(“x: \(x)”)

into something like this:

somethingThatTakesALongTime(completion: { (x) in
   print(“Congratulations, we got x”)
   print(“x: \(x)”)
})

It does not block the current queue, though. The current queue keeps going on 
with whatever it was doing before. When the ‘await'ed call finished, it is 
scheduled back on a queue to continue running.

-BJ

> On Aug 25, 2017, at 4:39 PM, Florent Vilmart via swift-evolution 
>  wrote:
> 
> 
> On 25 août 2017 18:31 -0400, Jonathan Hull , wrote:
>> But then it would need to be called with await under the current proposal, 
>> meaning that either:
>> 
>> • b would await the calculation of a
>> 
>> beginAsync {
>> let a = await longCalculationA()
>> let b = await longCalculationB() //This only calculates when a is finished
>> } 
> why would it? the async modifier could very well be used to transform a sync 
> function into an async one, dispatching on a defined queue returning the 
> 'Future' and resolving once the function completes.
> 
> I'm not sure why it's understood as all or nothing, AFAICU, await is just a 
> way to block the current queue and wait for a result from an async function.
> beginAsync is a way to make sure we don't block the current execution queue.
> 
> something like
> 
> let a = await async longSynchrounousCall() would block the current execution 
> queue (because await) but the execution of the longSynchronousCall() would be 
> on a separate queue / block.
> 
> The question lays more in where the calls are executed, either they are 
> dispatched after, current block is suspended, runloop continues, and then the 
> block is re-entered upon returning.  that would lead to some weird executions 
> flows.
> 
>> 
>> • or b would be executed while a is awaiting, but a and b would be in 
>> different scopes
>> 
>> beginAsync{
>> let a = await longCalculationA()
>> }
>> beginAsync{
>> let b = await longCalculationB() //We can’t see ‘a’ anymore
>> }
>> //We can’t see ‘a’ or ‘b’ here to use them
>> 
>> We could, also implement some sort of future, and then re-write our 
>> functions to take advantage of it, but this misses out on numerous compiler 
>> optimizations and requires our functions to be written with futures in mind. 
>>  In my example, the functions can just be written as async, and they don’t 
>> care whether they are called with async or await.
>> 
>> Thanks,
>> Jon
>> 
>>> On Aug 25, 2017, at 3:13 PM, Florent Vilmart >> > wrote:
>>> 
>>> be doesn't wait if it's defined as 
>>> 
>>> func longCalculationB() async -> SomeType 
>>> 
>>> which would be helpful if it's a long calculation, 
>>> 
>>> in the case it's
>>> 
>>> func longCalculationB() -> SomeType 
>>> 
>>> That would probably be valid to put the async keyword front even though I 
>>> would not be a big fan of that as you'd be executing on an indefinite queue 
>>> a calculation that may not be thread safe.
>>> 
>>> async would be in that case a wrapper around dispatch_async  + semaphore
>>> 
>>> 
>>> On 25 août 2017 18:08 -0400, Jonathan Hull >> >, wrote:
 Why wouldn’t b wait for a in this example?  If it is using futures, those 
 aren’t available in the current proposal.
 
> On Aug 25, 2017, at 3:02 PM, Florent Vilmart  > wrote:
> 
> Probably with:
> 
> let a = longCalculationA() 
> let b = longCalculationB() //b doesn’t wait for a to complete before 
> starting
> let c = longCalculationC() //c doesn’t wait for a or b
> let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits 
> until a, b, and c are all available
> 
> On 25 août 2017 17:48 -0400, wrote:
>> 
>> let a = async longCalculationA()
>> let b = async longCalculationB() //b doesn’t wait for a to complete 
>> before starting
>> let c = async longCalculationC() //c doesn’t wait for a or b
>> let result = await combineCalculations(a: a, b: b, c: c) //waits until 
>> a, b, and c are all available
 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Florent Vilmart via swift-evolution

On 25 août 2017 18:31 -0400, Jonathan Hull , wrote:
> But then it would need to be called with await under the current proposal, 
> meaning that either:
>
> • b would await the calculation of a
>
> beginAsync {
> let a = await longCalculationA()
> let b = await longCalculationB() //This only calculates when a is finished
> }
why would it? the async modifier could very well be used to transform a sync 
function into an async one, dispatching on a defined queue returning the 
'Future' and resolving once the function completes.

I'm not sure why it's understood as all or nothing, AFAICU, await is just a way 
to block the current queue and wait for a result from an async function.
beginAsync is a way to make sure we don't block the current execution queue.

something like

let a = await async longSynchrounousCall() would block the current execution 
queue (because await) but the execution of the longSynchronousCall() would be 
on a separate queue / block.

The question lays more in where the calls are executed, either they are 
dispatched after, current block is suspended, runloop continues, and then the 
block is re-entered upon returning.  that would lead to some weird executions 
flows.

>
> • or b would be executed while a is awaiting, but a and b would be in 
> different scopes
>
> beginAsync{
> let a = await longCalculationA()
> }
> beginAsync{
> let b = await longCalculationB() //We can’t see ‘a’ anymore
> }
> //We can’t see ‘a’ or ‘b’ here to use them
>
> We could, also implement some sort of future, and then re-write our functions 
> to take advantage of it, but this misses out on numerous compiler 
> optimizations and requires our functions to be written with futures in mind.  
> In my example, the functions can just be written as async, and they don’t 
> care whether they are called with async or await.
>
> Thanks,
> Jon
>
> > On Aug 25, 2017, at 3:13 PM, Florent Vilmart  wrote:
> >
> > be doesn't wait if it's defined as
> >
> > func longCalculationB() async -> SomeType
> >
> > which would be helpful if it's a long calculation,
> >
> > in the case it's
> >
> > func longCalculationB() -> SomeType
> >
> > That would probably be valid to put the async keyword front even though I 
> > would not be a big fan of that as you'd be executing on an indefinite queue 
> > a calculation that may not be thread safe.
> >
> > async would be in that case a wrapper around dispatch_async  + semaphore
> >
> >
> > On 25 août 2017 18:08 -0400, Jonathan Hull , wrote:
> > > Why wouldn’t b wait for a in this example?  If it is using futures, those 
> > > aren’t available in the current proposal.
> > >
> > > > On Aug 25, 2017, at 3:02 PM, Florent Vilmart  
> > > > wrote:
> > > >
> > > > Probably with:
> > > >
> > > > let a = longCalculationA()
> > > > let b = longCalculationB() //b doesn’t wait for a to complete before 
> > > > starting
> > > > let c = longCalculationC() //c doesn’t wait for a or b
> > > > let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits 
> > > > until a, b, and c are all available
> > > >
> > > > On 25 août 2017 17:48 -0400, wrote:
> > > > >
> > > > > let a = async longCalculationA()
> > > > > let b = async longCalculationB() //b doesn’t wait for a to complete 
> > > > > before starting
> > > > > let c = async longCalculationC() //c doesn’t wait for a or b
> > > > > let result = await combineCalculations(a: a, b: b, c: c) //waits 
> > > > > until a, b, and c are all available
> > >
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread BJ Homer via swift-evolution
> how would you accomplish the following under the current proposal?


We could implement a Future type (as imagined in the async/await proposal), 
which would enable something like this:

let futureA = Future { await longCalculationA() }
let futureB = Future { await longCalculationB() }
let futureC = Future { await longCalculationC() }

// Asynchronously waits for a, b, and c to finish before calling 
combineCalculations()
let result = await combineCalculations(a: a.get(), b: b.get(), c: 
c.get()) 

If there's no Future type around, it's reasonable to imagine that 
DispatchQueue.async would be modified to accept an 'async' closure, so you 
could do this:

let group = DispatchGroup()
let queue = DisatchQueue.global()

var a: Any? = nil
var b: Any? = nil
var c: Any? = nil

group.enter()
queue.async {
a = await longCalculationA()
group.leave()
}

group.enter()
queue.async {
b = await longCalculationB()
group.leave()
}

group.enter()
queue.async {
c = await longCalculationC()
group.leave()
}

group.notify {
combineCalculations(a: a, b: b, c: c)
}

A Future type certainly makes this look nicer, though.

-BJ

> On Aug 25, 2017, at 3:49 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> To prove (or potentially disprove) my assertion that this is not just sugar, 
> how would you accomplish the following under the current proposal?
> 
>   let a = async longCalculationA()
>   let b = async longCalculationB() //b doesn’t wait for a to complete 
> before starting
>   let c = async longCalculationC() //c doesn’t wait for a or b
>   let result = await combineCalculations(a: a, b: b, c: c) //waits until 
> a, b, and c are all available
> 
> (Note: this is using my version of async below which doesn’t use futures)
> 
> Thanks,
> Jon
> 
> 
>> On Aug 25, 2017, at 2:13 PM, Jonathan Hull via swift-evolution 
>> > wrote:
>> 
>> I actually really like the idea of using ‘async' to start a computation in a 
>> non-blocking way.  It is extremely common in real-world code to want to 
>> start a few computations/downloads at once in the background and then use 
>> the results together...
>> 
>> I think full-fledged futures could be a framework thing added on top, but 
>> what I would really love to see at the language level is that using ‘async’ 
>> just allows you to defer calling ‘await’.  That is, you could get a value 
>> back from something called with async, but you would be forced to await that 
>> value before it could be used:
>> 
>>  var image = async downloadImage()  //Image is type UIImage
>>  //Do something else here
>>  let size = await image.size //The compiler forces me to call await 
>> before I can actually use the value
>> 
>> This looks somewhat similar to a future, but you can’t interact with it as a 
>> separate type of object.  The value above is just a UIImage, but with a 
>> compiler flag/annotation that forces me to call await on it before it can be 
>> accessed/used.  The compiler has a lot more freedom to optimize/reorganize 
>> things behind the scenes, because it doesn’t necessarily need to make an 
>> intermediate object.
>> 
>> I don’t think this is just sugar.  It adds expressivity and control for a 
>> set of very common use-cases which aren’t fully supported by await alone.
>> 
>> Thanks,
>> Jon
>> 
>> 
>>> On Aug 24, 2017, at 4:40 AM, Trevör ANNE DENISE via swift-evolution 
>>> > wrote:
>>> 
>>> Hello Swift community,
>>> 
>>> I was really interested by the recent Task-based concurrency manifesto and 
>>> Concrete proposal for async semantics in Swift.
>>> 
>>> Looking at beginAsync() and Futures, I had an idea for a new syntax based 
>>> on the `async` keyword, I'd love to hear your feedback about this idea:
>>> https://github.com/adtrevor/Swift-ideas/blob/master/New%20async%20keyword%20usage.md
>>>  
>>> 
>>> 
>>> Would such a syntax make any sense?
>>> 
>>> Thank you ! :)
>>> 
>>> 
>>> Trevör
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing 

Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Trevör Anne Denise via swift-evolution
First of all, thank you to everyone for reacting ! :)




Taking the messages in chronological order :

> Wallacy  
> Interesting, its syntax seems to improve the "fire and forget" issue.
> 
> @IBAction func buttonClicked() {
>   async downloadAndUpdateImageView()
> }

While this could be nice it would indeed not be needed in this case @IBAction 
methods were async as Chris Lattner says.

> func SomethingUsingUser() -> Void {
>   var user = await getUser() //Only here
>   printf(user.age > 21 ? "Let's Drink" : "See you later!")


I don't have a lot of experience with async await syntaxes, but if I understand 
correctly the proposal and the way async/await works, doing that inside of a 
non-async function would be problematic as this would block the thread and 
wouldn't clearly show that calling your function would be blocking (being 
forced to marked a function as async and the imposed language syntax at call 
site fixes this issue).
That's why I only proposed "async outside of await" and not "await outside of 
async", because async outside of await would still enable the compiler to 
prevent issues like the aforementioned one thanks to a Future like behaviour.





=


> Chris Lattner  
> 
> Yes, it is entirely possible that we will want to provide more syntactic 
> sugar than the proposal suggests: the proposal is intentionally designed to 
> be minimal, so we can get it in place, get experience using it, then decide 
> whether any specific syntactic pain point is significant enough to be worth 
> adding additional sugar/complexity.
> 
> As has been mentioned in other threads, the hope is that “beginAsync” is 
> actually extremely rare in practice.  If that is the case, there is little 
> point to sugaring it.
> 
> -Chris


The second part of my proposition is indeed more syntactic sugar if beginAsync 
ends up being rarely used in practice, but about the first part of my 
explanation (using async inside of async functions to provide a future like 
syntax), would it enable to both to drastically reduce the syntactic complexity 
of async/await and to hide away implementation giving more freedom for future 
Swift releases as Wallacy and Jonathan Hull suggested?

Thank you ! :)



=
> Wallacy > 
> Using only async/await is pretty easy to learn and teach.
> And after that, "Future" can be implement in any way because will not be a
> public API anymore (I do not know, but there may also be some opportunities
> for optimization as well), and we only need to care about when we need to
> "keep the reference" from some async call.
> 
> And possibly, they will not need to create any Future type! The variable
> type will be "async User" as long as it is not "unwrapped". (
> suspend/defer/abandon still possible)

Using async at call site would indeed (in my opinion) make async/await easier 
to learn (especially given the parallel with optional unwrapping and 
similarities with other behaviours of Swift, including possible async vars of 
Actors maybe?).

I'd be interested to know what would be the ramifications of promoting async at 
type level as you propose, what would be the pros and cons of such an approach 
? I'd be interested to get other opinions about it ! :)

In my first idea async at call site would be synthesising a Future just as 
T? synthesises Optional, but I'd be interested to know too if hiding 
implementation details would have any advantages for the future of Swift ? 
Making things more flexible maybe?




=
> Jonathan Hull jhull at gbis.com 

> This looks somewhat similar to a future, but you can’t interact with it as a 
> separate type of object.  The value above is just a UIImage, but with a 
> compiler flag/annotation that forces me to call await on it before it can be 
> accessed/used.  The compiler has a lot more freedom to optimize/reorganize 
> things behind the scenes, because it doesn’t necessarily need to make an 
> intermediate object.


As for the message of Wallacy I'd be interested the pros and cons of hiding the 
implementation details ! :)


> To prove (or potentially disprove) my assertion that this is not just sugar, 
> how would you accomplish the following under the current proposal?
> 
>   let a = async longCalculationA()
>   let b = async longCalculationB() //b doesn’t wait for a to complete 
> before starting
>   let c = async longCalculationC() //c doesn’t wait for a or b
>   let result = await combineCalculations(a: a, b: b, c: c) //waits until 
> a, b, and c are all available


Would this be implemented differently than with Futures? I don't have much 
experience with concurrency, but I don't see how this would be handled 
differently than by using Futures, internally ? (at least 

Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Jonathan Hull via swift-evolution
But then it would need to be called with await under the current proposal, 
meaning that either:

• b would await the calculation of a

beginAsync {
let a = await longCalculationA()
let b = await longCalculationB() //This only calculates when a 
is finished
}

• or b would be executed while a is awaiting, but a and b would be in different 
scopes

beginAsync{
let a = await longCalculationA()
}
beginAsync{
let b = await longCalculationB() //We can’t see ‘a’ anymore
}
//We can’t see ‘a’ or ‘b’ here to use them

We could, also implement some sort of future, and then re-write our functions 
to take advantage of it, but this misses out on numerous compiler optimizations 
and requires our functions to be written with futures in mind.  In my example, 
the functions can just be written as async, and they don’t care whether they 
are called with async or await.

Thanks,
Jon

> On Aug 25, 2017, at 3:13 PM, Florent Vilmart  wrote:
> 
> be doesn't wait if it's defined as 
> 
> func longCalculationB() async -> SomeType 
> 
> which would be helpful if it's a long calculation, 
> 
> in the case it's
> 
> func longCalculationB() -> SomeType 
> 
> That would probably be valid to put the async keyword front even though I 
> would not be a big fan of that as you'd be executing on an indefinite queue a 
> calculation that may not be thread safe.
> 
> async would be in that case a wrapper around dispatch_async  + semaphore
> 
> 
> On 25 août 2017 18:08 -0400, Jonathan Hull , wrote:
>> Why wouldn’t b wait for a in this example?  If it is using futures, those 
>> aren’t available in the current proposal.
>> 
>>> On Aug 25, 2017, at 3:02 PM, Florent Vilmart >> > wrote:
>>> 
>>> Probably with:
>>> 
>>> let a = longCalculationA() 
>>> let b = longCalculationB() //b doesn’t wait for a to complete before 
>>> starting
>>> let c = longCalculationC() //c doesn’t wait for a or b
>>> let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits 
>>> until a, b, and c are all available
>>> 
>>> On 25 août 2017 17:48 -0400, wrote:
 
 let a = async longCalculationA()
 let b = async longCalculationB() //b doesn’t wait for a to complete before 
 starting
 let c = async longCalculationC() //c doesn’t wait for a or b
 let result = await combineCalculations(a: a, b: b, c: c) //waits until a, 
 b, and c are all available
>> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Florent Vilmart via swift-evolution
be doesn't wait if it's defined as

func longCalculationB() async -> SomeType

which would be helpful if it's a long calculation,

in the case it's

func longCalculationB() -> SomeType

That would probably be valid to put the async keyword front even though I would 
not be a big fan of that as you'd be executing on an indefinite queue a 
calculation that may not be thread safe.

async would be in that case a wrapper around dispatch_async  + semaphore


On 25 août 2017 18:08 -0400, Jonathan Hull , wrote:
> Why wouldn’t b wait for a in this example?  If it is using futures, those 
> aren’t available in the current proposal.
>
> > On Aug 25, 2017, at 3:02 PM, Florent Vilmart  wrote:
> >
> > Probably with:
> >
> > let a = longCalculationA()
> > let b = longCalculationB() //b doesn’t wait for a to complete before 
> > starting
> > let c = longCalculationC() //c doesn’t wait for a or b
> > let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits 
> > until a, b, and c are all available
> >
> > On 25 août 2017 17:48 -0400, wrote:
> > >
> > > let a = async longCalculationA()
> > > let b = async longCalculationB() //b doesn’t wait for a to complete 
> > > before starting
> > > let c = async longCalculationC() //c doesn’t wait for a or b
> > > let result = await combineCalculations(a: a, b: b, c: c) //waits until a, 
> > > b, and c are all available
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Jonathan Hull via swift-evolution
Why wouldn’t b wait for a in this example?  If it is using futures, those 
aren’t available in the current proposal.

> On Aug 25, 2017, at 3:02 PM, Florent Vilmart  wrote:
> 
> Probably with:
> 
> let a = longCalculationA() 
> let b = longCalculationB() //b doesn’t wait for a to complete before starting
> let c = longCalculationC() //c doesn’t wait for a or b
> let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits until 
> a, b, and c are all available
> 
> On 25 août 2017 17:48 -0400, wrote:
>> 
>> let a = async longCalculationA()
>> let b = async longCalculationB() //b doesn’t wait for a to complete before 
>> starting
>> let c = async longCalculationC() //c doesn’t wait for a or b
>> let result = await combineCalculations(a: a, b: b, c: c) //waits until a, b, 
>> and c are all available

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Florent Vilmart via swift-evolution
Probably with:

let a = longCalculationA()
let b = longCalculationB() //b doesn’t wait for a to complete before starting
let c = longCalculationC() //c doesn’t wait for a or b
let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits until 
a, b, and c are all available

On 25 août 2017 17:48 -0400, wrote:
>
> let a = async longCalculationA()
> let b = async longCalculationB() //b doesn’t wait for a to complete before 
> starting
> let c = async longCalculationC() //c doesn’t wait for a or b
> let result = await combineCalculations(a: a, b: b, c: c) //waits until a, b, 
> and c are all available
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Jonathan Hull via swift-evolution
To prove (or potentially disprove) my assertion that this is not just sugar, 
how would you accomplish the following under the current proposal?

let a = async longCalculationA()
let b = async longCalculationB() //b doesn’t wait for a to complete 
before starting
let c = async longCalculationC() //c doesn’t wait for a or b
let result = await combineCalculations(a: a, b: b, c: c) //waits until 
a, b, and c are all available

(Note: this is using my version of async below which doesn’t use futures)

Thanks,
Jon


> On Aug 25, 2017, at 2:13 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I actually really like the idea of using ‘async' to start a computation in a 
> non-blocking way.  It is extremely common in real-world code to want to start 
> a few computations/downloads at once in the background and then use the 
> results together...
> 
> I think full-fledged futures could be a framework thing added on top, but 
> what I would really love to see at the language level is that using ‘async’ 
> just allows you to defer calling ‘await’.  That is, you could get a value 
> back from something called with async, but you would be forced to await that 
> value before it could be used:
> 
>   var image = async downloadImage()  //Image is type UIImage
>   //Do something else here
>   let size = await image.size //The compiler forces me to call await 
> before I can actually use the value
> 
> This looks somewhat similar to a future, but you can’t interact with it as a 
> separate type of object.  The value above is just a UIImage, but with a 
> compiler flag/annotation that forces me to call await on it before it can be 
> accessed/used.  The compiler has a lot more freedom to optimize/reorganize 
> things behind the scenes, because it doesn’t necessarily need to make an 
> intermediate object.
> 
> I don’t think this is just sugar.  It adds expressivity and control for a set 
> of very common use-cases which aren’t fully supported by await alone.
> 
> Thanks,
> Jon
> 
> 
>> On Aug 24, 2017, at 4:40 AM, Trevör ANNE DENISE via swift-evolution 
>> > wrote:
>> 
>> Hello Swift community,
>> 
>> I was really interested by the recent Task-based concurrency manifesto and 
>> Concrete proposal for async semantics in Swift.
>> 
>> Looking at beginAsync() and Futures, I had an idea for a new syntax based on 
>> the `async` keyword, I'd love to hear your feedback about this idea:
>> https://github.com/adtrevor/Swift-ideas/blob/master/New%20async%20keyword%20usage.md
>>  
>> 
>> 
>> Would such a syntax make any sense?
>> 
>> Thank you ! :)
>> 
>> 
>> Trevör
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Jonathan Hull via swift-evolution
I actually really like the idea of using ‘async' to start a computation in a 
non-blocking way.  It is extremely common in real-world code to want to start a 
few computations/downloads at once in the background and then use the results 
together...

I think full-fledged futures could be a framework thing added on top, but what 
I would really love to see at the language level is that using ‘async’ just 
allows you to defer calling ‘await’.  That is, you could get a value back from 
something called with async, but you would be forced to await that value before 
it could be used:

var image = async downloadImage()  //Image is type UIImage
//Do something else here
let size = await image.size //The compiler forces me to call await 
before I can actually use the value

This looks somewhat similar to a future, but you can’t interact with it as a 
separate type of object.  The value above is just a UIImage, but with a 
compiler flag/annotation that forces me to call await on it before it can be 
accessed/used.  The compiler has a lot more freedom to optimize/reorganize 
things behind the scenes, because it doesn’t necessarily need to make an 
intermediate object.

I don’t think this is just sugar.  It adds expressivity and control for a set 
of very common use-cases which aren’t fully supported by await alone.

Thanks,
Jon


> On Aug 24, 2017, at 4:40 AM, Trevör ANNE DENISE via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> I was really interested by the recent Task-based concurrency manifesto and 
> Concrete proposal for async semantics in Swift.
> 
> Looking at beginAsync() and Futures, I had an idea for a new syntax based on 
> the `async` keyword, I'd love to hear your feedback about this idea:
> https://github.com/adtrevor/Swift-ideas/blob/master/New%20async%20keyword%20usage.md
>  
> 
> 
> Would such a syntax make any sense?
> 
> Thank you ! :)
> 
> 
> Trevör
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving KeyPath

2017-08-25 Thread Joe Groff via swift-evolution

> On Aug 25, 2017, at 1:45 PM, Eagle Offshore  wrote:
> 
> 
>> On Aug 25, 2017, at 1:35 PM, Joe Groff > > wrote:
>> 
>> What do you mean exactly by traits? That's an overloaded term.
> 
> 
> http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf 
> 
> 
> Like PHP or Pharo traits.  Like a protocol that has a default implementation 
> that comes along with it.

OK. Swift already has protocol extensions, which let you provide default 
implementations alongside protocols.

-Joe

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving KeyPath

2017-08-25 Thread Joe Groff via swift-evolution

> On Aug 25, 2017, at 1:27 PM, Eagle Offshore  wrote:
> 
> Reflection mechanisms in general would let one make things like Codable and 
> Keypaths simply a library capability/protocol extension rather than the 
> special case one trick pony it is now.
> 
> More than any other feature discussed, full access to meta data such as 
> memory layouts is the thing I most miss from Objective C.  
> 
> Given reflection/introspection, you can build KVC, Codable, and any number of 
> other clever features yourself if you are so inclined.

Runtime information about type layouts exists in the Swift runtime, and there 
are many ways we can choose to expose it to programmers. There needs to be some 
stable runtime-provided interface at the bottom, and KeyPath has some 
advantages over ObjC-style string-based KVC as that foundation—they're strongly 
typed, and they don't need to depend on string descriptions of everything being 
embedded in the binary, which might be undesirable for secrecy reasons. We 
could allow a type to vend a collection of key paths to all of its fields 
without having to fully expose source-level details of what those fields are 
named and how they're laid out, which has been a shortcoming of ObjC's approach 
for a lot of secrecy-sensitive clients.

> Oh, and traits - want traits for composability.


What do you mean exactly by traits? That's an overloaded term.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving KeyPath

2017-08-25 Thread Eagle Offshore via swift-evolution
Reflection mechanisms in general would let one make things like Codable and 
Keypaths simply a library capability/protocol extension rather than the special 
case one trick pony it is now.

More than any other feature discussed, full access to meta data such as memory 
layouts is the thing I most miss from Objective C.  

Given reflection/introspection, you can build KVC, Codable, and any number of 
other clever features yourself if you are so inclined.

Oh, and traits - want traits for composability.

> On Aug 25, 2017, at 11:43 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> These would all be great additional features to eventually add to key paths. 
> I think reflection mechanisms centered on key paths like what you describe 
> would be a superior replacement for most of what Mirror attempts to provide.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] New async keyword usage

2017-08-25 Thread Wallacy via swift-evolution
Makes sense. But if i'm reading its right (and the original proposal too),
in this case we don't have only a syntax sugar, we actually gain another
ways to use.

First, because Future actually need another proposal, and beginAsync  (to
me) does not apear to be that rare! "Fire and Forget" is pretty common when
we use Cocoa.

Second, because in this way we don't need to handle with Future anymore.
Like i see on the other Threads, people tends to believe the "Future" is a
more powerful, and only what is needed. Because that (not only that) we
cant prevent something like this:

func someAsyncFunc() -> Future


So, after the Future class be implemented, we will need to handle with two
patterns at same time! Sometime we will use "await someAsyncFunc()" other
times, we will be forced to call someAsyncFunc().get().

Using only async/await is pretty easy to learn and teach. And the ability
to only "wrap" at asynchronous context and "unwrap" using only these two
keywords appear be worth.

Use async keyword to make a function asynchronous.
Use async keyword to make a closure asynchronous.
Use async keyword at call side to capture the "reference" and only "unwrap"
later. (maybe send to some other place too).
Use await  to get the value from a async function/closure.

And after that, "Future" can be implement in any way because will not be a
public API anymore (I do not know, but there may also be some opportunities
for optimization as well), and we only need to care about when we need to
"keep the reference" from some async call.

And possibly, they will not need to create any Future type! The variable
type will be "async User" as long as it is not "unwrapped". (
suspend/defer/abandon still possible)

Em sex, 25 de ago de 2017 às 02:15, Chris Lattner via swift-evolution <
swift-evolution@swift.org> escreveu:

>
> On Aug 24, 2017, at 4:40 AM, Trevör ANNE DENISE via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hello Swift community,
>
> I was really interested by the recent* Task-based concurrency manifesto*
>  and *Concrete proposal for async semantics in Swift.*
>
> Looking at beginAsync() and Futures, I had an idea for a new syntax based
> on the `async` keyword, I'd love to hear your feedback about this idea:
>
> https://github.com/adtrevor/Swift-ideas/blob/master/New%20async%20keyword%20usage.md
>
> Would such a syntax make any sense?
>
>
> Yes, it is entirely possible that we will want to provide more syntactic
> sugar than the proposal suggests: the proposal is intentionally designed to
> be minimal, so we can get it in place, get experience using it, then decide
> whether any specific syntactic pain point is significant enough to be worth
> adding additional sugar/complexity.
>
> As has been mentioned in other threads, the hope is that “beginAsync” is
> actually extremely rare in practice.  If that is the case, there is little
> point to sugaring it.
>
> -Chris
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Marc Schlichte via swift-evolution

> Am 25.08.2017 um 19:08 schrieb Adam Kemp via swift-evolution 
> :
> 
> I understand what you’re saying, but I just think trying to make synchronous, 
> blocking actor methods goes against the fundamental ideal of the actor model, 
> and it’s a recipe for disaster. When actors communicate with each other that 
> communication needs to be asynchronous or you will get deadlocks. It’s not 
> just going to be a corner case. It’s going to be a very frequent occurrence.
> 
> One of the general rules of multithreaded programming is “don’t call unknown 
> code while holding a lock”. Blocking a queue is effectively the same as 
> holding a lock, and calling another actor is calling unknown code. So if the 
> model works that way then the language itself will be encouraging people to 
> call unknown code while holding locks. That is not going to go well.
> 

I would claim - without having a prove though - that as long as you don’t 
invoke async actor methods on weak or unowned actor references and the code is 
retain cycle free, no deadlocks will happen.

Cheers
Marc

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving KeyPath

2017-08-25 Thread Joe Groff via swift-evolution

> On Aug 23, 2017, at 11:18 PM, Logan Shire via swift-evolution 
>  wrote:
> 
> Hey folks! 
> 
> Recently I’ve been working on a small library which leverages the Swift 4 
> Codable protocol
> and KeyPaths to provide a Swift-y interface to CoreData. (It maps back and 
> forth between
> native, immutable Swift structs and NSManagedObjects). In doing so I found a 
> couple of 
> frustrating limitations to the KeyPath API. Firstly, KeyPath does not provide 
> the name of the 
> property on the type it indexes. For example, if I have a struct:
> 
> 
> struct Person {
>let firstName: String
>let lastName: String
> }
> 
> let keyPath = \Person.firstName
> 
> 
> But once I have a keyPath, I can’t actually figure out what property it 
> accesses.
> So, I wind up having to make a wrapper:
> 
> 
> struct Attribute {
>let keyPath: AnyKeyPath
>let propertyName: String
> }
> 
> let firstNameAttribute = Attribute(keyPath: \Person.firstName, propertyName: 
> “firstName”)
> 
> 
> This forces me to write out the property name myself as a string which is 
> very error prone.
> All I want is to be able to access:
> 
> 
> keyPath.propertyName // “firstName”
> 
> 
> It would also be nice if we provided the full path as a string as well:
> 
> 
> keyPath.fullPath // “Person.firstName"
> 
> 
> Also, if I want to get all of the attributes from a given Swift type, my 
> options are to try to hack
> something together with Mirrors, or forcing the type to declare a function / 
> computed property
> returning an array of all of its key path / property name pairings. I would 
> really like to be able to 
> retrieve a type-erased array of any type’s key paths with:
> 
> 
> let person = Person(firstName: “John”, lastName: “Doe”)
> let keyPaths = Person.keyPaths
> let firstNameKeyPath = keyPaths.first { $0.propertyName = “firstName” } as! 
> KeyPath
> let firstName = person[keypath: firstNameKeyPath] // “John"
> 
> 
> And finally, without straying too far into Objective-C land, it would be nice 
> if we could initialize key paths
> with a throwing initializer.
> 
> 
> let keyPath = try Person.keyPath(“firstName”) // KeyPath type 
> erased to AnyKeyPath
> let keyPath = AnyKeyPath(“Person.firstName”)
> 
> 
> Let me know what you think about any / all of these suggestions!

These would all be great additional features to eventually add to key paths. I 
think reflection mechanisms centered on key paths like what you describe would 
be a superior replacement for most of what Mirror attempts to provide.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] typed throws

2017-08-25 Thread Dave Abrahams via swift-evolution


on Fri Aug 25 2017, John McCall  wrote: 

On Aug 25, 2017, at 12:18 PM, Dave Abrahams via swift-evolution 
 wrote: on Fri Aug 18 2017, Joe 
Groff  wrote:  
On Aug 17, 2017, at 11:27 PM, John McCall via swift-evolution 
 wrote: 


 Essentially, you give Error a tagged-pointer representation 
to allow payload-less errors on non-generic error types to be 
allocated 
 
globally, and then you can (1) tell people to not throw 
errors that require allocation if it's vital to avoid 
allocation (just like we would tell them today not to 
construct classes or indirect enum cases) and (2) allow a 
special global payload-less error to be substituted if error 
allocation fails.   Of course, we could also say that systems 
code is required to use a typed-throws feature that we add 
down the line for their purposes.  Or just tell them to not 
use payloads.  Or force them to constrain their error types 
to fit within some given size.  (Note that obsessive error 
taxonomies tend to end up with a bunch of indirect enum cases 
anyway, because they get recursive, so the allocation problem 
is very real whatever we do.) 
 Alternatively, with some LLVM work, we could have the thrower 
leave the error value on the stack when propagating an error, 
and make it the catcher's responsibility to consume the error 
value and pop the stack. We could make not only errors but 
existential returns in general more efficient and "systems 
code"-worthy with a technique like that. 
 That's how the best C++ unwiding mechanisms work already. 


Them's fighting words. :) 


The correct term, John, is “fightin'”

-Crustee

John. 

I always thought it was off the table because we were wedded to 
the idea that throwing functions are just effectively returning 
a Result normally under the covers, but if not, so much the 
better!   --  -Dave 
___ swift-evolution 
mailing list swift-evolution@swift.org 
https://lists.swift.org/mailman/listinfo/swift-evolution 


--
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Adam Kemp via swift-evolution

> On Aug 25, 2017, at 9:54 AM, Thomas  wrote:
> 
> I'd tend to think non-FIFO actor messaging will cause more trouble than 
> potential deadlocks. I'm re-reading the proposal and it seems to go this way 
> as well:
> 
> "An await on an actor method suspends the current task, and since you can get 
> circular waits, you can end up with deadlock. This is because only one 
> message is processed by the actor at a time. The trivial case like this can 
> also be trivially diagnosed by the compiler. The complex case would ideally 
> be diagnosed at runtime with a trap, depending on the runtime implementation 
> model."

I understand what you’re saying, but I just think trying to make synchronous, 
blocking actor methods goes against the fundamental ideal of the actor model, 
and it’s a recipe for disaster. When actors communicate with each other that 
communication needs to be asynchronous or you will get deadlocks. It’s not just 
going to be a corner case. It’s going to be a very frequent occurrence.

One of the general rules of multithreaded programming is “don’t call unknown 
code while holding a lock”. Blocking a queue is effectively the same as holding 
a lock, and calling another actor is calling unknown code. So if the model 
works that way then the language itself will be encouraging people to call 
unknown code while holding locks. That is not going to go well.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Thomas via swift-evolution

> On 25 Aug 2017, at 18:30, Adam Kemp  wrote:
> 
> 
> 
>> On Aug 25, 2017, at 1:14 AM, Thomas > > wrote:
>>> On 25 Aug 2017, at 01:15, Adam Kemp >> > wrote:
>>> I don’t think await should cause the actor’s queue (or any queue) to be 
>>> suspended. Actor methods should not block waiting for asynchronous things. 
>>> That’s how you get deadlocks. If an actor method needs to be async then it 
>>> should work just like any async method on the main queue: it unblocks the 
>>> queue and allows other messages to be processed until it gets an answer.
>>> 
>>> You do have to be aware of the fact that things can happen in between an 
>>> await and the next line of code, but conveniently these places are all 
>>> marked for you. They all say “await”. :)
>> 
>> It is correct that suspending the queue allows for deadlocks, but not doing 
>> it means you can receive messages while still in the middle of another 
>> message. For the same reason you may need FIFO ordering in a class to 
>> guarantee coherency, you will want this to work in an asynchronous world as 
>> well. Take for example some storage class:
>> 
>> 1. store(object, key)
>> 2. fetch(key)
>> 
>> If you're doing these operations in order, you want the fetch to return the 
>> object you just stored. If the 'store' needs to await something in its 
>> implementation and we were to not suspend the queue, the fetch would be 
>> processed before the object is actually stored and it would return something 
>> unexpected.
> 
> Actors can use other means to serialize operations if they need to, for 
> instance by using an internal queue of pending operations. It’s better for 
> actors that need this kind of serialization to handle it explicitly than for 
> every actor to suffer from potential deadlocks when doing seemingly 
> straightforward things.
> 
> async/await in general is not meant to block anything. It’s explicitly meant 
> to avoid blocking things. That’s what the feature is for. It would be 
> confusing if await did something different for actor methods than it did for 
> every other context.

I'd tend to think non-FIFO actor messaging will cause more trouble than 
potential deadlocks. I'm re-reading the proposal and it seems to go this way as 
well:

"An await on an actor method suspends the current task, and since you can get 
circular waits, you can end up with deadlock. This is because only one message 
is processed by the actor at a time. The trivial case like this can also be 
trivially diagnosed by the compiler. The complex case would ideally be 
diagnosed at runtime with a trap, depending on the runtime implementation 
model."

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] typed throws

2017-08-25 Thread John McCall via swift-evolution
> On Aug 25, 2017, at 12:18 PM, Dave Abrahams via swift-evolution 
>  wrote:
> on Fri Aug 18 2017, Joe Groff  wrote:
> 
>>> On Aug 17, 2017, at 11:27 PM, John McCall via swift-evolution
>>>  wrote:
>>> 
>>> Essentially, you give Error a tagged-pointer representation to allow
>>> payload-less errors on non-generic error types to be allocated
>> 
>>> globally, and then you can (1) tell people to not throw errors that
>>> require allocation if it's vital to avoid allocation (just like we
>>> would tell them today not to construct classes or indirect enum
>>> cases) and (2) allow a special global payload-less error to be
>>> substituted if error allocation fails.
>>> 
>>> Of course, we could also say that systems code is required to use a
>>> typed-throws feature that we add down the line for their purposes.
>>> Or just tell them to not use payloads.  Or force them to constrain
>>> their error types to fit within some given size.  (Note that
>>> obsessive error taxonomies tend to end up with a bunch of indirect
>>> enum cases anyway, because they get recursive, so the allocation
>>> problem is very real whatever we do.)
>> 
>> Alternatively, with some LLVM work, we could have the thrower leave
>> the error value on the stack when propagating an error, and make it
>> the catcher's responsibility to consume the error value and pop the
>> stack. We could make not only errors but existential returns in
>> general more efficient and "systems code"-worthy with a technique like
>> that.
> 
> That's how the best C++ unwiding mechanisms work already.

Them's fighting words. :)

John.

> I always thought it was off the table because we were wedded to the idea that
> throwing functions are just effectively returning a Result normally
> under the covers, but if not, so much the better!
> 
> -- 
> -Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Adam Kemp via swift-evolution
Cancellation and time out can be built into futures, and async/await can 
interact with futures. I don’t think we need async/await itself to support 
either of those.

Just as a real-world example, C#’s async/await feature doesn’t have built-in 
timeout or cancellation support, but it’s still easy to handle both of those 
cases using the tools available. For example, one technique would be this (in 
C#):

var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMilliseconds(2500));
try {
await DoAsync(cts.Token);
}
catch (OperationCanceledException) {
// Handle cancelled
}
catch (Exception) {
// Handle other failure
}

There are other techniques that would let you distinguish between cancellation 
and timeout as well.

> On Aug 25, 2017, at 7:06 AM, Cavelle Benjamin via swift-evolution 
>  wrote:
> 
> Disclaimer: not an expert
> 
> Question
> I didn’t see any where the async is required to time out after a certain time 
> frame. I would think that we would want to specify both on the function 
> declaration side as a default and on the function call side as a 
> customization. That being said, the return time then becomes an optional 
> given the timeout and the calling code would need to unwrap.
> 
> func loadWebResource(_ path: String) async -> Resource
> func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image
> func dewarpAndCleanupImage(_ i : Image) async -> Image
> 
> func processImageData1() async -> Image {
> let dataResource  = await loadWebResource("dataprofile.txt")
> let imageResource = await loadWebResource("imagedata.dat")
> let imageTmp  = await decodeImage(dataResource, imageResource)
> let imageResult   = await dewarpAndCleanupImage(imageTmp)
> return imageResult
> }
> 
> 
> So the prior code becomes… 
> 
> func loadWebResource(_ path: String) async(timeout: 1000) -> Resource?
> func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image?
> func dewarpAndCleanupImage(_ i : Image) async -> Image?
> 
> func processImageData1() async -> Image? {
> let dataResource  = guard let await loadWebResource("dataprofile.txt”) 
> else { // handle timeout }
> let imageResource = guard let await(timeout: 100) 
> loadWebResource("imagedata.dat”) else { // handle timeout }
> let imageTmp  = await decodeImage(dataResource, imageResource)
> let imageResult   = await dewarpAndCleanupImage(imageTmp)
> return imageResult
> }
> 
> 
> Given this structure, the return type of all async’s would be optionals with 
> now 3 return types??
> 
> .continuation // suspends and picks back up
> .value // these are the values we are looking for
> .none // took too long, so you get nothing.
> 
> 
> 
>> On 2017-Aug -17 (34), at 18:24, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>> Hi all,
>> 
>> As Ted mentioned in his email, it is great to finally kick off discussions 
>> for what concurrency should look like in Swift.  This will surely be an epic 
>> multi-year journey, but it is more important to find the right design than 
>> to get there fast.
>> 
>> I’ve been advocating for a specific model involving async/await and actors 
>> for many years now.  Handwaving only goes so far, so some folks asked me to 
>> write them down to make the discussion more helpful and concrete.  While I 
>> hope these ideas help push the discussion on concurrency forward, this isn’t 
>> in any way meant to cut off other directions: in fact I hope it helps give 
>> proponents of other designs a model to follow: a discussion giving extensive 
>> rationale, combined with the long term story arc to show that the features 
>> fit together.
>> 
>> Anyway, here is the document, I hope it is useful, and I’d love to hear 
>> comments and suggestions for improvement:
>> https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782 
>> 
>> 
>> -Chris
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Adam Kemp via swift-evolution


> On Aug 25, 2017, at 1:14 AM, Thomas  wrote:
>> On 25 Aug 2017, at 01:15, Adam Kemp > > wrote:
>> I don’t think await should cause the actor’s queue (or any queue) to be 
>> suspended. Actor methods should not block waiting for asynchronous things. 
>> That’s how you get deadlocks. If an actor method needs to be async then it 
>> should work just like any async method on the main queue: it unblocks the 
>> queue and allows other messages to be processed until it gets an answer.
>> 
>> You do have to be aware of the fact that things can happen in between an 
>> await and the next line of code, but conveniently these places are all 
>> marked for you. They all say “await”. :)
> 
> It is correct that suspending the queue allows for deadlocks, but not doing 
> it means you can receive messages while still in the middle of another 
> message. For the same reason you may need FIFO ordering in a class to 
> guarantee coherency, you will want this to work in an asynchronous world as 
> well. Take for example some storage class:
> 
> 1. store(object, key)
> 2. fetch(key)
> 
> If you're doing these operations in order, you want the fetch to return the 
> object you just stored. If the 'store' needs to await something in its 
> implementation and we were to not suspend the queue, the fetch would be 
> processed before the object is actually stored and it would return something 
> unexpected.

Actors can use other means to serialize operations if they need to, for 
instance by using an internal queue of pending operations. It’s better for 
actors that need this kind of serialization to handle it explicitly than for 
every actor to suffer from potential deadlocks when doing seemingly 
straightforward things.

async/await in general is not meant to block anything. It’s explicitly meant to 
avoid blocking things. That’s what the feature is for. It would be confusing if 
await did something different for actor methods than it did for every other 
context.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] Fixing race conditions in async/await example

2017-08-25 Thread Joe Groff via swift-evolution

> On Aug 25, 2017, at 12:34 AM, Howard Lovatt  wrote:
> 
>  In particular a future that is cancellable is more powerful that the 
> proposed async/await.

It's not more powerful; the features are to some degree disjoint. You can build 
a Future abstraction and then use async/await to sugar code that threads 
computation through futures. Getting back to Jakob's example, someone (maybe 
the Clang importer, maybe Apple's framework developers in an overlay) will 
still need to build infrastructure on top of IBActions and other currently 
ad-hoc signalling mechanisms to integrate them into a more expressive 
coordination framework.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] typed throws

2017-08-25 Thread Dave Abrahams via swift-evolution

on Fri Aug 18 2017, Joe Groff  wrote:

>> On Aug 17, 2017, at 11:27 PM, John McCall via swift-evolution
>>  wrote:
>> 
>> Essentially, you give Error a tagged-pointer representation to allow
>> payload-less errors on non-generic error types to be allocated
>
>> globally, and then you can (1) tell people to not throw errors that
>> require allocation if it's vital to avoid allocation (just like we
>> would tell them today not to construct classes or indirect enum
>> cases) and (2) allow a special global payload-less error to be
>> substituted if error allocation fails.
>> 
>> Of course, we could also say that systems code is required to use a
>> typed-throws feature that we add down the line for their purposes.
>> Or just tell them to not use payloads.  Or force them to constrain
>> their error types to fit within some given size.  (Note that
>> obsessive error taxonomies tend to end up with a bunch of indirect
>> enum cases anyway, because they get recursive, so the allocation
>> problem is very real whatever we do.)
>
> Alternatively, with some LLVM work, we could have the thrower leave
> the error value on the stack when propagating an error, and make it
> the catcher's responsibility to consume the error value and pop the
> stack. We could make not only errors but existential returns in
> general more efficient and "systems code"-worthy with a technique like
> that.

That's how the best C++ unwiding mechanisms work already.  I always
thought it was off the table because we were wedded to the idea that
throwing functions are just effectively returning a Result normally
under the covers, but if not, so much the better!

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] typed throws

2017-08-25 Thread Dave Abrahams via swift-evolution

on Thu Aug 17 2017, John McCall  wrote:

>> On Aug 18, 2017, at 12:58 AM, Chris Lattner via swift-evolution 
>>  wrote:
>> Splitting this off into its own thread:
>> 
>>> On Aug 17, 2017, at 7:39 PM, Matthew Johnson  wrote:
>>> One related topic that isn’t discussed is type errors.  Many third
>
>>> party libraries use a Result type with typed errors.  Moving to an
>>> async / await model without also introducing typed errors into
>>> Swift would require giving up something that is highly valued by
>>> many Swift developers.  Maybe Swift 5 is the right time to tackle
>>> typed errors as well.  I would be happy to help with design and
>>> drafting a proposal but would need collaborators on the
>>> implementation side.
>> 
>> Typed throws is something we need to settle one way or the other,
>> and I agree it would be nice to do that in the Swift 5 cycle.
>> 
>> For the purposes of this sub-discussion, I think there are three kinds of 
>> code to think about: 
>> 1) large scale API like Cocoa which evolve (adding significant
>> functionality) over the course of many years and can’t break
>> clients.
>> 2) the public API of shared swiftpm packages, whose lifecycle may
>> rise and fall - being obsoleted and replaced by better packages if
>> they encounter a design problem.
>> 3) internal APIs and applications, which are easy to change because
>> the implementations and clients of the APIs are owned by the same
>> people.
>> 
>> These each have different sorts of concerns, and we hope that
>> something can start out as #3 but work its way up the stack
>> gracefully.
>> 
>> Here is where I think things stand on it:
>> - There is consensus that untyped throws is the right thing for a
>> large scale API like Cocoa.  NSError is effectively proven here.
>> Even if typed throws is introduced, Apple is unlikely to adopt it in
>> their APIs for this reason.
>> - There is consensus that untyped throws is the right default for people to 
>> reach for for public package (#2).
>> - There is consensus that Java and other systems that encourage
>> lists of throws error types lead to problematic APIs for a variety
>> of reasons.
>> - There is disagreement about whether internal APIs (#3) should use
>> it.  It seems perfect to be able to write exhaustive catches in this
>> situation, since everything in knowable. OTOH, this could encourage
>> abuse of error handling in cases where you really should return an
>> enum instead of using throws.
>> - Some people are concerned that introducing typed throws would
>> cause people to reach for it instead of using untyped throws for
>> public package APIs.
>
> Even for non-public code.  The only practical merit of typed throws I
> have ever seen someone demonstrate is that it would let them use
> contextual lookup in a throw or catch.  People always say "I'll be
> able to exhaustively switch over my errors", and then I ask them to
> show me where they want to do that, and they show me something that
> just logs the error, which of course does not require typed throws.
> Every.  Single.  Time.
>
> Sometimes we then go on to have a conversation about wrapping errors
> in other error types, and that can be interesting, but now we're
> talking about adding a big, messy feature just to get "safety"
> guarantees for a fairly minor need.
>
> Programmers often have an instinct to obsess over error taxonomies
> that is very rarely directed at solving any real problem; it is just
> self-imposed busy-work.

+1; I couldn't have said this any better.  

The problem is not merely that by implementing this we'd be expending
effort and adding language complexity; it's also that programmers love
to classify things and those working with statically-typed languages
have a natural inclination to think “more static type information is
better,” so they *will* use this feature whether it's good for code or
not.

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Cavelle Benjamin via swift-evolution
Disclaimer: not an expert

Question
I didn’t see any where the async is required to time out after a certain time 
frame. I would think that we would want to specify both on the function 
declaration side as a default and on the function call side as a customization. 
That being said, the return time then becomes an optional given the timeout and 
the calling code would need to unwrap.

func loadWebResource(_ path: String) async -> Resource
func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image
func dewarpAndCleanupImage(_ i : Image) async -> Image

func processImageData1() async -> Image {
let dataResource  = await loadWebResource("dataprofile.txt")
let imageResource = await loadWebResource("imagedata.dat")
let imageTmp  = await decodeImage(dataResource, imageResource)
let imageResult   = await dewarpAndCleanupImage(imageTmp)
return imageResult
}


So the prior code becomes… 

func loadWebResource(_ path: String) async(timeout: 1000) -> Resource?
func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image?
func dewarpAndCleanupImage(_ i : Image) async -> Image?

func processImageData1() async -> Image? {
let dataResource  = guard let await loadWebResource("dataprofile.txt”) else 
{ // handle timeout }
let imageResource = guard let await(timeout: 100) 
loadWebResource("imagedata.dat”) else { // handle timeout }
let imageTmp  = await decodeImage(dataResource, imageResource)
let imageResult   = await dewarpAndCleanupImage(imageTmp)
return imageResult
}


Given this structure, the return type of all async’s would be optionals with 
now 3 return types??

.continuation // suspends and picks back up
.value // these are the values we are looking for
.none // took too long, so you get nothing.



> On 2017-Aug -17 (34), at 18:24, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hi all,
> 
> As Ted mentioned in his email, it is great to finally kick off discussions 
> for what concurrency should look like in Swift.  This will surely be an epic 
> multi-year journey, but it is more important to find the right design than to 
> get there fast.
> 
> I’ve been advocating for a specific model involving async/await and actors 
> for many years now.  Handwaving only goes so far, so some folks asked me to 
> write them down to make the discussion more helpful and concrete.  While I 
> hope these ideas help push the discussion on concurrency forward, this isn’t 
> in any way meant to cut off other directions: in fact I hope it helps give 
> proponents of other designs a model to follow: a discussion giving extensive 
> rationale, combined with the long term story arc to show that the features 
> fit together.
> 
> Anyway, here is the document, I hope it is useful, and I’d love to hear 
> comments and suggestions for improvement:
> https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782
> 
> -Chris
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Thomas via swift-evolution

> On 25 Aug 2017, at 10:14, Thomas via swift-evolution 
>  wrote:
> 
> 
>> On 25 Aug 2017, at 01:15, Adam Kemp > > wrote:
>> 
>> 
>> 
>>> On Aug 24, 2017, at 3:15 PM, Thomas >> > wrote:
>>> 
>>> 
 On 24 Aug 2017, at 23:47, Adam Kemp > wrote:
 
 
> On Aug 24, 2017, at 1:05 PM, Thomas via swift-evolution 
> > wrote:
> 
>> 
>> On 24 Aug 2017, at 21:48, Marc Schlichte > > wrote:
>> 
>> Yes, I think it is mandatory that we continue on the callers queue after 
>> an `await ` on some actor method.
>> 
>> If you `await` on a non-actor-method though, you would have to changes 
>> queues manually if needed.
>> 
>> Any `actor` should have a `let actorQueue: DispatchQueue` property so 
>> that we can call in these cases:
>> 
>> ```await actorQueue.asyncCoroutine()``` as mentioned in the manifesto.
> 
> Wouldn't that be really confusing though? That awaiting certain methods 
> would bring us back to the actor's queue but awaiting others would 
> require manual queue hopping? What if the compiler was to always generate 
> the 'await actorQueue.asyncCoroutine()' queue hopping code after awaiting 
> on an async/actor method?
 
 Yes, it would be confusing. await should either always return to the same 
 queue or never do it. Otherwise it’s even more error-prone. I see the 
 actor feature as being just another demonstration of why solving the 
 queue-hopping problem is important for async/await to be useful.
>>> 
>>> So the way a non "fire and forget" actor method would work is:
>>> 
>>> - the actor's queue is in a suspended state until the method returns, this 
>>> is required so that messages sent to other actor methods are not processed 
>>> (they're added to the queue)
>>> - if the method body awaits on some other code, it automatically jumps back 
>>> on the actor's queue after awaiting, regardless of the queue's suspension 
>>> and content
>>> - when the method returns, the actor's queue is resumed and pending 
>>> messages can be processed (if any)
>>> 
>> 
>> I don’t think await should cause the actor’s queue (or any queue) to be 
>> suspended. Actor methods should not block waiting for asynchronous things. 
>> That’s how you get deadlocks. If an actor method needs to be async then it 
>> should work just like any async method on the main queue: it unblocks the 
>> queue and allows other messages to be processed until it gets an answer.
>> 
>> You do have to be aware of the fact that things can happen in between an 
>> await and the next line of code, but conveniently these places are all 
>> marked for you. They all say “await”. :)
> 
> It is correct that suspending the queue allows for deadlocks, but not doing 
> it means you can receive messages while still in the middle of another 
> message. For the same reason you may need FIFO ordering in a class to 
> guarantee coherency, you will want this to work in an asynchronous world as 
> well. Take for example some storage class:
> 
> 1. store(object, key)
> 2. fetch(key)
> 
> If you're doing these operations in order, you want the fetch to return the 
> object you just stored. If the 'store' needs to await something in its 
> implementation and we were to not suspend the queue, the fetch would be 
> processed before the object is actually stored and it would return something 
> unexpected.

Also think about this storage class being used concurrently. If the 'store' 
method is called concurrently and you don't suspend the queue, you'd end up 
with some of these 'store' requests processed while possibly in the middle of 
previous 'store' requests. That doesn't seem very safe. Soon enough, you'll end 
up wanting to wrap your class into an async FIFO pipeline.

Thomas

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Thomas via swift-evolution

> On 25 Aug 2017, at 10:14, Thomas via swift-evolution 
>  wrote:
> 
> 
>> On 25 Aug 2017, at 01:15, Adam Kemp > > wrote:
>> 
>> 
>> 
>>> On Aug 24, 2017, at 3:15 PM, Thomas >> > wrote:
>>> 
>>> 
 On 24 Aug 2017, at 23:47, Adam Kemp > wrote:
 
 
> On Aug 24, 2017, at 1:05 PM, Thomas via swift-evolution 
> > wrote:
> 
>> 
>> On 24 Aug 2017, at 21:48, Marc Schlichte > > wrote:
>> 
>> Yes, I think it is mandatory that we continue on the callers queue after 
>> an `await ` on some actor method.
>> 
>> If you `await` on a non-actor-method though, you would have to changes 
>> queues manually if needed.
>> 
>> Any `actor` should have a `let actorQueue: DispatchQueue` property so 
>> that we can call in these cases:
>> 
>> ```await actorQueue.asyncCoroutine()``` as mentioned in the manifesto.
> 
> Wouldn't that be really confusing though? That awaiting certain methods 
> would bring us back to the actor's queue but awaiting others would 
> require manual queue hopping? What if the compiler was to always generate 
> the 'await actorQueue.asyncCoroutine()' queue hopping code after awaiting 
> on an async/actor method?
 
 Yes, it would be confusing. await should either always return to the same 
 queue or never do it. Otherwise it’s even more error-prone. I see the 
 actor feature as being just another demonstration of why solving the 
 queue-hopping problem is important for async/await to be useful.
>>> 
>>> So the way a non "fire and forget" actor method would work is:
>>> 
>>> - the actor's queue is in a suspended state until the method returns, this 
>>> is required so that messages sent to other actor methods are not processed 
>>> (they're added to the queue)
>>> - if the method body awaits on some other code, it automatically jumps back 
>>> on the actor's queue after awaiting, regardless of the queue's suspension 
>>> and content
>>> - when the method returns, the actor's queue is resumed and pending 
>>> messages can be processed (if any)
>>> 
>> 
>> I don’t think await should cause the actor’s queue (or any queue) to be 
>> suspended. Actor methods should not block waiting for asynchronous things. 
>> That’s how you get deadlocks. If an actor method needs to be async then it 
>> should work just like any async method on the main queue: it unblocks the 
>> queue and allows other messages to be processed until it gets an answer.
>> 
>> You do have to be aware of the fact that things can happen in between an 
>> await and the next line of code, but conveniently these places are all 
>> marked for you. They all say “await”. :)
> 
> It is correct that suspending the queue allows for deadlocks, but not doing 
> it means you can receive messages while still in the middle of another 
> message. For the same reason you may need FIFO ordering in a class to 
> guarantee coherency, you will want this to work in an asynchronous world as 
> well. Take for example some storage class:
> 
> 1. store(object, key)
> 2. fetch(key)
> 
> If you're doing these operations in order, you want the fetch to return the 
> object you just stored. If the 'store' needs to await something in its 
> implementation and we were to not suspend the queue, the fetch would be 
> processed before the object is actually stored and it would return something 
> unexpected.

By the way, contrary to what I said earlier, that means we'd need to do this 
also for "fire and forget" methods, as is "store" in this example.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Thomas via swift-evolution

> On 25 Aug 2017, at 10:17, Thomas via swift-evolution 
>  wrote:
> 
>> 
>> On 25 Aug 2017, at 09:04, Marc Schlichte > > wrote:
>> 
>> 
>>> Am 24.08.2017 um 22:05 schrieb Thomas via swift-evolution 
>>> >:
>>> 
 
 Yes, I think it is mandatory that we continue on the callers queue after 
 an `await ` on some actor method.
 
 If you `await` on a non-actor-method though, you would have to changes 
 queues manually if needed.
 
 Any `actor` should have a `let actorQueue: DispatchQueue` property so that 
 we can call in these cases:
 
 ```await actorQueue.asyncCoroutine()``` as mentioned in the manifesto.
>>> 
>>> Wouldn't that be really confusing though? That awaiting certain methods 
>>> would bring us back to the actor's queue but awaiting others would require 
>>> manual queue hopping? What if the compiler was to always generate the 
>>> 'await actorQueue.asyncCoroutine()' queue hopping code after awaiting on an 
>>> async/actor method?
>>> 
>>> Thomas
>>> 
>> 
>> I think we are not allowed to implicitly switch back to the actor's queue 
>> after awaiting non-actor methods. These might have been auto converted from 
>> Continuation-Passing-Style (CPS) to async/await style. With the `mainActor` 
>> idea from the manifesto, all existing code will run in some actor, so 
>> changing the queue semantics could break existing code.
> 
> This would only happen when the caller is an actor, which means new code, so 
> I don't think we would be breaking any existing code.

Oh but yeah, the main actor will probably need migration/warnings from the 
compiler.

Thomas

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Thomas via swift-evolution

> On 25 Aug 2017, at 09:04, Marc Schlichte  
> wrote:
> 
> 
>> Am 24.08.2017 um 22:05 schrieb Thomas via swift-evolution 
>> >:
>> 
>>> 
>>> Yes, I think it is mandatory that we continue on the callers queue after an 
>>> `await ` on some actor method.
>>> 
>>> If you `await` on a non-actor-method though, you would have to changes 
>>> queues manually if needed.
>>> 
>>> Any `actor` should have a `let actorQueue: DispatchQueue` property so that 
>>> we can call in these cases:
>>> 
>>> ```await actorQueue.asyncCoroutine()``` as mentioned in the manifesto.
>> 
>> Wouldn't that be really confusing though? That awaiting certain methods 
>> would bring us back to the actor's queue but awaiting others would require 
>> manual queue hopping? What if the compiler was to always generate the 'await 
>> actorQueue.asyncCoroutine()' queue hopping code after awaiting on an 
>> async/actor method?
>> 
>> Thomas
>> 
> 
> I think we are not allowed to implicitly switch back to the actor's queue 
> after awaiting non-actor methods. These might have been auto converted from 
> Continuation-Passing-Style (CPS) to async/await style. With the `mainActor` 
> idea from the manifesto, all existing code will run in some actor, so 
> changing the queue semantics could break existing code.

This would only happen when the caller is an actor, which means new code, so I 
don't think we would be breaking any existing code.

Thomas

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Thomas via swift-evolution

> On 25 Aug 2017, at 01:15, Adam Kemp  wrote:
> 
> 
> 
>> On Aug 24, 2017, at 3:15 PM, Thomas > > wrote:
>> 
>> 
>>> On 24 Aug 2017, at 23:47, Adam Kemp >> > wrote:
>>> 
>>> 
 On Aug 24, 2017, at 1:05 PM, Thomas via swift-evolution 
 > wrote:
 
> 
> On 24 Aug 2017, at 21:48, Marc Schlichte  > wrote:
> 
> Yes, I think it is mandatory that we continue on the callers queue after 
> an `await ` on some actor method.
> 
> If you `await` on a non-actor-method though, you would have to changes 
> queues manually if needed.
> 
> Any `actor` should have a `let actorQueue: DispatchQueue` property so 
> that we can call in these cases:
> 
> ```await actorQueue.asyncCoroutine()``` as mentioned in the manifesto.
 
 Wouldn't that be really confusing though? That awaiting certain methods 
 would bring us back to the actor's queue but awaiting others would require 
 manual queue hopping? What if the compiler was to always generate the 
 'await actorQueue.asyncCoroutine()' queue hopping code after awaiting on 
 an async/actor method?
>>> 
>>> Yes, it would be confusing. await should either always return to the same 
>>> queue or never do it. Otherwise it’s even more error-prone. I see the actor 
>>> feature as being just another demonstration of why solving the 
>>> queue-hopping problem is important for async/await to be useful.
>> 
>> So the way a non "fire and forget" actor method would work is:
>> 
>> - the actor's queue is in a suspended state until the method returns, this 
>> is required so that messages sent to other actor methods are not processed 
>> (they're added to the queue)
>> - if the method body awaits on some other code, it automatically jumps back 
>> on the actor's queue after awaiting, regardless of the queue's suspension 
>> and content
>> - when the method returns, the actor's queue is resumed and pending messages 
>> can be processed (if any)
>> 
> 
> I don’t think await should cause the actor’s queue (or any queue) to be 
> suspended. Actor methods should not block waiting for asynchronous things. 
> That’s how you get deadlocks. If an actor method needs to be async then it 
> should work just like any async method on the main queue: it unblocks the 
> queue and allows other messages to be processed until it gets an answer.
> 
> You do have to be aware of the fact that things can happen in between an 
> await and the next line of code, but conveniently these places are all marked 
> for you. They all say “await”. :)

It is correct that suspending the queue allows for deadlocks, but not doing it 
means you can receive messages while still in the middle of another message. 
For the same reason you may need FIFO ordering in a class to guarantee 
coherency, you will want this to work in an asynchronous world as well. Take 
for example some storage class:

1. store(object, key)
2. fetch(key)

If you're doing these operations in order, you want the fetch to return the 
object you just stored. If the 'store' needs to await something in its 
implementation and we were to not suspend the queue, the fetch would be 
processed before the object is actually stored and it would return something 
unexpected.

Thomas

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Marc Schlichte via swift-evolution

> Am 25.08.2017 um 01:15 schrieb Adam Kemp via swift-evolution 
> :
> 
> I don’t think await should cause the actor’s queue (or any queue) to be 
> suspended. Actor methods should not block waiting for asynchronous things. 
> That’s how you get deadlocks. If an actor method needs to be async then it 
> should work just like any async method on the main queue: it unblocks the 
> queue and allows other messages to be processed until it gets an answer.
> 
> You do have to be aware of the fact that things can happen in between an 
> await and the next line of code, but conveniently these places are all marked 
> for you. They all say “await”. :)

Yes, that is important to note: when we `await` on an `async` method, the 
callers queue does not get blocked in any way. The control flow just continues 
- with the next instruction after the enclosing `beginAsync` I suppose - and 
when done with the current DispatchWorkItem just dequeues the next 
DispatchWorkItem and works on it. If there is no next item, the underlying 
thread might still not be suspend but be used to work on some another queue.

Despite that, we might still want to discuss if actor-methods should get 
serialized beyond that - think of an underlying GCD queue (as discussed above) 
and a separate (non-GDC) message-queue where actor messages will get queued up. 
In another thread I proposed to introduce a new modifier for actor methods 
which will not put them into the message-queue and which are thus allowed to 
run whenever the GCD queue picks them up:

serialized by message-queue: 
`actor func foo() async`

non-serialized:
`interleaved actor func bar() async`

This way, when you reason about your code and look at places marked with 
`await`, only `interleaved` methods (or code using explicit `beginAsync` calls) 
might have changed your state.

Cheers
Marc

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Concurrency] Fixing race conditions in async/await example

2017-08-25 Thread Howard Lovatt via swift-evolution
Using a Future library, see below, you can do what you want. In particular
a future that is cancellable is more powerful that the proposed
async/await. Here is an extended example of a typical UI task including
users cancelling tasks that is written using a future library (see below):

@IBOutlet weak var timeButtonWasPressed: NSTextField!

static func progress(_ window: NSWindow, _ progress:
NSProgressIndicator) -> Future {
return AsynchronousFuture(timeout: .seconds(3)) { isCancelled ->
String in // Timeout set to 3 seconds to ensure normal progress closes the
window before timeout does.
defer { // Make sure the window always closes.
Thread.executeOnMain {
window.close()
}
}
var isFinished = false
var isClosed = false
while !(isFinished || isClosed || isCancelled()) {
Thread.sleep(forTimeInterval: 0.1) // Would do real work
here!
Thread.executeOnMain {
guard window.isVisible else { // Check if user has
closed the window.
isClosed = true
return
}
progress.increment(by: 1)
if progress.doubleValue >= progress.maxValue { // Check
if work done.
isFinished = true
}
}
}
if isClosed || isCancelled() { // Cancelled by user closing
window, by call to `cancel`, or by timeout
throw CancelFuture.cancelled
}
return "\(DispatchTime.now().uptimeNanoseconds)"
}
}

var windowOrigin = NSPoint(x: 0, y: NSScreen.main?.visibleFrame.height
?? 0) // First window in top left of screen.

@IBAction func buttonPushed(_ _: NSButton) {
let progressFrame = NSRect(x: 10, y: 10, width: 200, height: 100)
// On main thread; pop up a progress window.
let progress = NSProgressIndicator(frame: progressFrame)
progress.minValue = 0
progress.maxValue = 20
progress.isIndeterminate = false
let windowFrame = NSRect(x: 0, y: 0, width: progressFrame.width +
20, height: progressFrame.height + 20)
let window = NSWindow(contentRect: windowFrame, styleMask:
[.titled, .closable], backing: .buffered, defer: false)
window.contentView?.addSubview(progress)
windowOrigin = window.cascadeTopLeft(from: windowOrigin) //
Position window.
window.isReleasedWhenClosed = false // Needed to keep ARC happy!
window.orderFront(self) // Display the window but don't give it the
focus.
let _ = AsynchronousFuture { _ -> Void in // Runs on global default
queue.
let creationTime = ViewController.progress(window,
progress).get ?? "Cancelled" // Progress bar with close to allow user
cancellation and finishes automatically after 2 seconds to allow
cancellation or many button presses to pop up other progress windows.
Thread.executeOnMain {
self.timeButtonWasPressed.stringValue = creationTime
}
}
}

The above pops up a window with a progress bar in it every time the user
hits a button (buttonPushed), once the progress bar has completed or is
cancelled the main UI is updated, including noting cancellation by the
user. It can popup multiple windows and cancel them in any order.

This is easier to do with a future library than the proposed async/await
because the library has concepts of: cancellation, timeout, and control
over which queue routines run on.

Future library below:

//
//  main.swift
//  Future
//  Version 0.1
//
//  Created by Howard Lovatt on 22/8/17.
//  Copyright © 2017 Howard Lovatt.
//  This work is licensed under a Creative Commons Attribution 4.0
International License, http://creativecommons.org/licenses/by/4.0/.
//

import Foundation

/// - note:
///   - Written in GCD but execution service would be abstracted for a
'real' version of this proposed `Future`.
///   - It might be necessary to write an atomic class/struct and use it
for _status and isCancelled in CalculatingFuture; see comments after
property declarations.
///   - If _status and isCancelled in CalculatingFuture where atomic then
future would be thread safe.

extension Thread {
/// Run the given closure on the main thread (thread hops to main) and
*wait* for it to complete before returning its value; useful for updating
and reading UI components.
/// Checks to see if already executing on the main thread and if so
does not change to main thread before executing closure, since changing to
main when already on main would cause a deadlock.
/// - note: Not unique to `Future`, hence an extension on `Thread`.
static func executeOnMain(closure: @escaping () -> T) -> T {
var result: T?
if Thread.isMainThread {
result = closure()
} else {
DispatchQueue.main.sync {

Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-25 Thread Marc Schlichte via swift-evolution

> Am 24.08.2017 um 22:05 schrieb Thomas via swift-evolution 
> :
> 
>> 
>> Yes, I think it is mandatory that we continue on the callers queue after an 
>> `await ` on some actor method.
>> 
>> If you `await` on a non-actor-method though, you would have to changes 
>> queues manually if needed.
>> 
>> Any `actor` should have a `let actorQueue: DispatchQueue` property so that 
>> we can call in these cases:
>> 
>> ```await actorQueue.asyncCoroutine()``` as mentioned in the manifesto.
> 
> Wouldn't that be really confusing though? That awaiting certain methods would 
> bring us back to the actor's queue but awaiting others would require manual 
> queue hopping? What if the compiler was to always generate the 'await 
> actorQueue.asyncCoroutine()' queue hopping code after awaiting on an 
> async/actor method?
> 
> Thomas
> 

I think we are not allowed to implicitly switch back to the actor's queue after 
awaiting non-actor methods. These might have been auto converted from 
Continuation-Passing-Style (CPS) to async/await style. With the `mainActor` 
idea from the manifesto, all existing code will run in some actor, so changing 
the queue semantics could break existing code.

Actually, I don’t find it confusing: when calling non-actor methods, you have 
to take care by yourself - as today. Calling actor methods instead, you don’t 
have to bother about this any longer - this is actually a big incentive to 
‚actorify‘ many APIs ;-)

Cheers
Marc___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution