Re: [swift-evolution] [Draft] Guarded closures and `@guarded` arguments

2017-02-20 Thread Florent Bruneau via swift-evolution


> Le 20 févr. 2017 à 06:35, Brent Royal-Gordon via swift-evolution 
>  a écrit :
> 
>> On Feb 19, 2017, at 2:57 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> A guarded closure may be created by prefixing a bound instance method 
>> reference with the `?` sigil:
>> 
>> ```swift
>> let guarded = ?myObject.myMethod
>> 
>> // desugars to:
>> let guarded = { [weak myObject] in
>> guard let myObejct = myObject else {
>>   return
>> }
>> myObject.myMethod()
>> }
>> ```
> 
> I like this in principle, but I don't like the syntax. The `?` is cryptic and 
> looks pretty strange in prefix position. I think what I'd like to see is:
> 
>   let guarded = weak myObject.myMethod

I like the idea of weak closures even if this may conflict with the fact 
closures are already internally refcounted object. While we cannot have weak 
references to closure in the language, using `weak` might be misleading in some 
ways.

In term of syntax, the `weak` keyword looks nice (much better than the '?' and 
@guarded once). The weak could be used on both sides.

```swift
addAction(action: weak Action)
addAction(action: weak myAction)
```

However, I think this might still look weird with inlined closures, in 
particular in case you use the suffix syntax for closures:

```swift
addAction() weak {
/* */
}
```
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Manifesto] Ownership

2017-02-20 Thread Florent Bruneau via swift-evolution

> Le 20 févr. 2017 à 18:22, John McCall  a écrit :
> 
>> 
>> On Feb 20, 2017, at 3:40 AM, Florent Bruneau  
>> wrote:
>> 
>> Hi John,
>> 
>> I've spent 3 hours reading the manifesto and its really very interesting. 
>> Despite the completeness of the included discussion, I have a few 
>> comments/concerns.
>> 
>> 
>> The first one is about the use a Copyable protocol whose conformance must be 
>> explicit in the module of the definition of the type. Since copyability 
>> shouldn't be modified outside the module that define a type, using a 
>> protocol seems a bit weird since AFAIK no other protocol has this kind of 
>> constraints. I do understand this enables some idiomatic constructs (like 
>> you example where Array conforms to Copyable whenever its elements are 
>> copyable), but on the other hand this looks a bit confusing to me. I don't 
>> have a better solution, thought.
> 
> On the one hand, I agree that it's not quite a normal protocol.  On the other 
> hand... it's a capability of a type, which is the sort of thing we normally 
> express with a protocol.  And because it's not just a single bit — because a 
> generic type can conditionally have that capability — if we made it not a 
> protocol, we'd just have to re-invent a new mechanism to declare that, which 
> would effectively be exactly like the protocol mechanism.
> 
> I think it's much simpler to say that certain protocols are "policy" 
> protocols which are solely up to the author of the type to decide, and that 
> external, "retroactive" conformance is only allowed for non-policy protocols.

OK. You got me convinced this is probably the most consistent approach. Do you 
envision any other policy protocol?

>> Secondly, in your discussion about variable independence, you talk about 
>> logical dependence: variables that are part of the same container. However, 
>> whenever this is some concurrency involved, there is also some kind of 
>> physical dependence. If you have two values stored physically in memory in 
>> the same cache line, and you may want to modify both independently and 
>> concurrently (one thread modifies the first value, the second modifies the 
>> other one), you have some false sharing which impacts the performance since 
>> the actual writes get sequentialized at CPU level. Is there any plan to take 
>> this kind of dependencies into account?
> 
> Well, for one, CPUs may get cleverer here over time.  So I would be 
> uncomfortable with cementing this too much in the language.

I don't think this will dramatically improve over time. Moreover, 
spatial/physical dependencies may not be specific to cache lines. Another 
example would be two boolean packed into two bits. Those variables are not 
independent because writing into one of them requires loading and writing both 
of them (unless you exclusively use atomic operations).

> The bigger issue is that we don't have a mechanism for positively declaring 
> that two variables will be accessed from different threads.  It would be 
> disastrous to over-interpret the *possibility* of concurrent access on 
> different class properties as a statement of *probability* of concurrent 
> access — because the only option there would be, what, to put each property 
> on its own cache line?  And cache line sizes change, so this is not 
> statically knowable.

This indeed wouldn't be statically checkable, but this could be (maybe as an 
opt-in?) dynamically checked.

> I think it's fine for us to design the implementation around the idea that 
> it's not necessarily a good idea to access different properties concurrently 
> — that's true semantically, not just for performance, because obviously that 
> kind of concurrent access to a class takes a lot more care and attention to 
> get right — and leave it up to the programmer to respond.
> 
> Allowing some sort of intelligent layout to prevent cache-line collisions 
> would certainly be a secondary goal of a concurrency design, though.

OK

