Re: [swift-evolution] New async keyword usage

2017-08-24 Thread Chris Lattner via swift-evolution

> 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?

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


Re: [swift-evolution] [Concurrency] Passing classes between actors

2017-08-24 Thread Chris Lattner via swift-evolution

> On Aug 23, 2017, at 2:18 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> There seems to be an open question about how to handle passing mutable state 
> between actors (or possibly just disallowing it). I have a germ of an idea, 
> and I thought I would share in case it triggers a more fully formed idea in 
> someone.
> 
> We should have an extremely easy way to wrap a bit of mutable state in a 
> bubble of the actor that owns it… or rather, we should be able to 
> effortlessly create a proxy to mutable state within an actor (either objects, 
> global properties, or closures) for sharing with another actor.  For objects, 
> the proxy would basically convert method calls to asynchronous messages. In 
> my mind, the wrapper would hold a reference to the actor’s internal queue, 
> and would forward the message to the object/closure within that queue, then 
> asynchronously return the value (if any) to the calling actor.
> 
> Note that this is different than having properties/methods on the actor 
> itself, since the wrapper/proxy might not be shared publicly, and it can be 
> passed around like an object/closure.  It allows a bunch of patterns that 
> aren’t possible otherwise.  For example, I could ask an actor for a callback 
> closure to call when something has been completed… and the callback that I 
> receive might be unique to me, which allows the actor to field multiple 
> requests asynchronously/independently (Instead of having to track state 
> internally, it can just use the closure to clean up).

As you say, this is effectively a closure around a reference to a state with a 
guarantee that it will only be touched in the context of the proper actor.  I’m 
not exactly sure how this sketch of an idea would work, but I think that 
something like it is very likely to follow from the basic design.  

That’s sort of the appeal of starting from a minimal design: with the basics in 
place, we can look at the pain points in practice, and figure out how to expand 
them out to support common patterns like this.  What you describe seems very 
likely to me, and I hope it is something we can express with a library rather 
than a language feature.

-Chris

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


Re: [swift-evolution] [Concurrency] Async/Await

2017-08-24 Thread Howard Lovatt via swift-evolution
You are correct, my mistake. Example should read:

func processImageData1() -> Future {
return AsynchronousFuture { _ -> Image in
let dataResource  = loadWebResource("dataprofile.txt") //
dataResource and imageResource run in parallel.
let imageResource = loadWebResource("imagedata.dat")
let imageTmp  = decodeImage(dataResource.get ?? Resource(path:
"Default data resource or prompt user"), imageResource.get ??
Resource(path: "Default image resource or prompt user"))
let imageResult   =  dewarpAndCleanupImage(imageTmp.get ??
Image(dataPath: "Default image or prompt user", imagePath: "Default image
or prompt user"))
return imageResult.get ?? Image(dataPath: "Default image or prompt
user", imagePath: "Default image or prompt user")
}
}


  -- Howard.

On 25 August 2017 at 00:25, BJ Homer  wrote:

> Your processImageData1() function is not asynchronous, and does not need
> to return a future, because the “.get” calls are blocking; as you have
> implemented them, they will wait until they have a response or timeout. As
> a result, by the time you reach the return imageResult line, you have
> already waited for that data (or timed out), with the current thread
> blocked. There is no work left to do in the Future.
>
> The point of async/await is that we can wait for the completion of those
> items *asynchronously*, not blocking the current thread. The control
> would return to the calling function before all the data was fetched.
>
> -BJ
>
> On Aug 23, 2017, at 7:35 PM, Howard Lovatt via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi All,
>
> Really glad that concurrency is on the table for Swift 5.
>
> I am not sure if async/await are worth adding, as is, to Swift because it
> is just as easy to do with a library function - in the spirit of Swift 5,
> see `Future` library code below that you can play with and run.
>
> If a `Future` class was added and the compiler translated
> 'completion-handler' code to 'future' code then the running example given
> in the whitepaper would become (also see the example in the code below):
>
> func loadWebResource(_ path: String) -> Future { ... }
> func decodeImage(_ dataResource: Resource, _ imageResource: Resource) ->
> Future { ... }
> func dewarpAndCleanupImage(_ image: Image) -> Future { ... }
>
> func processImageData1() -> Future {
> let dataResource  = loadWebResource("dataprofile.txt") //
> dataResource and imageResource run in parallel.
> let imageResource = loadWebResource("imagedata.dat")
> let imageTmp  = decodeImage(dataResource.get ?? Resource(path:
> "Default data resource or prompt user"), imageResource.get ??
> Resource(path: "Default image resource or prompt user"))
> let imageResult   =  dewarpAndCleanupImage(imageTmp.get ??
> Image(dataPath: "Default image or prompt user", imagePath: "Default image
> or prompt user"))
> return imageResult
> }
>
>
> Which I would argue is actually better than the proposed async/await code
> because:
>
>1. The code is naturally parallel, in example dataResource and
>imageResource are calculated in parallel.
>2. The code handles errors and deadlocks by providing a default value
>using `??`.
>3. The code can be deadlock free or can help find deadlocks, see code
>below, due to having a timeout and a means of cancelling.
>4. The programmer who writes the creator of the `Future` controls
>which queue the future executes on, I would contend that this is the best
>choice since the programmer knows what limitations are in the code and can
>change queue if the code changes in later versions. This is the same
>argument as encapsulation, which gives more control to the writer of a
>struct/class and less control to the user of the struct/class.
>
> In summary, I don't think async/await carries its weight (pun intended),
> as it stands, compared to a library.
>
> But definitely for more Swift concurrency,
>
>  -- Howard.
>
> PS A memory model and atomic that also guaranteed volatile would really
> help with parallel programming!
>
> …(snip)...
>
> ___
> 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] Two thoughts on concurrency

2017-08-24 Thread Chris Lattner via swift-evolution

> On Aug 24, 2017, at 9:17 PM, Félix Cloutier  wrote:
> 
> I feel that it's important to point out that this example feels weird because 
> even though the compiler doesn't treat "weak" as a reserved term, most 
> developers perceive it as one. I don't think that David is worried that we're 
> taking away all the cool words from the realm of identifiers; the problem is 
> that "technically not a keyword" is a qualifier mostly distinct from "not 
> perceived as a keyword". Even if attributes don't live in the same token 
> namespace as identifiers as far as the compiler is perceived, I'd argue that 
> they add about the same complexity (or more) to the mental model that 
> developers have to have about the language.

Obviously details matter here, but there is an important time and place to 
introduce a “conceptual” keyword: it is when there is an important and distinct 
concept that needs to be thought about by the humans that interact with the 
code.

In the proposal “actor” vs “distributed actor” is one of those really important 
distinctions, which is why (IMO) it deserves the “complexity” of a new 
identifier.  It isn’t the identifier that adds the complexity, it is the 
expansion of the language surface that the identifier designates.

-Chris




> Félix
> 
>> Le 24 août 2017 à 20:58, Chris Lattner via swift-evolution 
>> > a écrit :
>> 
>> 
>>> On Aug 24, 2017, at 8:57 PM, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
>>> On Aug 24, 2017, at 1:59 PM, Dave DeLong via swift-evolution 
>>> > wrote:
 Keyword Explosion
 
 During the Great Access Control Wars of Swift 4, one of the points that 
 kept coming up was the reluctance to introduce a bazillion new keywords to 
 address all the cases that were being brought up. The impression I got is 
 that adding new keywords was essentially an anti-pattern. And so when I’m 
 reading through this onslaught of emails, I’m troubled by how everything 
 is seeming to require new keywords. There’s the obvious async/await, but 
 there’s also been discussion of actor, reliable, distributed, behavior, 
 message, and signal (and I’ve probably missed others).
>>> 
>>> I can’t speak for message/signal, but you need to understand a bit more 
>>> about how Swift works.  There is a distinction between an actual keyword 
>>> (which ‘async’ would be, and ‘class’ currently is) and “modifiers”.  
>>> Modifiers occur with attributes ahead of a real keyword, but they are not 
>>> themselves keywords.  They are things like weak, mutating, reliable, 
>>> distributed, etc.  If we go with the “actor class” and “actor func” 
>>> approach, then actor would not be a keyword.
>> 
>> Concrete example, this is (weird but) valid code:
>> 
>> var weak = 42
>> weak += 2
>> print(weak+weak)
>> 
>> 
>> This is a consequence of weak not being a keyword.
>> 
>> -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] Two thoughts on concurrency

2017-08-24 Thread Félix Cloutier via swift-evolution
I feel that it's important to point out that this example feels weird because 
even though the compiler doesn't treat "weak" as a reserved term, most 
developers perceive it as one. I don't think that David is worried that we're 
taking away all the cool words from the realm of identifiers; the problem is 
that "technically not a keyword" is a qualifier mostly distinct from "not 
perceived as a keyword". Even if attributes don't live in the same token 
namespace as identifiers as far as the compiler is perceived, I'd argue that 
they add about the same complexity (or more) to the mental model that 
developers have to have about the language.

Félix

> Le 24 août 2017 à 20:58, Chris Lattner via swift-evolution 
>  a écrit :
> 
> 
>> On Aug 24, 2017, at 8:57 PM, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>> On Aug 24, 2017, at 1:59 PM, Dave DeLong via swift-evolution 
>> > wrote:
>>> Keyword Explosion
>>> 
>>> During the Great Access Control Wars of Swift 4, one of the points that 
>>> kept coming up was the reluctance to introduce a bazillion new keywords to 
>>> address all the cases that were being brought up. The impression I got is 
>>> that adding new keywords was essentially an anti-pattern. And so when I’m 
>>> reading through this onslaught of emails, I’m troubled by how everything is 
>>> seeming to require new keywords. There’s the obvious async/await, but 
>>> there’s also been discussion of actor, reliable, distributed, behavior, 
>>> message, and signal (and I’ve probably missed others).
>> 
>> I can’t speak for message/signal, but you need to understand a bit more 
>> about how Swift works.  There is a distinction between an actual keyword 
>> (which ‘async’ would be, and ‘class’ currently is) and “modifiers”.  
>> Modifiers occur with attributes ahead of a real keyword, but they are not 
>> themselves keywords.  They are things like weak, mutating, reliable, 
>> distributed, etc.  If we go with the “actor class” and “actor func” 
>> approach, then actor would not be a keyword.
> 
> Concrete example, this is (weird but) valid code:
> 
> var weak = 42
> weak += 2
> print(weak+weak)
> 
> 
> This is a consequence of weak not being a keyword.
> 
> -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] Two thoughts on concurrency

2017-08-24 Thread Chris Lattner via swift-evolution

> On Aug 24, 2017, at 8:57 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> On Aug 24, 2017, at 1:59 PM, Dave DeLong via swift-evolution 
> > wrote:
>> Keyword Explosion
>> 
>> During the Great Access Control Wars of Swift 4, one of the points that kept 
>> coming up was the reluctance to introduce a bazillion new keywords to 
>> address all the cases that were being brought up. The impression I got is 
>> that adding new keywords was essentially an anti-pattern. And so when I’m 
>> reading through this onslaught of emails, I’m troubled by how everything is 
>> seeming to require new keywords. There’s the obvious async/await, but 
>> there’s also been discussion of actor, reliable, distributed, behavior, 
>> message, and signal (and I’ve probably missed others).
> 
> I can’t speak for message/signal, but you need to understand a bit more about 
> how Swift works.  There is a distinction between an actual keyword (which 
> ‘async’ would be, and ‘class’ currently is) and “modifiers”.  Modifiers occur 
> with attributes ahead of a real keyword, but they are not themselves 
> keywords.  They are things like weak, mutating, reliable, distributed, etc.  
> If we go with the “actor class” and “actor func” approach, then actor would 
> not be a keyword.

Concrete example, this is (weird but) valid code:

var weak = 42
weak += 2
print(weak+weak)


This is a consequence of weak not being a keyword.

-Chris


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


Re: [swift-evolution] Two thoughts on concurrency

2017-08-24 Thread Chris Lattner via swift-evolution
On Aug 24, 2017, at 1:59 PM, Dave DeLong via swift-evolution 
 wrote:
> Keyword Explosion
> 
> During the Great Access Control Wars of Swift 4, one of the points that kept 
> coming up was the reluctance to introduce a bazillion new keywords to address 
> all the cases that were being brought up. The impression I got is that adding 
> new keywords was essentially an anti-pattern. And so when I’m reading through 
> this onslaught of emails, I’m troubled by how everything is seeming to 
> require new keywords. There’s the obvious async/await, but there’s also been 
> discussion of actor, reliable, distributed, behavior, message, and signal 
> (and I’ve probably missed others).

I can’t speak for message/signal, but you need to understand a bit more about 
how Swift works.  There is a distinction between an actual keyword (which 
‘async’ would be, and ‘class’ currently is) and “modifiers”.  Modifiers occur 
with attributes ahead of a real keyword, but they are not themselves keywords.  
They are things like weak, mutating, reliable, distributed, etc.  If we go with 
the “actor class” and “actor func” approach, then actor would not be a keyword.

> I’m not opposed to adding new keywords by any means, but can we get some 
> clarification on some limits of reasonableness? What restraint (if any) 
> should we be exercising as we consider this feature?

There is no general rule that can be applied.  Details matter.

> Language vs Library Feature
> 
> Related to the explosion of keywords is the question of whether the 
> concurrency model is going to be a language feature or a library feature. 
> Allow me to explain…
> 
> We currently have language support for errors with throws and try (and 
> friends):
> 
> func doSomething() throws → Value { … }
> 
> let value = try doSomething()
> 
> However, this could be viewed as sugar syntax for a hypothetical library 
> feature involving a Result type:
> 
> func doSomething() → Result { … }
> 
> let value = doSomething().value! // or however you get the value of a Result
> 
> In other words, throws and try are the language support for silently hiding a 
> Result type.

Sort of, but I see what you’re saying.

> I would be really happy if whatever concurrency model we end up with ends up 
> being sugar syntax for a library feature, such that async and await (or 
> whatever we decide on) become sugar for dealing with a Future type or 
> whatever. Implementing concurrency in this manner would free app developers 
> to handle concurrency in the manner in which they’re familiar. If you wanted, 
> you call the function without await and get back the underlying Future. 
> async becomes sugar for simplifying the return type, like in the throws 
> example above. try await becomes sugar for fulfilling the promise or dealing 
> with a cancellation (or other) error, etc.

I understand the conceptual ideal of something being "pure sugar”, but that it 
is also limiting.  The design as proposed is exactly the opposite of what you 
suggest: since there are many interesting user facing libraries (future is just 
one of them) that can be built on top of the primitive language features.

You can still think of the primitives as being built in terms of futures if 
that makes sense to you, but it isn’t any more correct than it is to say that 
throws is implemented in terms of a hidden result type.

-Chris


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


Re: [swift-evolution] Two thoughts on concurrency

2017-08-24 Thread Yuta Koshizawa via swift-evolution
Hi,

Although `throws` and `async` are similar to return a `Result` and a
`Future` respectively as you say, However, `try` and `await` are
corresponding to `flatMap` theoretically.

// `throws/try`
func foo() throws -> Int { ... }

func bar() throws -> Int {
  let a: Int = try foo()
  let b: Int = try foo()
  return a + b
}

// `Result`
func foo() -> Result { ... }

func bar() -> Result {
  return foo().flatMap { a: Int in
foo().flatMap { b: Int in
  return a + b
}
  }
}

// `async/await`
func foo() async -> Int { ... }

func bar() async -> Int {
  let a: Int = await foo()
  let b: Int = await foo()
  return a + b
}

// `Future`
// `flatMap` works like `then` of JS's `Promise`
// I have an implementation of such `Promise` in Swift
// https://github.com/koher/PromiseK/tree/dev-3.0
func foo() -> Future { ... }

func bar() -> Future {
  return foo().flatMap { a: Int in
foo().flatMap { b: Int in
  return a + b
}
  }
}

Also, thinking about something like `do/catch` for `async/await`, I
think `do` for blocking is consistent because it should be possible to
return a value from inside `do {}` as well as `do/catch`. For example:

// `throws/try`
func bar() -> Int {
  do {
return try foo()
  } catch {
...
  }
}

// `async/await`
func bar() -> Int {
  do {
return await foo()
  } block
}

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


Re: [swift-evolution] Two thoughts on concurrency

2017-08-24 Thread Dave DeLong via swift-evolution

> On Aug 24, 2017, at 3:59 PM, Adam Kemp  wrote:
> 
> I generally agree that async/await could be more valuable built on top of 
> library support. I did have one nitpick about this:
> 
>> On Aug 24, 2017, at 1:59 PM, Dave DeLong via swift-evolution 
>> > wrote:
>> 
>> In other words:
>> 
>> async func doSomething() → Value { … }
>> 
>> Let value = await doSomething()
>> 
>> Becomes sugar for this pseudocode:
>> 
>> func doSomething() → Future { … }
>> 
>> let value = doSomething().value // or however you “wait” for the value
> 
> These two examples do fundamentally different things. The await version 
> doesn’t block the thread (it would return to the caller instead of blocking 
> and pick up again later). The .value version would have to block. In C# this 
> is equivalent to using the .Result property of the Task type. However, 
> that is strongly discouraged because it easily leads to deadlocks.
> 
> A closer equivalent would be something like this:
> 
> func doSomething() -> Future { … }
> 
> doSomething().continueWith { (future: Future) in
> let value = try? future.value
> }
> 
> Now it’s asynchronous either way. The continuation block takes a 
> Future so that you could do error handling (more complex error 
> handling not shown).

That’s fine. I assumed it was blocking because it has a very prominent “wait” 
in the name. 路‍♂️ 

>> I’m admittedly not very familiar with async/await or the actor pattern.

:) 

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-24 Thread Adam Kemp via swift-evolution


> 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”. :)___
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-24 Thread Thomas via swift-evolution