> 
>> Thirdly, I'm a bit worried about the runtime impact of the dynamic 
>> enforcement of the law of exclusivity. It seems to me that in many use cases 
>> we will fall back to the dynamic enforcement because of the language is too 
>> dynamic to allow static enforcement. As discussed in the manifesto, it's not 
>> desirable (not doable) to put the full concept of ownership and lifetime in 
>> the type system. However, I cannot see how interaction between objects will 
>> work in the current approach. Let suppose I have a concurrent application 
>> that have a shared ressource that can be used by various workers. Workers 
>> can be either structures/classes or closures.
>> 
>> ```swift
>> struct Ressource {
>>/* content is unimportant here */
>> }
>> 
>> class Worker {
>>shared ressource: Ressource
>> 
>>init(ressource: shared Ressource) {
>>self.ressource = ressource
>>}
>> 
>>/* ... */
>> }
>> 
>> let ressource = Ressource()
>> 
>> for i in 0..<10 {
>>   let worker 

Re: [swift-evolution] [Manifesto] Ownership

2017-02-20 Thread Florent Bruneau via swift-evolution

> Le 20 févr. 2017 à 23:16, John McCall  a écrit :
> 
> 
>> On Feb 20, 2017, at 4:55 PM, Florent Bruneau  
>> wrote:
>> 
>> 
>>> Le 20 févr. 2017 à 18:22, John McCall  a écrit :
>>> 
 
 On Feb 20, 2017, at 3:40 AM, Florent Bruneau 
  wrote:
 
 Hi John,
 
 I've spent 3 hours reading the manifesto and its really very interesting. 
 Despite the completeness of the included discussion, I have a few 
 comments/concerns.
 
 
 The first one is about the use a Copyable protocol whose conformance must 
 be explicit in the module of the definition of the type. Since copyability 
 shouldn't be modified outside the module that define a type, using a 
 protocol seems a bit weird since AFAIK no other protocol has this kind of 
 constraints. I do understand this enables some idiomatic constructs (like 
 you example where Array conforms to Copyable whenever its elements are 
 copyable), but on the other hand this looks a bit confusing to me. I don't 
 have a better solution, thought.
>>> 
>>> On the one hand, I agree that it's not quite a normal protocol.  On the 
>>> other hand... it's a capability of a type, which is the sort of thing we 
>>> normally express with a protocol.  And because it's not just a single bit — 
>>> because a generic type can conditionally have that capability — if we made 
>>> it not a protocol, we'd just have to re-invent a new mechanism to declare 
>>> that, which would effectively be exactly like the protocol mechanism.
>>> 
>>> I think it's much simpler to say that certain protocols are "policy" 
>>> protocols which are solely up to the author of the type to decide, and that 
>>> external, "retroactive" conformance is only allowed for non-policy 
>>> protocols.
>> 
>> OK. You got me convinced this is probably the most consistent approach. Do 
>> you envision any other policy protocol?
> 
> Not right away, but it's possible that eventually we might want equivalents 
> to some of the other magic protocols in Rust, like Send (which IIRC promises 
> that shared references are thread-safe; that's a similar sort of fundamental 
> property).
> 
 Secondly, in your discussion about variable independence, you talk about 
 logical dependence: variables that are part of the same container. 
 However, whenever this is some concurrency involved, there is also some 
 kind of physical dependence. If you have two values stored physically in 
 memory in the same cache line, and you may want to modify both 
 independently and concurrently (one thread modifies the first value, the 
 second modifies the other one), you have some false sharing which impacts 
 the performance since the actual writes get sequentialized at CPU level. 
 Is there any plan to take this kind of dependencies into account?
>>> 
>>> Well, for one, CPUs may get cleverer here over time.  So I would be 
>>> uncomfortable with cementing this too much in the language.
>> 
>> I don't think this will dramatically improve over time. Moreover, 
>> spatial/physical dependencies may not be specific to cache lines. Another 
>> example would be two boolean packed into two bits. Those variables are not 
>> independent because writing into one of them requires loading and writing 
>> both of them (unless you exclusively use atomic operations).
> 
> Correct.  This design doesn't *completely* give up on allowing bit-packing in 
> classes, but it does make it much harder.  That was considered. :)
> 
>>> The bigger issue is that we don't have a mechanism for positively declaring 
>>> that two variables will be accessed from different threads.  It would be 
>>> disastrous to over-interpret the *possibility* of concurrent access on 
>>> different class properties as a statement of *probability* of concurrent 
>>> access — because the only option there would be, what, to put each property 
>>> on its own cache line?  And cache line sizes change, so this is not 
>>> statically knowable.
>> 
>> This indeed wouldn't be statically checkable, but this could be (maybe as an 
>> opt-in?) dynamically checked.
> 
> Yes, we could certainly do layout dynamically based on the actual cache-line 
> size.  But I hope we can agree that putting every class property on its own 
> cache line by default is not actually acceptable. :)

Putting every value in its own cache line would clearly be a disaster.

>>> I think it's fine for us to design the implementation around the idea that 
>>> it's not necessarily a good idea to access different properties 
>>> concurrently — that's true semantically, not just for performance, because 
>>> obviously that kind of concurrent access to a class takes a lot more care 
>>> and attention to get right — and leave it up to the programmer to respond.
>>> 
>>> Allowing some sort of intelligent layout to prevent cache-line collisions 
>>> would certainly be a secondary goal of a concurrency design, though.
>> 
>> OK
>> 
>>> 
 Thirdly,

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0176: Enforce Exclusive Access to Memory

2017-05-03 Thread Florent Bruneau via swift-evolution
> • What is your evaluation of the proposal?

+1. However, it's unclear to me what the dynamic enforcement will look like: 
will it trap, emit a warning, be catchable in a debugger, ... More details on 
the developer-facing interface of the dynamic enforcement would be nice.

> • Is the problem being addressed significant enough to warrant a change to 
> Swift?

The problem is significant, however I can see two significant downsides. The 
first is the source-breaking nature of the proposal. Breaking source is a 
problem by itself, but here I'm afraid the errors reporting won't be easily 
understandable, because "exclusivity" is kind of an advanced feature that won't 
be easily grasped by developers.

My second concern is the performance of the dynamic enforcement. How confident 
are you that the performance hit of the enforcement will not nullify the gain 
made by the enabling of more compile-time optimisations?

> • Does this proposal fit well with the feel and direction of Swift?

Yes.

> • If you have used other languages or libraries with a similar feature, how 
> do you feel that this proposal compares to those?
> • How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?

Full read. BTW, there is a typo in the "Eliminating non-instantaneous 
accesses?" section, _Int_appendABunchOfStuff => _Array_appendABunchOfStuff

> More information about the Swift evolution process is available at:
> 
> https://github.com/apple/swift-evolution/blob/master/process.md
> 
> 
> Thanks,
> Ben Cohen
> Review Manager
> 
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce

-- 
Florent Bruneau

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0176: Enforce Exclusive Access to Memory

2017-05-03 Thread Florent Bruneau via swift-evolution

> Le 3 mai 2017 à 17:23, John McCall  a écrit :
> 
>> On May 3, 2017, at 3:42 AM, Florent Bruneau via swift-evolution 
>>  wrote:
>>> • What is your evaluation of the proposal?
>> 
>> +1. However, it's unclear to me what the dynamic enforcement will look like: 
>> will it trap, emit a warning, be catchable in a debugger, ... More details 
>> on the developer-facing interface of the dynamic enforcement would be nice.
> 
> It will trap.  That trap will of course be caught in the debugger, and 
> hopefully the debugger will be able to deliver a nice debugging experience 
> here.
> 
>>> • Is the problem being addressed significant enough to warrant a change to 
>>> Swift?
>> 
>> The problem is significant, however I can see two significant downsides. The 
>> first is the source-breaking nature of the proposal. Breaking source is a 
>> problem by itself, but here I'm afraid the errors reporting won't be easily 
>> understandable, because "exclusivity" is kind of an advanced feature that 
>> won't be easily grasped by developers.
> 
> Our hope is that this will trigger very rarely and that we can make sure that 
> there's suitable documentation for what it means.

I'm worrying this may trigger more often on beginners' code because beginners 
will experiment and write incorrect code more often than experimented dev who 
have learned idiomatic code patterns.

>> My second concern is the performance of the dynamic enforcement. How 
>> confident are you that the performance hit of the enforcement will not 
>> nullify the gain made by the enabling of more compile-time optimisations?
> 
> It's a performance trade-off where, unfortunately, the upsides and downsides 
> will be seen in very different code.  Dynamic enforcement will kick in mostly 
> for code that makes heavy use of mutable class properties, e.g. traditional 
> Cocoa programming.  We expect that the optimization advantages will mostly be 
> seen in code that makes heavy use of value types, especially copy-on-write 
> value types like the standard library's data structures.  Of course, 
> traditional Cocoa programming also does use a lot of dictionaries and arrays, 
> so it's possible that the advantages will offset each other.
> 
> One direction we're exploring for dynamic enforcement is enabling it only in 
> certain builds by default (e.g. debug configurations).  Unlike array bounds 
> checks and integer overflows, exclusivity violations are generally not 
> data-dependent:  it's usually true that just executing the code in any 
> configuration will adequately test for dynamic exclusivity violations.  You 
> can get them with races, of course, but the dynamic enforcement mechanisms 
> we're looking at will probably not detect cross-thread violations anyway.  Of 
> course, you can make a reasonable argument that not enabling dynamic 
> enforcement checks in production builds would contradict Swift's general 
> policy of "safe by default", so this is not a certain thing.  We would very 
> much like to hear swift-evolution's thoughts about this.

I would go for disabling the dynamic checks in productions. The rational is 
mostly the little gain compared to the performance overhead.

>>> • Does this proposal fit well with the feel and direction of Swift?
>> 
>> Yes.
>> 
>>> • If you have used other languages or libraries with a similar feature, how 
>>> do you feel that this proposal compares to those?
>>> • How much effort did you put into your review? A glance, a quick reading, 
>>> or an in-depth study?
>> 
>> Full read. BTW, there is a typo in the "Eliminating non-instantaneous 
>> accesses?" section, _Int_appendABunchOfStuff => _Array_appendABunchOfStuff
> 
> Thank you, this has been fixed.
> 
> John.
> 
>> 
>>> More information about the Swift evolution process is available at:
>>> 
>>> https://github.com/apple/swift-evolution/blob/master/process.md
>>> 
>>> 
>>> Thanks,
>>> Ben Cohen
>>> Review Manager
>>> 
>>> ___
>>> swift-evolution-announce mailing list
>>> swift-evolution-annou...@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution-announce
>> 
>> -- 
>> Florent Bruneau
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

-- 
Florent Bruneau

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0176: Enforce Exclusive Access to Memory

2017-05-15 Thread Florent Bruneau via swift-evolution
Hi,

I may simply have missed something, but I'm not sure to understand why the 
proposal adds user-facing restrictions instead of using a fallback from static 
to dynamic enforcement in case of violation of the NRR/NPCR rules (maybe with 
an additional warning).

> Le 13 mai 2017 à 04:29, Ben Cohen  a écrit :
> 
> Hello Swift community,
> 
> The review of revisions to SE-0176: Enforce Exclusive Access to Memory begins 
> now and runs through May 17, 2017.
> 
> Most of this proposal was previously accepted.  An implementation issue has 
> been discovered with the use of dynamic enforcement on inout parameters.  The 
> proposal implementors suggest adopting a stronger rule governing the use of 
> non-escaping closures which will also allow Swift to make firm guarantees 
> about the use of static enforcement when a variable does not escape.  The 
> core team tentatively supports this new rule but believes it is a substantial 
> enough revision that it requires a separate review period.
> The proposal is available here: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md
> 
> Since this is a review of revisions only, you may find these two relevant 
> commits easier:
> https://github.com/apple/swift-evolution/commit/d61c07df2f02bee6c00528e73fbe33738288179a
> https://github.com/apple/swift-evolution/commit/5205a61f9cdca918d896269521bf89cb11e4aa12
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at:
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
> Proposal link:
> 
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md
> 
> 
> Reply text
> 
> Other replies
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   • What is your evaluation of the proposal?
>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   • Does this proposal fit well with the feel and direction of Swift?
>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> More information about the Swift evolution process is available at:
> 
> https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce

-- 
Florent Bruneau

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


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0176: Enforce Exclusive Access to Memory

2017-05-15 Thread Florent Bruneau via swift-evolution
> Le 15 mai 2017 à 10:55, John McCall  a écrit :
> 
>> On May 15, 2017, at 3:00 AM, Florent Bruneau via swift-evolution 
>>  wrote:
>> I may simply have missed something, but I'm not sure to understand why the 
>> proposal adds user-facing restrictions instead of using a fallback from 
>> static to dynamic enforcement in case of violation of the NRR/NPCR rules 
>> (maybe with an additional warning).
> 
> Three reasons.
> 
> The first is that it's much simpler for both users and the compiler if there 
> is a bright-line rule guaranteeing that static enforcement will be used.  A 
> programmer trying to understand "why is this slower" or "why is this problem 
> only checked at runtime" should not have to understand the language 
> implementation well enough to examine their code and e.g. deduce that the 
> problems is that they made an un-inlineable call during an access within a 
> closure and the compiler couldn't prove that that didn't lead to a re-entrant 
> access and so it fell back to dynamic enforcement.  Paring back dynamic 
> enforcement to the same cases where we need to allocate variables on the heap 
> is far more straightforward to explain and understand.
> 
> The second is closely related, which is that it preserves the ability to have 
> a subset of the language which doesn't need dynamic allocation or 
> enforcement.  This sort of performance and semantic guarantee is important in 
> a number of situations, from audio programming to low-level systems work.  
> You could imagine having a special scope, or even a compiler flag, that 
> mandates staying within that subset.  But you wouldn't want that flag to 
> change the dynamic behavior of the program or rely for correctness on an 
> assumption that the entire program, libraries included, are compiled with the 
> flag.  And that ties in with the next point.
> 
> The final reason is that, when compilers get conservative, they get very 
> conservative.  For example, we can only tell that the NPCR is being violated 
> by looking at the function that takes the closures, not the one that creates 
> them; but it's the latter function which decides what enforcement to use for 
> its captured variables.  Statically detecting NPCR violations, therefore, 
> basically requires the ability to inline every function to which we passed 
> them — we don't actually have to do the inlining, but we do have to be able 
> to see their definitions, which in many cases is not possible.  And most of 
> the heuristics you might imagine we could use to statically prove that a 
> closure can't be recursively invoked aren't actually valid.  So 
> conservatively falling back on dynamic enforcement in closures really means 
> doing it pervasively.
> 
> When you take those reasons and balance them against the patterns that are 
> being restricted here — and really, they're still legal, you just have to 
> mark one of the closures as escaping —it's not really a difficult choice.

Thanks for the details, this really helps understanding the choice you made. I 
can only +1 the proposal.

>> 
>>> Le 13 mai 2017 à 04:29, Ben Cohen  a écrit :
>>> 
>>> Hello Swift community,
>>> 
>>> The review of revisions to SE-0176: Enforce Exclusive Access to Memory 
>>> begins now and runs through May 17, 2017.
>>> 
>>> Most of this proposal was previously accepted.  An implementation issue has 
>>> been discovered with the use of dynamic enforcement on inout parameters.  
>>> The proposal implementors suggest adopting a stronger rule governing the 
>>> use of non-escaping closures which will also allow Swift to make firm 
>>> guarantees about the use of static enforcement when a variable does not 
>>> escape.  The core team tentatively supports this new rule but believes it 
>>> is a substantial enough revision that it requires a separate review period.
>>> The proposal is available here: 
>>> https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md
>>> 
>>> Since this is a review of revisions only, you may find these two relevant 
>>> commits easier:
>>> https://github.com/apple/swift-evolution/commit/d61c07df2f02bee6c00528e73fbe33738288179a
>>> https://github.com/apple/swift-evolution/commit/5205a61f9cdca918d896269521bf89cb11e4aa12
>>> 
>>> Reviews are an important part of the Swift evolution process. All reviews 
>>> should be sent to the swift-evolution mailing list at:
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> or, if you would li

Re: [swift-evolution] [Proposal] Change Void meaning

2017-06-13 Thread Florent Bruneau via swift-evolution

> Le 13 juin 2017 à 10:41, Xiaodi Wu via swift-evolution 
>  a écrit :
> 
>> On Tue, Jun 13, 2017 at 3:06 AM, John McCall  wrote:
>>> On Jun 13, 2017, at 3:30 AM, Jérémie Girault  
>>> wrote:
>>> 
>>> Exactly, 
>>> The reflexion behind it is: 
>>> 
>>> - Let's understand that 0110 and other tuple SE are important for the 
>>> compiler, we do not want them to rollback
>>> - However we have number of regressions for generics / functional 
>>> programmers
>>> - Let’s solve this step by step like a typical problem
>>> 
>>> - Step 0 is adressing this Void tuple of size zero :
>>> - Zero is in many problems of CS an edge case, so let’s handle this 
>>> case first
>>> - The compiler knows what Void is, and its only value (or non-value)
>>> - It was handled historically by the compiler because of implicit side 
>>> effects
>>> - Let’s handle it explicitely with rules in current context
>>> - one effect of the proposal is source compatibility
>>> - but the goal is to build atop and strengthen 0110, 0066 and other 
>>> tuple-related SE
>>> 
>> 
>> There are four difficulties I see with this proposal.
>> 
>> The first is that it is a first step that quite clearly does not lead to 
>> anything.  It resolves a difficulty with exactly one case of function 
>> composition, but we would need completely different solutions to handle any 
>> of the other compositional regressions of SE-0110.
>> 
>> The second is that it's a huge source of complexity for the type system.  
>> The type checker would not be able to do even rudimentary type matching, 
>> e.g. when checking a call, without having first resolved all of the argument 
>> and parameter types to prove that they are not Void.  This would probably 
>> render it impossible to type-check many programs without some ad-hoc rule of 
>> inferring that certain types are not Void.  It would certainly make 
>> type-checking vastly more expensive.
>> 
>> The third is that it is not possible to prevent values of Void from 
>> existing, because (unlike Never, which cannot be constructed) they are 
>> always created by returning from a Void-returning function, and a generic 
>> function can do anything it likes with that value — turn it into an Any, 
>> store it in an Array, whatever.  The proposal seems to only consider using 
>> the value as a parameter.
>> 
> Hang on, though. If Jérémie is interested only in addressing the issue of 
> Void as a parameter and his idea can be adequately carried out by inferring a 
> default value of Void for every parameter of type Void, this should be a 
> fairly self-contained change, should it not? And would the impact on the cost 
> of type checking really be vastly greater in that case?
> 
> This idea is now rather intriguing to me because it extends beyond just 
> addressing one symptom of SE-0110. Swift allows us to omit the spelling out 
> of return types that are Void, it allows warning-free discarding of return 
> values that are Void, etc. This could add a nice consistency and rationalize 
> some of the weirdness of passing a value that is stipulated by the parameter 
> type.
> 
>> Finally, it would allow a lot of inadvertent errors with the use of generic 
>> functions, because any argument of unconstrained type could be accidentally 
>> specialized with Void.  For example, if you forgot to pass an argument to 
>> this function, it would simply infer T=Void:
>>   func append(value: T)
>> It seems more likely that this would lead to unexpected, frustrating bugs 
>> than that this would actually be desired by the programmer.  You really just 
>> want this to kick in in more generic situations.
>> 
> Hmm, at first glance, that seemed like it could be bad. But if, say, a 
> particular collection can store an element of type Void, is it so undesirable 
> to allow `append()` to append Void?

Seems to me the language should go for safety before convenience here. In 
John's example you are dealing with a generic function, not a generic type and 
having append() being silently resolve to append(value: Void) could 
clearly cause bug with the wrong append() function being called in some cases 
(because you may mean `append()` from a parent scope instead of `append(value: 
Void)` from the current scope)

In the case of a collection, or any generic type, you can simply provide an 
`extension Collection where Element == Void { }` that overloads you append() 
function with a no-param version.

>> 
>> —
>> very short reply expected - vsre.info
>> Jérémie Girault
>> 
>> On 13 juin 2017 at 00:44:52, Xiaodi Wu (xiaodi...@gmail.com) wrote:
>> 
>>> On Mon, Jun 12, 2017 at 5:38 PM, Xiaodi Wu  wrote:
>>> On Mon, Jun 12, 2017 at 5:25 PM, Jérémie Girault 
>>>  wrote:
>>> 
>>> 
>>> —
>>> very short reply expected - vsre.info
>>> Jérémie Girault
>>> 
>>> On 12 juin 2017 at 23:56:37, Xiaodi Wu (xiaodi...@gmail.com) wrote:
>>> 
 On Mon, Jun 12, 2017 at 4:47 PM, Jérémie Girault 
  wrote:
 - Void as arguments is pretty common whe

Re: [swift-evolution] Reduce with inout

2017-01-24 Thread Florent Bruneau via swift-evolution
Hi,

Looks like there is a typo in the proposal:

func reduce(mutating: A, _ combine: (inout A, Iterator.Element) -> ()) 
-> A {
var result = initial

This makes use of `initial` that is not defined, should be:

func reduce(mutating initial: A, _ combine: (inout A, Iterator.Element) 
-> ()) -> A {
var result = initial

> Le 24 janv. 2017 à 08:54, Chris Eidhof via swift-evolution 
>  a écrit :
> 
> I've thought about it for a few days, and really like `reduce(mutating:_)`. 
> I've updated the PR, and am now happy for this to go into review.
> 
> https://github.com/apple/swift-evolution/pull/587
> 
> On Mon, Jan 23, 2017 at 8:27 AM, Russ Bishop  wrote:
> 
>> On Jan 22, 2017, at 10:56 PM, Chris Eidhof  wrote:
>> 
>> Not as a direct reply to Russ, but just to reiterate: to me, there are two 
>> clear benefits of using the `inout` version of reduce:
>> 
>> 1. The performance (currently discussed at length)
>> 2. Readability (because we can use mutating methods on `inout` arguments).
>> 
>> Even if the compiler were to optimize the unnecessary copy of `return arr + 
>> [el]` away, there are still a lot of other mutable methods that you might 
>> want to use within the reduce closure. So I think the proposal is still very 
>> valid even if the compiler optimizations would magically appear tomorrow.
>> 
>> To push this proposal forward a little bit, I'd like to come up with a good 
>> name. It seems like we shouldn't overload `reduce`, but choose a different 
>> name, so that we don't stress the typechecker. Any other suggestions?
>> 
>> On Mon, Jan 23, 2017 at 7:11 AM, Russ Bishop  wrote:
>> -- 
>> Chris Eidhof
> 
> 
> Sorry for the derail!
> 
> reduce(mutating:_:) { } is still my favorite; You can take mutating to mean 
> we will copy the value now but mutate it later.
> 
> 
> Some alternatives:
> 
> reduce(forMutating:_:) { }
> 
> reduce(forInout:_:) { }
> 
> reduce(initial:_:) { }
> 
> reduce(copying:mutate:) { }
> 
> // just kidding...
> reduce(copyForLaterMutating:_:) { }
> 
> 
> 
> It should definitely be some form of reduce. 
> 
> Russ
> 
> 
> 
> -- 
> Chris Eidhof
> ___
> 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] Proposal to improve C pointer type import

2017-01-31 Thread Florent Bruneau via swift-evolution
Hi swift-evolution, 

For the last few weeks, I've been working on introducing some Swift in a pure-C 
codebase. While the Clang importer makes the process quite smooth, there are 
still some rough edges.

Here is a (lengthy) proposal resulting from that experience.
Rendered version: 
https://gist.github.com/Fruneau/fa83fe87a316514797c1ee2e5012

Introduction
===

Directly importing C APIs is a core feature of the Swift compiler. In that 
process, C pointers are systematically imported as `Unsafe*Pointer` swift 
objects. However, in C we make the distinction between pointers that reference 
a single object, and those pointing to an array of objects. In the case of a 
single object of type `T`, the Swift compiler should be able to import the 
parameter `T *` as a `inout T`, and `T const *` as `T`. Since the compiler 
cannot makes the distinction between pointer types by itself, we propose to add 
an attribute of C pointer for that purpose.

Motivation
===

Let consider the following C API:

```c
typedef struct sb_t {
char * _Nonnull data;
int len;
int size;
} sb_t;

/** Append the string \p str to \p sb. */
void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);

/** Append the content of \p other to \p sb. */
void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);

/** Returns the amount of available memory of \p sb. */
int sb_avail(const sb_t * _Nonnull sb);
```

This is imported in Swift as follow:

```swift
struct sb_t {
var data: UnsafeMutablePointer
var len: Int32
var size: Int32
}

func sb_adds(_ sb: UnsafeMutablePointer, _ str: UnsafePointer)
func sb_addsb(_ sb: UnsafeMutablePointer, _ other: UnsafePointer)
func sb_avail(_ sb: UnsafePointer) -> Int32
```

`sb_adds()` takes two pointers: the first one is supposed to point to a single 
object named `sb` that will be mutated in order to add the content of `str` 
which points to a c-string. So we have two kinds of pointers: the first points 
to a single object, the second to a buffer. But both are represented using 
`Unsafe*Pointer`. Swift cannot actually make the difference between those two 
kind of pointers since the C language provides no way to express it.

`sb_addsb()` takes two objects of type `sb_t`. The first is mutated by the 
function by appending the content of the second one, which is `const`. The 
constness is properly reflected in Swift. However, the usage of the imported 
API is Swift might be surprising since Swift requires usage of an `inout` 
parameter in order to build an `Unsafe*Pointer` object:

```swift
var sb = sb_t(...)
let sb2 = sb_t(...)
sb_addsb(&sb, &sb2) // error: cannot pass immutable value as inout argument: 
'sb2' is a 'let' constant
sb_addsb(&sb, sb2) // cannot convert value of type 'sb_t' to expected argument 
type 'UnsafePointer!'