> 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)

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


Re: [swift-evolution] Two thoughts on concurrency

2017-08-24 Thread Adam Kemp via swift-evolution
I generally agree that async/await could be more valuable built on top of 
library support. I did have one nitpick about this:

> On Aug 24, 2017, at 1:59 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> In other words:
> 
> async func doSomething() → Value { … }
> 
> Let value = await doSomething()
> 
> Becomes sugar for this pseudocode:
> 
> func doSomething() → Future { … }
> 
> let value = doSomething().value // or however you “wait” for the value

These two examples do fundamentally different things. The await version doesn’t 
block the thread (it would return to the caller instead of blocking and pick up 
again later). The .value version would have to block. In C# this is equivalent 
to using the .Result property of the Task type. However, that is strongly 
discouraged because it easily leads to deadlocks.

A closer equivalent would be something like this:

func doSomething() -> Future { … }

doSomething().continueWith { (future: Future) in
let value = try? future.value
}

Now it’s asynchronous either way. The continuation block takes a Future 
so that you could do error handling (more complex error handling not shown).___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Two thoughts on concurrency

2017-08-24 Thread Jean-Daniel via swift-evolution

> Le 24 août 2017 à 22:59, Dave DeLong via swift-evolution 
>  a écrit :
> 
> Hi everyone,
> 
> (the standard disclaimer of “I’m neither a compiler engineer nor a language 
> design expert” applies)
> 
> I’ve been trying to keep up with all the discussion around concurrency going 
> on, and I’m admittedly not very familiar with async/await or the actor 
> pattern.
> 
> However, a couple of things worry me about the direction the conversation 
> seems to be going:
> 
> Keyword Explosion
> 
> During the Great Access Control Wars of Swift 4, one of the points that kept 
> coming up was the reluctance to introduce a bazillion new keywords to address 
> all the cases that were being brought up. The impression I got is that adding 
> new keywords was essentially an anti-pattern. And so when I’m reading through 
> this onslaught of emails, I’m troubled by how everything is seeming to 
> require new keywords. There’s the obvious async/await, but there’s also been 
> discussion of actor, reliable, distributed, behavior, message, and signal 
> (and I’ve probably missed others).
> 
> I’m not opposed to adding new keywords by any means, but can we get some 
> clarification on some limits of reasonableness? What restraint (if any) 
> should we be exercising as we consider this feature?
> 
> Language vs Library Feature
> 
> Related to the explosion of keywords is the question of whether the 
> concurrency model is going to be a language feature or a library feature. 
> Allow me to explain…
> 
> We currently have language support for errors with throws and try (and 
> friends):
> 
> func doSomething() throws → Value { … }
> 
> let value = try doSomething()
> 
> However, this could be viewed as sugar syntax for a hypothetical library 
> feature involving a Result type:
> 
> func doSomething() → Result { … }
> 
> let value = doSomething().value! // or however you get the value of a Result
> 
> In other words, throws and try are the language support for silently hiding a 
> Result type.