var sb3 = sb_t(...)
sb_addsb(&sb, &sb3) // works
```

```swift
sb_avail(&sb2) // cannot convert value of type 'sb_t' to expected argument type 
'UnsafePointer!'
```


However, Swift also provides the `swift_name()` attribute that allows remapping 
a C function to a Swift method, which includes mapping one of the parameter to 
`self:`:

```c 
__attribute__((swift_name("sb_t.add(self:string:)")))
void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);
__attribute__((swift_name("sb_t.add(self:other:)")))
void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);
__attribute__((swift_name("sb_t.avail(self:)")))
int sb_avail(const sb_t * _Nonnull sb);
```

```swift
struct sb_t {
var data: UnsafeMutablePointer
var len: Int32
var size: Int32

mutating func add(string: UnsafePointer)
mutating func add(other: UnsafePointer)
func avail() -> Int32
}
```

With that attribute used, there is no need to convert the parameter mapped to 
`self:` to an `Unsafe*Pointer`. As a consequence, we have an improved API:

```swift
sb2.avail() // This time it works!
```

But we also have some inconsistent behavior since only `self:` is affected by 
this:

```swift
sb.add(other: &sb2)  // error: cannot pass immutable value as inout argument: 
'sb2' is a 'let' constant
sb.add(other: sb2) // cannot convert value of type 'sb_t' to expected argument 
type 'UnsafePointer!'
```


What we observe here is that mapping an argument to `self:` is enough for the 
compiler to be able to change its semantics. As soon as it knows the pointer is 
actually the pointer to a single object, it can deal with it without exposing 
it as an `Unsafe*Pointer`, making the API safer and less surprising.


Proposed solution


A new qualifier could be added to inform the compiler that a pointer points to 
a single object. Then the Swift compiler could use that new piece of the 
information to generate API that use directly the object type instead of the 
pointer type. We propose the introduction of a new qualifier named `_Ref`, 
semantically similar to a C++ reference. That is:

* `_Ref` is applied with the same grammar as the `_Nonnull`,  `_Nullable`,

Re: [swift-evolution] Proposal to improve C pointer type import

2017-02-07 Thread Florent Bruneau via swift-evolution
Anyone interested in that subject?

> Le 31 janv. 2017 à 09:16, Florent Bruneau via swift-evolution 
>  a écrit :
> 
> Hi swift-evolution, 
> 
> For the last few weeks, I've been working on introducing some Swift in a 
> pure-C codebase. While the Clang importer makes the process quite smooth, 
> there are still some rough edges.
> 
> Here is a (lengthy) proposal resulting from that experience.
> Rendered version: 
> https://gist.github.com/Fruneau/fa83fe87a316514797c1ee2e5012
> 
> Introduction
> ===
> 
> Directly importing C APIs is a core feature of the Swift compiler. In that 
> process, C pointers are systematically imported as `Unsafe*Pointer` swift 
> objects. However, in C we make the distinction between pointers that 
> reference a single object, and those pointing to an array of objects. In the 
> case of a single object of type `T`, the Swift compiler should be able to 
> import the parameter `T *` as a `inout T`, and `T const *` as `T`. Since the 
> compiler cannot makes the distinction between pointer types by itself, we 
> propose to add an attribute of C pointer for that purpose.
> 
> Motivation
> ===
> 
> Let consider the following C API:
> 
> ```c
> typedef struct sb_t {
>char * _Nonnull data;
>int len;
>int size;
> } sb_t;
> 
> /** Append the string \p str to \p sb. */
> void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);
> 
> /** Append the content of \p other to \p sb. */
> void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);
> 
> /** Returns the amount of available memory of \p sb. */
> int sb_avail(const sb_t * _Nonnull sb);
> ```
> 
> This is imported in Swift as follow:
> 
> ```swift
> struct sb_t {
>var data: UnsafeMutablePointer
>var len: Int32
>var size: Int32
> }
> 
> func sb_adds(_ sb: UnsafeMutablePointer, _ str: UnsafePointer)
> func sb_addsb(_ sb: UnsafeMutablePointer, _ other: UnsafePointer)
> func sb_avail(_ sb: UnsafePointer) -> Int32
> ```
> 
> `sb_adds()` takes two pointers: the first one is supposed to point to a 
> single object named `sb` that will be mutated in order to add the content of 
> `str` which points to a c-string. So we have two kinds of pointers: the first 
> points to a single object, the second to a buffer. But both are represented 
> using `Unsafe*Pointer`. Swift cannot actually make the difference between 
> those two kind of pointers since the C language provides no way to express it.
> 
> `sb_addsb()` takes two objects of type `sb_t`. The first is mutated by the 
> function by appending the content of the second one, which is `const`. The 
> constness is properly reflected in Swift. However, the usage of the imported 
> API is Swift might be surprising since Swift requires usage of an `inout` 
> parameter in order to build an `Unsafe*Pointer` object:
> 
> ```swift
> var sb = sb_t(...)
> let sb2 = sb_t(...)
> sb_addsb(&sb, &sb2) // error: cannot pass immutable value as inout argument: 
> 'sb2' is a 'let' constant
> sb_addsb(&sb, sb2) // cannot convert value of type 'sb_t' to expected 
> argument type 'UnsafePointer!'
> 
> var sb3 = sb_t(...)
> sb_addsb(&sb, &sb3) // works
> ```
> 
> ```swift
> sb_avail(&sb2) // cannot convert value of type 'sb_t' to expected argument 
> type 'UnsafePointer!'
> ```
> 
> 
> However, Swift also provides the `swift_name()` attribute that allows 
> remapping a C function to a Swift method, which includes mapping one of the 
> parameter to `self:`:
> 
> ```c 
> __attribute__((swift_name("sb_t.add(self:string:)")))
> void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);
> __attribute__((swift_name("sb_t.add(self:other:)")))
> void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);
> __attribute__((swift_name("sb_t.avail(self:)")))
> int sb_avail(const sb_t * _Nonnull sb);
> ```
> 
> ```swift
> struct sb_t {
>var data: UnsafeMutablePointer
>var len: Int32
>var size: Int32
> 
>mutating func add(string: UnsafePointer)
>mutating func add(other: UnsafePointer)
>func avail() -> Int32
> }
> ```
> 
> With that attribute used, there is no need to convert the parameter mapped to 
> `self:` to an `Unsafe*Pointer`. As a consequence, we have an improved API:
> 
> ```swift
> sb2.avail() // This time it works!
> ```
> 
> But we also have some inconsistent behavior since only `self:` is affected by 
> this:
> 
> ```swift
> sb.add(other: &sb2)  // error: cannot pass immutable value as inout argument: 
> 'sb2' is a 'let&