It not only hide a Result type, it also allow the compiler to perform some 
optimization that would not be possible with a pure library implementation, 
like using a custom calling convention. 

The same probably apply to coroutines.

> I would be really happy if whatever concurrency model we end up with ends up 
> being sugar syntax for a library feature, such that async and await (or 
> whatever we decide on) become sugar for dealing with a Future type or 
> whatever. Implementing concurrency in this manner would free app developers 
> to handle concurrency in the manner in which they’re familiar. If you wanted, 
> you call the function without await and get back the underlying Future. 
> async becomes sugar for simplifying the return type, like in the throws 
> example above. try await becomes sugar for fulfilling the promise or dealing 
> with a cancellation (or other) error, etc.

I don’t think Future should even exists. As stated in the manifest, it add some 
cost to all calls with no benefit for most coroutine users.


___
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-24 Thread Adam Kemp via swift-evolution

> 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.___
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-24 Thread Ben Rimmington via swift-evolution
Re: 

Chris Lattner recently commented in  
that the prototype could use  support.

In one of the CppCon videos, Gor Nishanov said that C++ coroutines won't have 
an `async` keyword, and will be compatible with function pointers in C and C++.

* 


* 

* 


I couldn't find the reason for this decision; does anyone here know why C++ 
coroutines don't need an `async` keyword?

And/or why do Swift coroutines need the `async` keyword? Does it imply a hidden 
parameter, like the `throws` keyword?

-- Ben

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


Re: [swift-evolution] (core library) modern URL types

2017-08-24 Thread Eagle Offshore via swift-evolution
I liked the polymorphic identifiers paper presented at Dynamic Languages 
Symposium 2013.

http://dl.acm.org/citation.cfm?doid=2508168.2508169 


There's a lot of power in URI's that remains largely untapped in most systems.

There's not a great reason for this heterogeneity other than historical baggage.

Properly done, URI's can unify keypaths, user defaults, environment variables, 
files, network stores, databases, etc.


> On Aug 22, 2017, at 12:52 PM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> Just leaving it out here that the iOS/macOS app experience with paths is 
> likely to be very different from the server (or system program) experience. 
> Most of your paths are relative to a container because the effective root of 
> your data is the container. I would tend to believe that a lot of your paths, 
> not while fully static, could be expressed with something like 
> "${DOCUMENTS}/static/part", where ${DOCUMENTS} is the only thing that 
> effectively changes. A system-level program just happens to use / as its 
> prefix.
> 
> Most platforms already have some notion of file domains, which are really 
> just path prefixes (the user's home folder, the file system root, the network 
> root, etc). I think that some level of support for these would be desirable 
> (would it be only a set of functions that return different path prefixes). 
> It's also my humble opinion that tilde expansion should be part of a larger 
> shell expansion feature to avoid surprises.
> 
> I think that I support the conclusion.
> 
> Félix
> 
> Le 22 août 2017 à 12:02, Dave DeLong  a écrit :
> 
>> I suppose, if you squint at it weirdly.
>> 
>> My current Path API is a “Path” protocol, with “AbsolutePath” and 
>> “RelativePath” struct versions. The protocol defines a path to be an array 
>> of path components. The only real difference between an AbsolutePath and a 
>> RelativePath is that all file system operations would only take an 
>> AbsolutePath. A URL would also only provide an AbsolutePath as its “path” 
>> bit.
>> 
>> public enum PathComponent {
>> case this // “."
>> case up   // “..” 
>> case item(name: String, extension: String?)
>> }
>> 
>> public protocol Path {   
>> var components: Array { get }
>> init(_ components: Array) // used on protocol extensions 
>> that mutate paths, such as appending components
>> }
>> 
>> public struct AbsolutePath: Path { }
>> public struct RelativePath: Path { }
>> 
>> By separating out the concept of an Absolute and a Relative path, I can put 
>> additional functionality on each one to make semantic sense (you cannot 
>> concatenate two absolute paths, but you can concat any path with a relative 
>> path, for example). Or all file system operations must take an AbsolutePath. 
>> 
>> One of the key things I realized is that a “Path” type should not be 
>> ExpressibleByStringLiteral, because you cannot statically determine if a 
>> Path should be absolute or relative. However, one of the initializers for an 
>> AbsolutePath would handle things like expanding a tilde, and both types try 
>> to reduce a set of components as much as possible (by filtering out “.this” 
>> components, and handling “.up” components where possible, etc). Also in my 
>> experience, it’s fairly rare to want to deal with a known-at-compile-time, 
>> hard-coded path. Usually you’re dealing with paths relative to known 
>> “containers” that are determined at runtime (current user’s home folder, 
>> app’s sandboxed documents directory, etc).
>> 
>> Another thing I’ve done is that no direct file system operations exist on 
>> AbsolutePath (like “.exists” or “.createDirectory(…)” or whatever); those 
>> are still on FileManager/FileHandle/etc in the form of extensions to handle 
>> the new types. In my app, a path is just a path, and it only has meaning 
>> based on the thing that is using it. An AbsolutePath for a URL is used 
>> differently than an AbsolutePath on a file system, although they are 
>> represented with the same “AbsolutePath” type.
>> 
>> I’m not saying this is a perfect API of course, or even that a hypothetical 
>> stdlib-provided Path should mimic this. I’m just saying that for my 
>> use-case, this has vastly simplified how I deal with paths, because both URL 
>> and String smell really bad for what I’m doing.
>> 
>> Dave
>> 
>>> On Aug 22, 2017, at 12:37 PM, Taylor Swift >> > wrote:
>>> So are you saying we need three distinct “URI” types for local-absolute, 
>>> local-relative, and remote? That’s a lot of API surface to support.
>>> 
>>> On Tue, Aug 22, 2017 at 12:24 PM, Dave DeLong >> > wrote:
>>> I completely agree. URL packs a lot of punch, but IMO it’s the wrong 
>>> abstraction for file system paths.
>>> 
>>> I maintain an app that deals a lot with file system paths, and 

[swift-evolution] Two thoughts on concurrency

2017-08-24 Thread Dave DeLong via swift-evolution
Hi everyone,

(the standard disclaimer of “I’m neither a compiler engineer nor a language 
design expert” applies)

I’ve been trying to keep up with all the discussion around concurrency going 
on, and I’m admittedly not very familiar with async/await or the actor pattern.

However, a couple of things worry me about the direction the conversation seems 
to be going:

Keyword Explosion

During the Great Access Control Wars of Swift 4, one of the points that kept 
coming up was the reluctance to introduce a bazillion new keywords to address 
all the cases that were being brought up. The impression I got is that adding 
new keywords was essentially an anti-pattern. And so when I’m reading through 
this onslaught of emails, I’m troubled by how everything is seeming to require 
new keywords. There’s the obvious async/await, but there’s also been discussion 
of actor, reliable, distributed, behavior, message, and signal (and I’ve 
probably missed others).

I’m not opposed to adding new keywords by any means, but can we get some 
clarification on some limits of reasonableness? What restraint (if any) should 
we be exercising as we consider this feature?

Language vs Library Feature

Related to the explosion of keywords is the question of whether the concurrency 
model is going to be a language feature or a library feature. Allow me to 
explain…

We currently have language support for errors with throws and try (and friends):

func doSomething() throws → Value { … }

let value = try doSomething()

However, this could be viewed as sugar syntax for a hypothetical library 
feature involving a Result type:

func doSomething() → Result { … }

let value = doSomething().value! // or however you get the value of a Result

In other words, throws and try are the language support for silently hiding a 
Result type.

I would be really happy if whatever concurrency model we end up with ends up 
being sugar syntax for a library feature, such that async and await (or 
whatever we decide on) become sugar for dealing with a Future type or 
whatever. Implementing concurrency in this manner would free app developers to 
handle concurrency in the manner in which they’re familiar. If you wanted, you 
call the function without await and get back the underlying Future. async 
becomes sugar for simplifying the return type, like in the throws example 
above. try await becomes sugar for fulfilling the promise or dealing with a 
cancellation (or other) error, etc.

In other words:

async func doSomething() → Value { … }

Let value = await doSomething()

Becomes sugar for this pseudocode:

func doSomething() → Future { … }

let value = doSomething().value // or however you “wait” for the value

(Incidentally, I would love to see this pattern retroactively applied for 
throws and errors)

Please don’t all break out your pitchforks at once.  

Cheers,

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-24 Thread Thomas via swift-evolution

> On 24 Aug 2017, at 22:05, Thomas via swift-evolution 
>  wrote:
> 
>> 
>> On 24 Aug 2017, at 21:48, Marc Schlichte > > wrote:
>> 
>> 
>>> Am 24.08.2017 um 01:56 schrieb Adam Kemp >> >:
>>> 
>>> 
>>> 
 On Aug 23, 2017, at 4:28 PM, Marc Schlichte via swift-evolution 
 > wrote:
 
 