Re: [swift-evolution] Proposal to improve C pointer type import

2017-02-07 Thread Florent Bruneau via swift-evolution
Hi Charlie,

Thanks for your answer.

> Le 7 févr. 2017 à 18:23, Charlie Monroe  a écrit :
> 
>> 
>> On Feb 7, 2017, at 5:56 PM, Florent Bruneau via swift-evolution 
>>  wrote:
>> 
>> Anyone interested in that subject?
>> 
>>> Le 31 janv. 2017 à 09:16, Florent Bruneau via swift-evolution 
>>>  a écrit :
>>> 
>>> Hi swift-evolution, 
>>> 
>>> For the last few weeks, I've been working on introducing some Swift in a 
>>> pure-C codebase. While the Clang importer makes the process quite smooth, 
>>> there are still some rough edges.
>>> 
>>> Here is a (lengthy) proposal resulting from that experience.
>>> Rendered version: 
>>> https://gist.github.com/Fruneau/fa83fe87a316514797c1ee2e5012
>>> 
>>> Introduction
>>> ===
>>> 
>>> Directly importing C APIs is a core feature of the Swift compiler. In that 
>>> process, C pointers are systematically imported as `Unsafe*Pointer` swift 
>>> objects. However, in C we make the distinction between pointers that 
>>> reference a single object, and those pointing to an array of objects. In 
>>> the case of a single object of type `T`, the Swift compiler should be able 
>>> to import the parameter `T *` as a `inout T`, and `T const *` as `T`. Since 
>>> the compiler cannot makes the distinction between pointer types by itself, 
>>> we propose to add an attribute of C pointer for that purpose.
>>> 
>>> Motivation
>>> ===
>>> 
>>> Let consider the following C API:
>>> 
>>> ```c
>>> typedef struct sb_t {
>>>  char * _Nonnull data;
>>>  int len;
>>>  int size;
>>> } sb_t;
>>> 
>>> /** Append the string \p str to \p sb. */
>>> void sb_adds(sb_t * _Nonnull sb, const char * _Nonnull str);
>>> 
>>> /** Append the content of \p other to \p sb. */
>>> void sb_addsb(sb_t * _Nonnull sb, const sb_t * _Nonnull other);
>>> 
>>> /** Returns the amount of available memory of \p sb. */
>>> int sb_avail(const sb_t * _Nonnull sb);
>>> ```
>>> 
>>> This is imported in Swift as follow:
>>> 
>>> ```swift
>>> struct sb_t {
>>>  var data: UnsafeMutablePointer
>>>  var len: Int32
>>>  var size: Int32
>>> }
>>> 
>>> func sb_adds(_ sb: UnsafeMutablePointer, _ str: UnsafePointer)
>>> func sb_addsb(_ sb: UnsafeMutablePointer, _ other: 
>>> UnsafePointer)
>>> func sb_avail(_ sb: UnsafePointer) -> Int32
>>> ```
>>> 
>>> `sb_adds()` takes two pointers: the first one is supposed to point to a 
>>> single object named `sb` that will be mutated in order to add the content 
>>> of `str` which points to a c-string. So we have two kinds of pointers: the 
>>> first points to a single object, the second to a buffer. But both are 
>>> represented using `Unsafe*Pointer`. Swift cannot actually make the 
>>> difference between those two kind of pointers since the C language provides 
>>> no way to express it.
>>> 
>>> `sb_addsb()` takes two objects of type `sb_t`. The first is mutated by the 
>>> function by appending the content of the second one, which is `const`. The 
>>> constness is properly reflected in Swift. However, the usage of the 
>>> imported API is Swift might be surprising since Swift requires usage of an 
>>> `inout` parameter in order to build an `Unsafe*Pointer` object:
>>> 
>>> ```swift
>>> var sb = sb_t(...)
>>> let sb2 = sb_t(...)
>>> sb_addsb(&sb, &sb2) // error: cannot pass immutable value as inout 
>>> argument: 'sb2' is a 'let' constant
> 
> This is because your declaration is const sb_t * _Nonnull other... See 
> http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int-const-int-const-and-int-const
> 
> Change it to "const sb_t * const _Nonnull other" and you get a non-mutable 
> pointer and you can use it with let.

Actually, no. In case of a function argument, the difference between `const 
sb_t *` and `const sb_t * const` is the same as between a `var` argument and a 
`let` argument in swift < 3: it only affects the mutability of the variable 
inside the function definition, and has no effect on the outside. When imported 
in swift, both result in the exact same function prototype.

```c
void sb_addsb(sb_t *self, const sb_t *other);
void sb_addsb2(sb_t *self, const sb_t * const other);
void sb_addsb3(sb_t * const self, const sb

Re: [swift-evolution] [Draft] @selfsafe: a new way to avoid reference cycles

2017-02-19 Thread Florent Bruneau via swift-evolution
Hi Matthew,

I'm not convinced we should come with a new mechanism that would handle the 
capture of `self` differently from the other captures. I do understand that 
this would match the way Apple APIs work, but as a general purpose language, 
this looks weird to add some asymmetry in the language itself. If we want to 
come with a solution to make memory management easier, it should be applicable 
to any captured variable of the closures, not just `self`.

Moreover, having the `@selfsafe` attribute defined on the library side seems 
dangerous to me: it imposes a custom reference counting mechanism to apply on 
the user provided closure. This means that, in case the caller code does not 
match the reference counting pattern the library writer had in mind, the caller 
might require a strong reference on `self` (but maybe a weak reference on 
another captured variable) and the library would just become unusable at this 
point.

As soon as you receive a function as argument, I cannot see any good reason 
(but there may be some I missed) to make any assumption about what that 
function (maybe except about purity): the function might be or not be a 
closure, might capture or not capture variables and among those variables, 
there may be `self` or any other ref counted object. If you start making 
assumptions about the function you received, this might mean you want to 
receive an object that match a particular protocol, in which case you control 
the reference counting you apply on the received object (I do understand you 
cannot change Apple APIs, but you can build your own extension that will 
provide the safer API that would receive the object and do the weak capture 
itself).

> Le 19 févr. 2017 à 02:24, Matthew Johnson via swift-evolution 
>  a écrit :
> 
> # `@selfsafe`: a new way to avoid reference cycles
> 
> * Proposal: [SE-](-selfsafe.md)
> * Authors: [Matthew Johnson](https://github.com/anandabits)
> * Review Manager: TBD
> * Status: **Awaiting review**
> 
> ## Introduction
> 
> This proposal introduces the `@selfsafe` function argument attribute which 
> together with a `withWeakSelf` property on values of function type.  Together 
> these features enable library authors to create APIs can be statically 
> verified to never extend the lifetime of the `self` a function they take may 
> have captured.  This is accomplished by allowing the library implementation 
> convert the function to a nearly identical function that is guaraneteed to 
> have a `weak` capture of `self` and be a no-op after `self` is released.
> 
> Swift-evolution thread: []()
> 
> ## Motivation
> 
> Accidentally forgeting to use weak references is a common problem and can 
> easily lead to reference cycles.  Some APIs are best designed such that users 
> *cannot* extend the lifetime of `self` by escaping a closure that happens to 
> strongly capture `self`.  For example, `UIControl.addTarget(_:action:for:) 
> does not retain the target, thereby preventing users from making the mistake 
> of using a closure with an accidental strong reference.  We can do something 
> similar in Swift:
> 
> ```swift
> // in the library:
> func addTarget(_ target: T, action: T -> Int -> Void) {
>   // store a weak reference to the target
>   // when the action is fired call ref.map{ action($0)(42) }
> }
> 
> // in user code:
> class C {
>   init() {
>  addTarget(self, action: C.takesInt)
>   }
> 
>   func takesInt(_ i: Int) {}
> }
> ```
> 
> Both the library and the caller have to deal with a lot of details and 
> boilerplate that we would prefer to avoid.  The natural design in Swift would 
> be to simply take an action function.  Unfortunately if we do that we run 
> into a problem:
> 
> ```swift
> // in the library
> func addAction(_ f: Int -> Void) {
>   // store a strong ref to f, which might include a strong ref to a captured 
> self
>   // later when the action is fired call f(42)
> }
> 
> // in user code
> class C {
>   init() {
>  addAction(takesInt)
>  // oops! should have been: addAction{ [weak self] self?.takesInt($0) }
>   }
> 
>   func takesInt(_ i: Int) {}
> }
> ```
> 
> Here the syntax is much nicer, but unfortunately we have unintentionally 
> extended the lifetime of `self`.  The burden of ensuring `self` is not 
> captured or captured weakly falls on users of the library.
> 
> It would very nice if it were possible to design an API that has weak capture 
> semantics while still acheiving the more concise and Swifty syntax.
> 
> ## Proposed Solution
> 
> This proposal introduces a read-only property on all function types: 
> `withWeakSelf` as well as a `@selfsafe` function argument annotation.  (This 
> name for the annotation is a strawman - I would love to hear better ideas)
> 
> ### `withWeakSelf`
> 
> `withWeakSelf` can be imagined as a property declared like the following:
> 
> ```swift
> extension T -> Void {
>  var withWeakSelf: T -> Void { return // compiler magic }
> }
> extension T -> U {
>  var withWea

Re: [swift-evolution] A concern

2017-02-19 Thread Florent Bruneau via swift-evolution
Hi,

Objective-C is a superset of C, the C11 standard is 683-pages long (OK, I'm 
talking about specification, not "user" guide). Everything that is part of C is 
part of Objective-C and might hurt the productivity of the developer at the 
worst moment: a sequence point breakage hidden in a macro, an integer overflow 
that get "optimized away", a strict aliasing breakage that produces surprising 
code... all those kinds of issues happen in real code when working with C and 
Objective-C. So, when you read the few pages of "getting started with" 
Objective-C you don't really know the language, you know the high-level 
principles.

Swift is much less surprising because of its focus not to have undefined 
behaviors: everything is well specified and just this makes the language much 
simpler to *really* master. There are some hard parts (memory management is 
still present and far from trivial. You need decades of programming to be a C / 
Objective-C expert, Swift is only 3 years old (in the wild), and I would 
suspect there is already a sensible amount of "experts" who understand the 
language.

I'm on the list since the beginning of the year, and what I see here is a list 
of proposals that tend to focus on making the language even more consistent and 
less surprising (access level consistency, better Int API, better String API, 
better enums, ...). That are rare cases where we are discussing new features of 
the language (like the ownership manifesto published at the end of the week), 
but this come to cover shortcomings of the languages (trade-offs that were made 
to have a language published earlier, but with a reduced feature set): in my 
point of view the lack of ownership, the lack of concurrency support, ... are 
shortcomings of the language that make working with Swift more surprising and 
that cause the need of "expert" developers when a full-featured consistent 
language may only require a "mid-level" programmer.

That said, whatever the language you chose, there will always be code written 
by "experts" who think it is important to write complex code to solve simple 
problems and that will not be accessible to beginners. I think having generics 
in a language is one of the key enablers of this kind of behavior: it becomes 
so easy to write meta-code. But at the same time, I will never consider 
generics bloat the language, because when well use they enable so many elegant 
use cases.

> Le 19 févr. 2017 à 10:00, Rien via swift-evolution 
>  a écrit :
> 
> Hello All,
> 
> Its Sunday, time for some reflection...
> 
> One of the big plusses of Objective-C was that the entire manual was just a 
> few pages long. I have not looked it up, but IIRC the entire manual 
> describing the language was probably less than 50 pages. Much less if you 
> subtract the filler stuff.
> 
> Now, Objective-C is -arguably- not a very ‘nice’ or aesthetically pleasing 
> language.

> Swift is a huge improvement aesthetically speaking. But at the cost of a much 
> larger user manual. Right of the bat it was clear to me that in Swift some of 
> the learning curve from the framework (Cocoa) was shifted into language 
> (Swift). I.e. Swift seemed specifically targeted to the idioms we used in 
> Objective-C/Cocoa. It was one of the reasons that I took to Swift immediately.
> 
> Now that we have Swift 3, many of the original shortcomings have been filled. 
> A few remain, but imo not very many.
> 
> That brings me to my concern: Swift seems to be on course to become a 
> behemoth of a language. 
> 
> I am absolutely convinced that everybody on this list has the best of 
> intentions. We all want the very best tool available. We want Swift to become 
> a shiny many facetted jewel among the languages.
> 
> But in doing so we might -inadvertently- make Swift into a behemoth that can 
> do everything ... if you know how!
> 
> In my opinion Swift is on course to become a very complex language where one 
> needs guru status to be a mid level programmer. Beginning programmers will 
> stand no chance whatsoever to maintain an app developed by an expert. (A bit 
> like C++, another extremely powerful language - that seems to have been 
> abandoned.)
> 
> I have been on this list now for a few weeks, and I see very little push-back 
> on new suggestions. Most of the reactions are positive-constructive. IMO we 
> need more push-back. Without it behemoth status is all but guaranteed.
> 
> I don’t know about the core team, I don’t know about Apple, I don’t know 
> where they want to go.
> 
> I just want to make a plea here: Please stop Swift from becoming a behemoth.
> 
> I don’t know if the millions (?) of Swift developers not on this list agree 
> with me. I somehow think they do, after all they are not on this list! They 
> are not looking to change Swift...
> 
> Well, I just had to get that off my chest...
> 
> To close this off, I do want to take this opportunity to thank the core team 
> for their work, I truly appreciate it!
> And wha

Re: [swift-evolution] [Manifesto] Ownership

2017-02-20 Thread Florent Bruneau via swift-evolution
Hi John,

I've spent 3 hours reading the manifesto and its really very interesting. 
Despite the completeness of the included discussion, I have a few 
comments/concerns.


The first one is about the use a Copyable protocol whose conformance must be 
explicit in the module of the definition of the type. Since copyability 
shouldn't be modified outside the module that define a type, using a protocol 
seems a bit weird since AFAIK no other protocol has this kind of constraints. I 
do understand this enables some idiomatic constructs (like you example where 
Array conforms to Copyable whenever its elements are copyable), but on the 
other hand this looks a bit confusing to me. I don't have a better solution, 
thought.



Secondly, in your discussion about variable independence, you talk about 
logical dependence: variables that are part of the same container. However, 
whenever this is some concurrency involved, there is also some kind of physical 
dependence. If you have two values stored physically in memory in the same 
cache line, and you may want to modify both independently and concurrently (one 
thread modifies the first value, the second modifies the other one), you have 
some false sharing which impacts the performance since the actual writes get 
sequentialized at CPU level. Is there any plan to take this kind of 
dependencies into account?



Thirdly, I'm a bit worried about the runtime impact of the dynamic enforcement 
of the law of exclusivity. It seems to me that in many use cases we will fall 
back to the dynamic enforcement because of the language is too dynamic to allow 
static enforcement. As discussed in the manifesto, it's not desirable (not 
doable) to put the full concept of ownership and lifetime in the type system. 
However, I cannot see how interaction between objects will work in the current 
approach. Let suppose I have a concurrent application that have a shared 
ressource that can be used by various workers. Workers can be either 
structures/classes or closures.

```swift
struct Ressource {
/* content is unimportant here */
}

class Worker {
shared ressource: Ressource

init(ressource: shared Ressource) {
self.ressource = ressource
}

/* ... */
}

let ressource = Ressource()

for i in 0..<10 {
   let worker = Worker(ressource: ressource)
   worker.schedule()
}
waitAllWorkers()
```

My understanding of the manifesto is that this kind of construct in not really 
part of it. Is there a way to enforce the workers' lifetime to be shorter than 
the lifetime of the ressource?



Finally, since I work a lot with imported C code, I'd like to know if there is 
some plan to make the ownership attributes works well with C code. I mean, you 
say that unsafe pointers just force a fall back to not enforcing the law of 
exclusivity, but in my day-to-day work, this is exactly where I need it the 
most: when I have to manipulate a structure that contain a pointer allocated by 
some C code, I cannot allow copy of that structure since that pointer may be 
reallocated and one of the copies would contain a dangling pointer. So, is 
there some way to opt-in for non-copyability of imported code?

I tried, without success, to propose some way to improve pointer-passing 
between C and Swift [1] that could help tracking ownership when interacting 
with C code.



[1] 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170130/031199.html
 

> Le 17 févr. 2017 à 09:25, John McCall via swift-evolution 
>  a écrit :
> 
> Hello, swift-evolution.
> 
> Memory ownership is a topic that keeps poking its head up here.  Core team
> members have mentioned several times that it's something we're interested in
> working on.  Questions sometimes get referred back to it, saying stuff like
> "we're working on tools to let you control ARC a little better".  It's even 
> on the
> short list of high-priority features for Swift 4:
> 
>   https://github.com/apple/swift-evolution
> 
>   Memory ownership model: an (opt-in) Cyclone/Rust-inspired memory
>   ownership model is highly desired by systems programmers and for other
>   high-performance applications that want predictable and deterministic
>   performance. This feature will fundamentally shape the ABI, from low-level
>   language concerns such as "inout" and low-level "addressors" to its impact
>   on the standard library. While a full memory ownership model is likely too
>   large for Swift 4 stage 1, we need a comprehensive design to understand
>   how it will change the ABI.
> 
> But that's all pretty vague.  What is ownership?  What does it mean for
> programmers?  Is somebody ever going to actually write that comprehensive
> design that was supposed to come out during Stage 1?
> 
> Well, here you go.
> 
> I want to emphasize that this document is two things.  It is a *manifesto*,
> because it describes the whole problem and presents a holistic solution to it.
> And it is a *meta-proposal*, because that holistic solution im