> Am 23.08.2017 um 12:29 schrieb Thomas via swift-evolution 
> >:
> 
> 
>> On 23 Aug 2017, at 11:28, Thomas via swift-evolution 
>> > wrote:
>> 
>> 1. What happens to the actor's queue when the body of a (non 
>> void-returning) actor method awaits away on some other actor? Does it 
>> suspend the queue to prevent other messages from being processes? It 
>> would seem to be the expected behavior but we'd also need a way to 
>> detach from the actor's queue in order to allow patterns like starting a 
>> long-running background operation and still allowing other messages to 
>> be processed (for example, calling a cancel() method). We could still do 
>> these long-running operations by passing a completion block to the 
>> method, rather than via its return value. That would clarify this goes 
>> beyond this one actor message, but we're back to the old syntax...
> 
> Maybe that's where Futures would come in handy? Just return a Future from 
> the method so callers can await long-running operations.
 
 If you wrap the call to a long-running operation of another actor in a 
 `beginAsync`, I would assume that other `actor funcs` of your actor will 
 be able to run even while
  the long-running operation is pending:
 
 actor class Caller {
   let callee = Callee()
   var state = SomeState()
 
   actor func foo() {
 beginAsync {
   let result = await callee.longRunningOperation()
   // do something with result and maybe state
 }
   }
   actor func bar() {
 // modify actor state
   }
 }
>>> 
>>> As currently proposed, the “// do something with result and maybe state” 
>>> line would likely run on Callee’s queue, not Caller’s queue. I still 
>>> strongly believe that this behavior should be reconsidered.
>>> 
>>> It does, however, bring up some interesting questions about how actors 
>>> interact with themselves. One of the rules laid out in Chris’s document 
>>> says that “local state and non-actor methods may only be accessed by 
>>> methods defined lexically on the actor or in an extension to it (whether 
>>> they are marked actor or otherwise).” That means it would be allowed for 
>>> the code in foo() to access state and call non-actor methods, even after 
>>> the await. As proposed that would be unsafe, and since the queue is an 
>>> implementation detail inaccessible to your code there wouldn’t be a 
>>> straightforward way to get back on the right queue to make it safe. I 
>>> presume you could call another actor method to get back on the right queue, 
>>> but having to do that explicitly after every await in an actor method seems 
>>> tedious and error prone.
>>> 
>>> In order to have strong safety guarantees for actors you would want to 
>>> ensure that all the code that has access to the state runs on the actor’s 
>>> queue. There are currently two holes I can think of that would prevent us 
>>> from having that protection: await and escaping blocks. await could be made 
>>> safe if it were changed to return to the calling queue. Maybe escaping 
>>> blocks could be restricted to only calling actor methods.
>> 
>> 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?

Adding a bit more about that: I think it doesn't matter what the callee is 
(async vs. actor). What matters is we're calling from an actor method and the 
compiler should guarantee that we're running in the context of the actor's 
queue. Therefore I would tend to think there should be no need for manual queue 
hopping. The compiler should just take care of it.

Thomas


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

2017-08-24 Thread Thomas via swift-evolution

> On 24 Aug 2017, at 21:48, Marc Schlichte  
> wrote:
> 
> 
>> Am 24.08.2017 um 01:56 schrieb Adam Kemp > >:
>> 
>> 
>> 
>>> On Aug 23, 2017, at 4:28 PM, Marc Schlichte via swift-evolution 
>>> > wrote:
>>> 
>>> 
 Am 23.08.2017 um 12:29 schrieb Thomas via swift-evolution 
 >:
 
 
> On 23 Aug 2017, at 11:28, Thomas via swift-evolution 
> > wrote:
> 
> 1. What happens to the actor's queue when the body of a (non 
> void-returning) actor method awaits away on some other actor? Does it 
> suspend the queue to prevent other messages from being processes? It 
> would seem to be the expected behavior but we'd also need a way to detach 
> from the actor's queue in order to allow patterns like starting a 
> long-running background operation and still allowing other messages to be 
> processed (for example, calling a cancel() method). We could still do 
> these long-running operations by passing a completion block to the 
> method, rather than via its return value. That would clarify this goes 
> beyond this one actor message, but we're back to the old syntax...
 
 Maybe that's where Futures would come in handy? Just return a Future from 
 the method so callers can await long-running operations.
>>> 
>>> If you wrap the call to a long-running operation of another actor in a 
>>> `beginAsync`, I would assume that other `actor funcs` of your actor will be 
>>> able to run even while
>>>  the long-running operation is pending:
>>> 
>>> actor class Caller {
>>>   let callee = Callee()
>>>   var state = SomeState()
>>> 
>>>   actor func foo() {
>>> beginAsync {
>>>   let result = await callee.longRunningOperation()
>>>   // do something with result and maybe state
>>> }
>>>   }
>>>   actor func bar() {
>>> // modify actor state
>>>   }
>>> }
>> 
>> As currently proposed, the “// do something with result and maybe state” 
>> line would likely run on Callee’s queue, not Caller’s queue. I still 
>> strongly believe that this behavior should be reconsidered.
>> 
>> It does, however, bring up some interesting questions about how actors 
>> interact with themselves. One of the rules laid out in Chris’s document says 
>> that “local state and non-actor methods may only be accessed by methods 
>> defined lexically on the actor or in an extension to it (whether they are 
>> marked actor or otherwise).” That means it would be allowed for the code in 
>> foo() to access state and call non-actor methods, even after the await. As 
>> proposed that would be unsafe, and since the queue is an implementation 
>> detail inaccessible to your code there wouldn’t be a straightforward way to 
>> get back on the right queue to make it safe. I presume you could call 
>> another actor method to get back on the right queue, but having to do that 
>> explicitly after every await in an actor method seems tedious and error 
>> prone.
>> 
>> In order to have strong safety guarantees for actors you would want to 
>> ensure that all the code that has access to the state runs on the actor’s 
>> queue. There are currently two holes I can think of that would prevent us 
>> from having that protection: await and escaping blocks. await could be made 
>> safe if it were changed to return to the calling queue. Maybe escaping 
>> blocks could be restricted to only calling actor methods.
> 
> 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

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


Re: [swift-evolution] (core library) modern URL types

2017-08-24 Thread Jean-Daniel via swift-evolution
Yes, and a URI class that don’t provide any FS operations, but only take care 
of proper URI parsing and building.

> Le 23 août 2017 à 12:03, Jakob Egger via swift-evolution 
>  a écrit :
> 
> I would absolutely love to see an API like AbsolutePath / RelativePath for 
> file system operations!
> 
>> On 22. Aug 2017, at 21:02, Dave DeLong via swift-evolution 
>> > wrote:
>> 
>> I suppose, if you squint at it weirdly.
>> 
>> My current Path API is a “Path” protocol, with “AbsolutePath” and 
>> “RelativePath” struct versions. The protocol defines a path to be an array 
>> of path components. The only real difference between an AbsolutePath and a 
>> RelativePath is that all file system operations would only take an 
>> AbsolutePath. A URL would also only provide an AbsolutePath as its “path” 
>> bit.
>> 
>> public enum PathComponent {
>> case this // “."
>> case up   // “..” 
>> case item(name: String, extension: String?)
>> }
>> 
>> public protocol Path {   
>> var components: Array { get }
>> init(_ components: Array) // used on protocol extensions 
>> that mutate paths, such as appending components
>> }
>> 
>> public struct AbsolutePath: Path { }
>> public struct RelativePath: Path { }
>> 
>> By separating out the concept of an Absolute and a Relative path, I can put 
>> additional functionality on each one to make semantic sense (you cannot 
>> concatenate two absolute paths, but you can concat any path with a relative 
>> path, for example). Or all file system operations must take an AbsolutePath. 
>> 
>> One of the key things I realized is that a “Path” type should not be 
>> ExpressibleByStringLiteral, because you cannot statically determine if a 
>> Path should be absolute or relative. However, one of the initializers for an 
>> AbsolutePath would handle things like expanding a tilde, and both types try 
>> to reduce a set of components as much as possible (by filtering out “.this” 
>> components, and handling “.up” components where possible, etc). Also in my 
>> experience, it’s fairly rare to want to deal with a known-at-compile-time, 
>> hard-coded path. Usually you’re dealing with paths relative to known 
>> “containers” that are determined at runtime (current user’s home folder, 
>> app’s sandboxed documents directory, etc).
>> 
>> Another thing I’ve done is that no direct file system operations exist on 
>> AbsolutePath (like “.exists” or “.createDirectory(…)” or whatever); those 
>> are still on FileManager/FileHandle/etc in the form of extensions to handle 
>> the new types. In my app, a path is just a path, and it only has meaning 
>> based on the thing that is using it. An AbsolutePath for a URL is used 
>> differently than an AbsolutePath on a file system, although they are 
>> represented with the same “AbsolutePath” type.
>> 
>> I’m not saying this is a perfect API of course, or even that a hypothetical 
>> stdlib-provided Path should mimic this. I’m just saying that for my 
>> use-case, this has vastly simplified how I deal with paths, because both URL 
>> and String smell really bad for what I’m doing.
>> 
>> Dave
>> 
>>> On Aug 22, 2017, at 12:37 PM, Taylor Swift >> > wrote:
>>> 
>>> So are you saying we need three distinct “URI” types for local-absolute, 
>>> local-relative, and remote? That’s a lot of API surface to support.
>>> 
>>> On Tue, Aug 22, 2017 at 12:24 PM, Dave DeLong >> > wrote:
>>> I completely agree. URL packs a lot of punch, but IMO it’s the wrong 
>>> abstraction for file system paths.
>>> 
>>> I maintain an app that deals a lot with file system paths, and using URL 
>>> has always felt cumbersome, but String is the absolute wrong type to use. 
>>> Lately as I’ve been working on it, I’ve been experimenting with a concrete 
>>> “Path” type, similar to PathKit (https://github.com/kylef/PathKit/ 
>>> ). Working in terms of AbsolutePath and 
>>> RelativePath (what I’ve been calling things) has been extremely refreshing, 
>>> because it allows me to better articulate the kind of data I’m dealing 
>>> with. URL doesn’t handle pure-relative paths very well, and it’s always a 
>>> bit of a mystery how resilient I need to be about checking .isFileURL or 
>>> whatever. All the extra properties (port, user, password, host) feel hugely 
>>> unnecessary as well.
>>> 
>>> Dave
>>> 
 On Aug 20, 2017, at 11:23 PM, Félix Cloutier via swift-evolution 
 > wrote:
 
 I'm not convinced that URLs are the appropriate abstraction for a file 
 system path. For the record, I'm not a fan of existing Foundation methods 
 that create objects from an URL. There is a useful and fundamental 
 difference between a local path and a remote path, and conflating the two 
 has 

Re: [swift-evolution] New async keyword usage

2017-08-24 Thread Wallacy via swift-evolution
Interesting, its syntax seems to improve the "fire and forget" issue.

@IBAction func buttonClicked() {
async downloadAndUpdateImageView()
}


In this case, the return Future also does not need to be produced as
one of the compiler optimization.

Also,

func someAsyncFunc() async -> User {
var userData = async downloadUserData() // userData is of type
Future as we used async   var image = async downloadImage() //
Equivalentely, image is of type Future return await
User(userData, image) // Await is somehow "unwarping" the futures back
into UserData and UIImage}


Makes sense to me, its pretty clear that downloadUserData and downloadImage can
be run in parallel, and the "sync point" is the only point when you need
the actual value.

What made me curious about this pattern is to do something like that:

func getUser() async -> User {
var userData = async downloadUserData() var image = async
downloadImage() return async User(userData, image)}func
SomethingUsingUser() -> Void {
var user = await getUser() //Only here  printf(user.age > 21 ? "Let's
Drink" : "See you later!")
}// ORfunc Something2UsingUser() -> Void {
var user = async getUser()
var ageToDrink = getDrinkAge(); printf(user.get().age > ageToDrink ?
"Let's Drink" : "See you later!")
}// ORfunc Something2UsingUser() -> Void {
var user = async getUser()
var ageToDrink = async getDrinkAge();
printf(await user.age > ageToDrink ? "Lets Drink" : "See you
latter!") // i dont know if this make sense}// OR maybe continue the
processfunc CanDrink() -> async bool {
var user = async getUser()
return async ()=>{ user.get().age > 21 }  // Or other way to pass a
future computation.}

But the bast part is enable this:

func CanDrink() -> bool {
var user = async getUser()
var isOpenToDrink = barIsOpen()
return isOpenToDrink ? (user.get().age > 21) : false // if bar is not
open, we dont need to evaluate user, and the task can be suspended
somehow.}




Em qui, 24 de ago de 2017 às 08:40, Trevör ANNE DENISE via swift-evolution <
swift-evolution@swift.org> escreveu:

> 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] [Concurrency] Async/Await

2017-08-24 Thread BJ Homer via swift-evolution
Your processImageData1() function is not asynchronous, and does not need to 
return a future, because the “.get” calls are blocking; as you have implemented 
them, they will wait until they have a response or timeout. As a result, by the 
time you reach the return imageResult line, you have already waited for that 
data (or timed out), with the current thread blocked. There is no work left to 
do in the Future.

The point of async/await is that we can wait for the completion of those items 
asynchronously, not blocking the current thread. The control would return to 
the calling function before all the data was fetched.

-BJ

> On Aug 23, 2017, at 7:35 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Hi All,
> 
> Really glad that concurrency is on the table for Swift 5.
> 
> I am not sure if async/await are worth adding, as is, to Swift because it is 
> just as easy to do with a library function - in the spirit of Swift 5, see 
> `Future` library code below that you can play with and run.
> 
> If a `Future` class was added and the compiler translated 
> 'completion-handler' code to 'future' code then the running example given in 
> the whitepaper would become (also see the example in the code below):
> 
> func loadWebResource(_ path: String) -> Future { ... }
> func decodeImage(_ dataResource: Resource, _ imageResource: Resource) -> 
> Future { ... }
> func dewarpAndCleanupImage(_ image: Image) -> Future { ... }
> 
> func processImageData1() -> Future {
> let dataResource  = loadWebResource("dataprofile.txt") // dataResource 
> and imageResource run in parallel.
> let imageResource = loadWebResource("imagedata.dat")
> let imageTmp  = decodeImage(dataResource.get ?? Resource(path: 
> "Default data resource or prompt user"), imageResource.get ?? Resource(path: 
> "Default image resource or prompt user"))
> let imageResult   =  dewarpAndCleanupImage(imageTmp.get ?? 
> Image(dataPath: "Default image or prompt user", imagePath: "Default image or 
> prompt user"))
> return imageResult
> }
>  
> Which I would argue is actually better than the proposed async/await code 
> because:
> The code is naturally parallel, in example dataResource and imageResource are 
> calculated in parallel. 
> The code handles errors and deadlocks by providing a default value using `??`.
> The code can be deadlock free or can help find deadlocks, see code below, due 
> to having a timeout and a means of cancelling.
> The programmer who writes the creator of the `Future` controls which queue 
> the future executes on, I would contend that this is the best choice since 
> the programmer knows what limitations are in the code and can change queue if 
> the code changes in later versions. This is the same argument as 
> encapsulation, which gives more control to the writer of a struct/class and 
> less control to the user of the struct/class.
> In summary, I don't think async/await carries its weight (pun intended), as 
> it stands, compared to a library.
> 
> But definitely for more Swift concurrency,
> 
>  -- Howard.
> 
> PS A memory model and atomic that also guaranteed volatile would really help 
> with parallel programming!
> 
> …(snip)...
> ___
> 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] [Planning][Request] "constexpr" for Swift 5

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

on Mon Jul 31 2017, John McCall  wrote:

>> I see your point. Dynamically-sized in-place allocation is something
>> that completely escaped me when I was thinking of fixed-size
>> arrays. I can say with confidence that a large portion of
>> private-class-copy-on-write value types would greatly benefit from
>> this and would finally be able to become true value types.
>
> To be clear, it's not obvious that using an inline array is always a
> good move for performance!  But it would be a tool available for use
> when people felt it was important.

Just to point out that people may be missing the case of fixed capacity
variable sized arrays, which are an important component of a general
system for optimizing variably-sized data structures. Implementing such
an array without dynamic allocation requires language support.

Cheers,

-- 
-Dave

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


[swift-evolution] New async keyword usage

2017-08-24 Thread Trevör ANNE DENISE via swift-evolution
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] Async vs Actor

2017-08-24 Thread Benjamin Garrigues via swift-evolution
Hi, not a compiler developer in any way, but i recently had the opportunity
to experiment with this pattern in go (thanks to
https://www.youtube.com/watch?v=yCbon_9yGVs).

It seems by reading the threads that the idea of mixing actor with async,
or actor with callbacks raises a lot of question related to the order in
which the instructions should be called.
Since actor seems to me like a way to reduce threading complexity (so it
should be a "no brainer" as to what to was in which order), and are cheap,
wouldn't a "solution' to simply say :

"execute an async call from an actor is done by spawning another actor,
sending the request to it, having it execute the request in a blocking
manner (but in its own thread/coroutine) then wait for his response message
as a regular call from actor to actor" ?

Now maybe one could say that "async" is just a shortcut for doing all this.
But i thought this was a simple way to think about it.

Just to my 2 cents.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] Improving KeyPath

2017-08-24 Thread Logan Shire via swift-evolution
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!


Thanks,
Logan


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