Re: [swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread John McCall via swift-evolution
> On Jan 12, 2018, at 6:47 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> I feel like we’re talking past each other right now, so I’ll give a concrete 
> example:
> 
> Let’s say MyAwesomeFramework.framework defines this enum:
> 
> enum Access {
>   case none
>   case readOnly
>   case readWrite
> }
> 
> This framework is compiled, built, and embedded in to 
> MyAwesomeApp.app/Frameworks.
> 
> Somewhere in MyAwesomeApp, I switch on the access of a thing:
> 
> switch aThing.access {
>   case .none: break
>   case .readOnly: print(“I can read”)
>   case .readWrite: print(“I can write”)
> }
> 
> Let’s here observe some things:
> 
> 1️⃣ the enum “Access” is *not* declared as frozen, because it might get a new 
> case in the future (such as “writeOnly”)
> 2️⃣ the switch on an Access value is exhaustive
> 3️⃣ under the proposal, I’m going to get a warning on the switch because 
> Access is not frozen. That warning will tell me to add “unknown case:”
> 
> This is the problem I’m talking about. The warning I’ll get on the switch is 
> technically correct (I’m switching on a non-frozen enum), but semantically 
> incorrect (it’s ok because the framework CANNOT introduce a new case without 
> recompilation of the switch statement, because they are packaged together). 
> The compiler will tell me to add an unknown case statement to the switch when 
> it will be completely unnecessary. Since MyAwesomeFramework.framework is 
> embedded in my app, there is no binary compatibility concern here, and I will 
> never come across an unknown case.
> 
> I think this false positive is going to be very common, because lots of 
> people embed frameworks in their apps, and those frameworks declare enums. 
> Until the frameworks are updated to freeze the enums, the app authors will be 
> forced to add “unknown case” statements to their switches for places where it 
> is entirely unnecessary. (This brings up the question: does this proposal 
> include a fixit to remove an “unknown case” statement from switches where 
> it’s unnecessary?)
> 
> So, what I’m asking for is a part in the proposal (likely under “Future 
> Directions”) where you acknowledge this problem (the “false positive problem 
> for embedded modules”) and list it as something we’d like to solve in the 
> future.

I agree that it's important to discuss this in the proposal.

I think the point that Jordan is trying to make is that this kind of resilience 
problem can come up as a source-compatibility issue, not just a 
binary-compatibility issue.  Of course an app can be version-locked to its 
non-OS dependencies and nobody will care.  However, it's problematic for a 
library to be version-locked to its dependencies even if both the library and 
its dependencies are only ever distributed as source: you ought to be able to 
upgrade the dependencies without having to revise all the dependent libraries.  
If our library ecosystem doesn't let you pull a new version of BaseLib without 
simultaneously pulling new versions of everything else you use that requires 
BaseLib — or, alternatively, hand-fixing them all yourself if that library 
hasn't gotten updated yet — that's a pretty frustrating experience.

Conversely, an app ought to be able to be version-locked to its non-OS 
dependencies whether they're binaries or source.  So this really has almost 
nothing to do with binary vs. source distribution and everything to do with 
whether version-locking makes sense for a specific project.

John.

> 
> Dave
> 
>> On Jan 12, 2018, at 4:27 PM, Dave DeLong via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jan 12, 2018, at 4:22 PM, Jordan Rose >> > wrote:
>>> 
>>> No, it's "Revision-locked imports”.
>> 
>> Ah, yeah I can see how the rev-locked imports is a variation on “I’ve copied 
>> in this library”.
>> 
>>> A source-breaking change is one in which updating the library at compile 
>>> time will break clients at compile time. That's relevant for libraries 
>>> distributed with an app as well as for libraries that are part of the OS. 
>>> You may not care, but I do, and I think other package authors will too.
>> 
>> ??? Of course I care about getting warnings when I’ve chosen to update a 
>> dependency. Where did I ever imply otherwise?
>> 
>> What I’m saying is that if I’m embedding such a library in my app *now* and 
>> I’m importing it *now*, I shouldn’t get a warning about handling unknown 
>> cases off non-frozen enums *now*. 
>> 
>> And if I am going to see such warnings now, then the document needs to 
>> include how those “false positives” will be eliminated in the future.
>> 
>> Dave
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swi

Re: [swift-evolution] [Pitch] Make try? + optional chain flattening work together

2018-01-12 Thread John McCall via swift-evolution

> On Jan 12, 2018, at 12:53 PM, BJ Homer via swift-evolution 
>  wrote:
> 
> I agree that this behavior is annoying. However, wouldn’t it be 
> source-breaking to change this now?

Source compatibility means that we can't change the behavior of Swift 3 / Swift 
4 source.  This would be a semantic change when building Swift 5 source (or 
later).  There is no technical reason we couldn't make this change.  It does 
need to meet a very high bar, because we are trying to avoid making significant 
semantic breaks.  My personal sense is that it meets that bar because 
double-optionals can be very confusing for novices and very annoying for 
everyone else.

I think most use sites probably do want the optional-collapsing behavior.  
'try?' is already "sugar" syntax and should aim to be as convenient as possible 
for the majority of use cases.  Much like the collapsing done by optional 
chaining, I think you can come up with examples where somebody would want the 
non-collapsing behavior, but it doesn't seem unreasonable to say that they just 
shouldn't use the sugar.

John.

> 
> -BJ
> 
>> On Jan 12, 2018, at 10:25 AM, Russ Bishop via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Greetings swift-evolution!
>> 
>> There is currently a disconnect between optional chaining and try? when it 
>> comes to optional flattening:
>> 
>> 
>> struct SomeType {
>> func nonThrow() -> SomeType? { return self }
>> func doThrow() throws -> SomeType? { return self }
>> func nonOptional() throws -> SomeType { return self }
>> }
>> 
>> let w = SomeType().nonThrow()?.nonThrow()?.nonThrow()?.nonThrow()
>> // w has type SomeType?
>> 
>> let x = try? 
>> SomeType().nonOptional().nonOptional().nonOptional().nonOptional()
>> // x has type SomeType?
>> 
>> let y = try! SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>> // y has type SomeType?
>> 
>> let z = try? SomeType().doThrow()?.doThrow()?.doThrow()?.doThrow()
>> // z has type SomeType??
>> 
>> 
>> We get a double-optional only when combining try? and optional-chaining. 
>> That is inconvenient and it would be natural to have the compiler do the 
>> flattening here.
>> 
>> 
>> If anyone is interested in working on the proposal or implementation please 
>> let me know. It would make a nice self-contained task if you're looking to 
>> start contributing.
>> 
>> 
>> Russ Bishop
>>  Simulator
>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] extension of AnyObject

2017-12-31 Thread John McCall via swift-evolution

> On Dec 29, 2017, at 11:21 PM, Kenny Leung via swift-evolution 
>  wrote:
> 
> Hi All.
> 
> I just discovered that you can’t write an extension on AnyObject. What’s the 
> reasoning behind this?
> 
> I’m trying to write my own version of KeyValueObserving, and it would be 
> really nice to be able to write
> 
>self.observe(someObject, keyPath) {
>blah de blah
>}
> 
> from anywhere.

The rationale is that AnyObject is a somewhat "structural" protocol, one that's 
really just "this is a class type", which means that extensions on it would 
become a way to add methods to a largely-unresticted set of types.  We've been 
reluctant to allow that for the same reason that we've been reluctant to allow 
extensions on Any.  One such reason that's particularly significant to me is 
that it feels like that would be an ability that would be quickly abused, so 
that the namespace of methods on Any/AnyObject would quickly become very 
crowded, downgrading the experience of code-completion, compiler diagnostics, 
and so on.

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


Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-31 Thread John McCall via swift-evolution

> On Dec 31, 2017, at 1:21 PM, Cheyo Jimenez  wrote:
> 
> 
> 
> On Dec 31, 2017, at 8:59 AM, Ben Rimmington via swift-evolution 
>  wrote:
> 
>>> On 21 Dec 2017, at 03:32, John McCall wrote:
>>> 
> On Dec 20, 2017, at 10:16 PM, Brent Royal-Gordon wrote:
> 
> On Dec 19, 2017, at 2:58 PM, Ted Kremenek wrote:
> 
>   • What is your evaluation of the proposal?
 
 I am pleased with the broad strokes of this design. I have quibbles with 
 three areas:
 
 1. The `@exhaustive` attribute may be confusing because the term doesn't 
 suggest versioning. My best alternative suggestion is `@frozen`, which 
 matches existing programming terminology: something that has been frozen 
 will not be changed in the future.
>>> 
>>> I rather like @frozen.  We could use that across language features, so that 
>>> we don't end up with a keyword per kind of declaration.
>> 
>> Could this also be used on functions to make them inlinable?
>> i.e. The body of the function has been frozen.
>> 
>> ```
>> @frozen
>> public func a()
>> 
>> @available(*, frozen)
>> public func b()
>> 
>> @available(swift, introduced: 4.1, frozen: 5.0)
>> public func c()
>> 
>> ```
> 
> My understanding is that frozen / exhaustible is guaranteed by the compiler 
> while inlineable is more of a strong suggestion to the compiler. It would be 
> confusing to use the same word for both.

Well, this is both true, and false, and true again.

It's true that frozen/inlineable on a function leaves the choice of whether to 
actually perform inlining (or other interprocedural optimizations like 
specialization) up to the compiler, whereas the impact of frozen on a type has 
a direct and reliably-observable impact in the sense of lifting certain 
semantic restrictions.

But from another perspective, the meaning of the attribute to the implementor 
is the same in both cases: it means that the implementation is the same across 
versions.  frozen on a type means that the basic storage structure of the type 
won't change (i.e. it has exactly the same stored properties/cases), and frozen 
on a function means that the behavior of the function won't change.

But then again, while we can reliably check the correctness of frozen on a 
type, we can't really check that for a function.  We can check 
frozen-correctness on a type because we don't mind forbidding non-trivial 
changes to the storage structure: i.e. the set of stored properties/cases (and 
their types) have to remain exactly the same, meaning you can't even do 
"obviously equivalent" changes like combining two stored properties into a 
single property of tuple type.  But we don't want to be that strict with 
functions because we do want to allow some non-trivial differences: it's 
frequently possible to improve the implementation of a function without 
changing its behavior, and we don't want to make that impossible, but we also 
don't really want to get into the business of requiring library authors to 
prove the semantic equivalence of two different function bodies.  That means we 
just have to take implementors at their word that using the new function body 
instead of the old isn't too annoying a difference.  I know Joe Groff has 
proposed in the past that we use a somewhat different semantic model for 
inlineable functions, one that promises that we use the newest available 
functionality, and I think there's some merit to that.

To me, the important questions around keyword choice are:
  - whether the operations feel sufficiently different that using the same 
keyword is going to feel awkward;
  - whether we might be preventing useful expressiveness by using the same 
keyword (the thing that occurs to me is that having a separate attribute for 
inlineable might let us easily mass-annotate an extension, which seems like a 
common use-case); and
  - whether we can get community agreement about it, which might seem "meta", 
but sometimes one must pick one's battles.

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


Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-21 Thread John McCall via swift-evolution

> On Dec 21, 2017, at 3:10 PM, Matthew Johnson  wrote:
> 
> 
>> On Dec 21, 2017, at 2:06 PM, John McCall > <mailto:rjmcc...@apple.com>> wrote:
>> 
>> 
>>> On Dec 21, 2017, at 2:41 PM, Matthew Johnson >> <mailto:matt...@anandabits.com>> wrote:
>>> 
>>> 
>>>> On Dec 21, 2017, at 1:26 PM, John McCall via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> 
>>>>> On Dec 21, 2017, at 2:03 PM, Jordan Rose via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>>> On Dec 20, 2017, at 12:35, Karl Wagner >>>>> <mailto:razie...@gmail.com>> wrote:
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> On 20. Dec 2017, at 19:54, Jordan Rose >>>>>> <mailto:jordan_r...@apple.com>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>>> On Dec 20, 2017, at 05:36, Karl Wagner via swift-evolution 
>>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On 19. Dec 2017, at 23:58, Ted Kremenek via swift-evolution 
>>>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>>>> 
>>>>>>>>> The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs 
>>>>>>>>> through January 3, 2018.
>>>>>>>>> 
>>>>>>>>> The proposal is available here:
>>>>>>>>> 
>>>>>>>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>>>>>>>>>  
>>>>>>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md>+1,
>>>>>>>>>  it needs to happen (and ASAP, since it _will_ introduce 
>>>>>>>>> source-breaking changes one way or the other).
>>>>>>>> 
>>>>>>>> I think non-exhaustive is the correct default. However, does this not 
>>>>>>>> mean that, by default, enums will be boxed because the receiver 
>>>>>>>> doesn’t know their potential size?
>>>>>>> 
>>>>>>> It's not always boxing, but yes, there will be more indirection if the 
>>>>>>> compiler can't see the contents of the enum. (More on that below.)
>>>>>>> 
>>>>>>> 
>>>>>>>> That would mean that the best transition path for multi-module Apps 
>>>>>>>> would be to make your enums @exhaustive, rather than adding “default” 
>>>>>>>> statements (which is unfortunate, because I imagine when this change 
>>>>>>>> hits, the way you’ll notice will be complaints about missing “default” 
>>>>>>>> statements).
>>>>>>> 
>>>>>>> Yep, that's going to be the recommendation. The current 
>>>>>>> minimal-for-review implementation does not do this but I'd like to 
>>>>>>> figure out how to improve that; at the very least it might be a 
>>>>>>> sensible thing to do in the migrator.
>>>>>>> 
>>>>>>>> 
>>>>>>>> I do have some thoughts about how we could ease the transition (for 
>>>>>>>> this and other resilience-related changes), but it’s best to leave 
>>>>>>>> that to a separate discussion.
>>>>>>>> 
>>>>>>>> The one thing I’m still not overly fond of is the name - I would like 
>>>>>>>> us to keep the set of resilience/optimisation related keywords to a 
>>>>>>>> minimum. “exhaustive” for enums feels an awful lot like 
>>>>>>>> “fixed_contents” for structs - couldn’t we come up with a single name 
>>>>>>>> which could be used for both? I don’t think anybody’s going to want to 
>>>>>>>> use “exhaustive” for structs.
>>>>>>> 
>>>>>>> The core team was very focused on this too, but I contend that 
>>>

Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-21 Thread John McCall via swift-evolution

> On Dec 21, 2017, at 2:41 PM, Matthew Johnson  wrote:
> 
> 
>> On Dec 21, 2017, at 1:26 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Dec 21, 2017, at 2:03 PM, Jordan Rose via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> 
>>>> On Dec 20, 2017, at 12:35, Karl Wagner >>> <mailto:razie...@gmail.com>> wrote:
>>>> 
>>>> 
>>>> 
>>>>> On 20. Dec 2017, at 19:54, Jordan Rose >>>> <mailto:jordan_r...@apple.com>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>>> On Dec 20, 2017, at 05:36, Karl Wagner via swift-evolution 
>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> On 19. Dec 2017, at 23:58, Ted Kremenek via swift-evolution 
>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>> The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs 
>>>>>>> through January 3, 2018.
>>>>>>> 
>>>>>>> The proposal is available here:
>>>>>>> 
>>>>>>> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>>>>>>>  
>>>>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md>+1,
>>>>>>>  it needs to happen (and ASAP, since it _will_ introduce 
>>>>>>> source-breaking changes one way or the other).
>>>>>> 
>>>>>> I think non-exhaustive is the correct default. However, does this not 
>>>>>> mean that, by default, enums will be boxed because the receiver doesn’t 
>>>>>> know their potential size?
>>>>> 
>>>>> It's not always boxing, but yes, there will be more indirection if the 
>>>>> compiler can't see the contents of the enum. (More on that below.)
>>>>> 
>>>>> 
>>>>>> That would mean that the best transition path for multi-module Apps 
>>>>>> would be to make your enums @exhaustive, rather than adding “default” 
>>>>>> statements (which is unfortunate, because I imagine when this change 
>>>>>> hits, the way you’ll notice will be complaints about missing “default” 
>>>>>> statements).
>>>>> 
>>>>> Yep, that's going to be the recommendation. The current 
>>>>> minimal-for-review implementation does not do this but I'd like to figure 
>>>>> out how to improve that; at the very least it might be a sensible thing 
>>>>> to do in the migrator.
>>>>> 
>>>>>> 
>>>>>> I do have some thoughts about how we could ease the transition (for this 
>>>>>> and other resilience-related changes), but it’s best to leave that to a 
>>>>>> separate discussion.
>>>>>> 
>>>>>> The one thing I’m still not overly fond of is the name - I would like us 
>>>>>> to keep the set of resilience/optimisation related keywords to a 
>>>>>> minimum. “exhaustive” for enums feels an awful lot like “fixed_contents” 
>>>>>> for structs - couldn’t we come up with a single name which could be used 
>>>>>> for both? I don’t think anybody’s going to want to use “exhaustive” for 
>>>>>> structs.
>>>>> 
>>>>> The core team was very focused on this too, but I contend that 
>>>>> "exhaustive" is not about optimization and really isn't even about 
>>>>> "resilience" (i.e. the ability to evolve a library's API while preserving 
>>>>> binary compatibility). It's a semantic feature of an enum, much like 
>>>>> 'open' or 'final' is for classes, and it affects what a client can or 
>>>>> can't do with an enum. For libaries compiled from source, it won't affect 
>>>>> performance at all—the compiler still knows the full set of cases in the 
>>>>> current version of the library even if the programmer is forced to 
>>>>> consider future versions.
>>>>> 
>>>>> I'm working on the fixed-conte

Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-21 Thread John McCall via swift-evolution

> On Dec 21, 2017, at 2:03 PM, Jordan Rose via swift-evolution 
>  wrote:
> 
> 
> 
>> On Dec 20, 2017, at 12:35, Karl Wagner > > wrote:
>> 
>> 
>> 
>>> On 20. Dec 2017, at 19:54, Jordan Rose >> > wrote:
>>> 
>>> 
>>> 
 On Dec 20, 2017, at 05:36, Karl Wagner via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 
 
> On 19. Dec 2017, at 23:58, Ted Kremenek via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> The review of "SE 0192 - Non-Exhaustive Enums" begins now and runs 
> through January 3, 2018.
> 
> The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> +1,
>  it needs to happen (and ASAP, since it _will_ introduce source-breaking 
> changes one way or the other).
 
 I think non-exhaustive is the correct default. However, does this not mean 
 that, by default, enums will be boxed because the receiver doesn’t know 
 their potential size?
>>> 
>>> It's not always boxing, but yes, there will be more indirection if the 
>>> compiler can't see the contents of the enum. (More on that below.)
>>> 
>>> 
 That would mean that the best transition path for multi-module Apps would 
 be to make your enums @exhaustive, rather than adding “default” statements 
 (which is unfortunate, because I imagine when this change hits, the way 
 you’ll notice will be complaints about missing “default” statements).
>>> 
>>> Yep, that's going to be the recommendation. The current minimal-for-review 
>>> implementation does not do this but I'd like to figure out how to improve 
>>> that; at the very least it might be a sensible thing to do in the migrator.
>>> 
 
 I do have some thoughts about how we could ease the transition (for this 
 and other resilience-related changes), but it’s best to leave that to a 
 separate discussion.
 
 The one thing I’m still not overly fond of is the name - I would like us 
 to keep the set of resilience/optimisation related keywords to a minimum. 
 “exhaustive” for enums feels an awful lot like “fixed_contents” for 
 structs - couldn’t we come up with a single name which could be used for 
 both? I don’t think anybody’s going to want to use “exhaustive” for 
 structs.
>>> 
>>> The core team was very focused on this too, but I contend that "exhaustive" 
>>> is not about optimization and really isn't even about "resilience" (i.e. 
>>> the ability to evolve a library's API while preserving binary 
>>> compatibility). It's a semantic feature of an enum, much like 'open' or 
>>> 'final' is for classes, and it affects what a client can or can't do with 
>>> an enum. For libaries compiled from source, it won't affect performance at 
>>> all—the compiler still knows the full set of cases in the current version 
>>> of the library even if the programmer is forced to consider future versions.
>>> 
>>> I'm working on the fixed-contents proposal now, though it won't be ready 
>>> for a while, and the same thing applies there: for structs compiled from 
>>> source, the compiler can still do all the same optimizations. It's only 
>>> when the library has binary compatibility concerns that we need to use 
>>> extra indirection, and then "fixed-contents" becomes important. (As 
>>> currently designed, it doesn't affect what clients can do with the struct 
>>> at all.) This means that I don't expect a "normal" package author to write 
>>> "fixed-contents" at all (however it ends up being spelled), whereas 
>>> "exhaustive" is a fairly normal thing to consider whenever you make an enum 
>>> public.
>>> 
>>> I hope that convinces you that "fixed-contents" and "exhaustive" don't need 
>>> to have the same name. I don't think anyone loves the particular name 
>>> "exhaustive", but as you see in the "Alternatives considered" we didn't 
>>> manage to come up with anything significantly better. If reviewers all 
>>> prefer something else we'd consider changing it.
>>> 
>>> Thanks for responding!
>>> Jordan
>>> 
>> 
>> When you say “libraries compiled from source”, what do you mean?
> 
> - Other targets in your project
> - Source packages built through SwiftPM / CocoaPods / Carthage / other
> 
> And I was being imprecise with the terminology, but also
> 
> - Libraries built by someone else but designed to be embedded into an app, so 
> that there's no chance of a different version showing up at run-time.
> 
>> 
>> As for whether its a resilience feature: actually it is completely a 
>> resilience feature. The effects on switching are only side-effects; really 
>> what “exhaustive” or “nonexhaustive” are saying is literally that cases may 
>> be added later. Even if we added private cases, you wouldn’t need to mark 
>> th

Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-20 Thread John McCall via swift-evolution

> On Dec 20, 2017, at 10:16 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Dec 19, 2017, at 2:58 PM, Ted Kremenek via swift-evolution 
>>  wrote:
>> 
>>  • What is your evaluation of the proposal?
> 
> I am pleased with the broad strokes of this design. I have quibbles with 
> three areas:
> 
> 1. The `@exhaustive` attribute may be confusing because the term doesn't 
> suggest versioning. My best alternative suggestion is `@frozen`, which 
> matches existing programming terminology: something that has been frozen will 
> not be changed in the future.

I rather like @frozen.  We could use that across language features, so that we 
don't end up with a keyword per kind of declaration.

John.

> 
> 2. I think we need some kind of `future` keyword in `switch` statements. Even 
> though a nonexhaustive enum may gain additional cases in the future, it's 
> still useful for the compiler to diagnose that you forgot *known* cases.
> 
> You say that "switches over non-exhaustive enums should be uncommon", and 
> this is true for many—perhaps most—non-exhaustive enums, but there is still a 
> large class of non-exhaustive enums which need to be switched over. These are 
> the ones I called "category 2" in my previous email in this thread. 
> `SKPaymentTransactionState` is the example I previously used; others might 
> include `Stream.Status` (if not exhaustive), `CLAuthorizationStatus`, 
> `EKParticipantType`, `PKPaymentMethodType`, and `MKMapType`. Each of these 
> could plausibly have more cases added; each has a good reason why you might 
> switch over cases (such as display in a user interface); and each ought to be 
> promptly updated when a new OS version introduces new cases. Without compiler 
> assistance, those updates won't happen.
> 
> If we plan to add private cases in a future version of Swift, `future` may 
> not be the best keyword. `unknown`, `invalid` (or `case #invalid`), etc. may 
> be better.
> 
> 3. I am very skeptical of treating all enums as exhaustive if imported by 
> `@testable import`. The only reason I can see not to do this is that forcing 
> you to provide `default` might hide tests that need to be updated for new 
> enum cases—but this is the exact problem that `future` is trying to solve. By 
> contrast, treating them as non-exhaustive forces you to actually notice when 
> an enum is published as nonexhaustive and consider whether that's the right 
> approach.
> 
> None of these are showstoppers if left unaddressed, but I think the design 
> would be better if we fixed them.
> 
>>  • Is the problem being addressed significant enough to warrant a change 
>> to Swift?
> 
> Yes. I have no idea how Swift programs currently behave when a future 
> framework version adds a case, but I can't imagine they do anything good.
> 
>>  • Does this proposal fit well with the feel and direction of Swift?
> 
> Yes, with the exception of conflating `default` and `future`, which removes 
> useful correctness checks.
> 
>>  • If you have used other languages or libraries with a similar feature, 
>> how do you feel that this proposal compares to those?
> 
> I've experienced bugs in Objective-C caused by the compiler not knowing an 
> enum might have additional, unknown cases. Debugging them sucked.
> 
>>  • How much effort did you put into your review? A glance, a quick 
>> reading, or an in-depth study?
> 
> I've participated in multiple rounds of discussion on this topic, and read 
> the proposal top-to-bottom for this review.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] [Accepted with revisions] SE-0187 “Introduce Sequence.filterMap(_:)”

2017-12-19 Thread John McCall via swift-evolution
Hi, Swift community!  I apologize for the delay in reporting our decision here; 
between one holiday and the other, it took awhile for the core team to assemble 
a quorum to talk through this.

Proposal Link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md
 


The second review of SE-0187 “Introduce Sequence.filterMap(_:)” ran from 
November 15...20, 2017.  The result of the first review was consensus to rename 
the method, and the purpose of the second review was to get more specific 
feedback on what the new name should be.

"filterMap" is a name with some precedent in other programming languages, 
especially functional ones, but some people felt strongly that the name was 
misleading because, as a combined operation, it wasn't quite a filter or a map. 
 Of the alternatives, the one with the strongest support seemed to be 
"compactMap", which builds on the precedent of "compact", an operation from 
other languages (notably Ruby) which returns a copy of the input without nil 
values.  Swift does not currently have such an operation, and in fact it is not 
currently possible to express it; nonetheless, the core team agrees that it 
would be a reasonable operation to add, and that "compactMap" is a good name 
for the operation.

Therefore, SE-0187 is accepted, with the revision that the new name be 
Sequence.compactMap(_:), and with the agreement that we will add 
Sequence.compact() when it is possible to do so.

Thank you all for your continued contributions to making Swift a better 
language.

John McCall
Review Manager 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal and Timeline for Discourse Transition

2017-12-14 Thread John McCall via swift-evolution
> On Dec 14, 2017, at 1:11 PM, Jon Shier  wrote:
> Personally I’d wait and see if much third party discussion happens and the 
> split it out if it gets too noisy. Otherwise you’re separating discussions 
> before we know they’ll happen. 

Yes, I've come around to this position, too.

John.

> 
> On Dec 14, 2017, at 11:01 AM, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> On Dec 14, 2017, at 1:38 AM, Nicole Jacque >> <mailto:jac...@apple.com>> wrote:
>>> 
>>> Could you explain a bit more about how you think that category might be 
>>> used (vs. discussion) and organized?
>> 
>> Well, I was thinking it could be a place for people to form stable working 
>> groups for various projects.  I suppose Development or Evolution is a more 
>> appropriate category for that when the "library or open source project" is 
>> the Swift project itself, so this would just be for other projects, and 
>> maybe there isn't enough of a compelling need to split that out from Using 
>> Swift.
>> 
>> John.
>> 
>>> 
>>>> On Dec 13, 2017, at 9:58 PM, John McCall via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> On Dec 13, 2017, at 6:00 PM, Jonathan Hull via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> I would also like a place in the “Using Swift” for working on libraries 
>>>>> or open source projects. I think asking for collaborators is 
>>>>> fundamentally different than asking technical questions.
>>>>> 
>>>>> It would be nice to have support somehow for the idea of working groups 
>>>>> for evolution
>>>> 
>>>> Having a Workspace category for project collaboration makes a lot of sense 
>>>> to me.
>>>> 
>>>> John.
>>>> 
>>>>> 
>>>>> 
>>>>>> On Dec 12, 2017, at 3:31 AM, Alejandro Martinez via swift-evolution 
>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> This sounds great!
>>>>>> Specially the new structure, it reminds me of the Rust forums. I just
>>>>>> have one question, is the Using Swift category expected to be the one
>>>>>> where the community posts project announcements for new libraries or
>>>>>> similar stuff? I remember a recent thread where some people wanted to
>>>>>> include more libs in the standard swift distribution and one of the
>>>>>> alternatives considered was making it easy for the community to get
>>>>>> together and share new projects and even join forces. This would seem
>>>>>> like the perfect place for it, similar to the announcements category
>>>>>> on Rust forum.
>>>>>> 
>>>>>> 
>>>>>> On Tue, Dec 12, 2017 at 7:42 AM, Ben Rimmington via swift-evolution
>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> [Forum] merging multiple staged accounts
>>>>>>> <https://bugs.swift.org/browse/SR-6594 
>>>>>>> <https://bugs.swift.org/browse/SR-6594>>
>>>>>>> 
>>>>>>> [Forum] importing names with non-Latin characters
>>>>>>> <https://bugs.swift.org/browse/SR-6595 
>>>>>>> <https://bugs.swift.org/browse/SR-6595>>
>>>>>>> 
>>>>>>> -- Ben
>>>>>>> 
>>>>>>>> On 12 Dec 2017, at 06:41, Ben Rimmington wrote:
>>>>>>>> 
>>>>>>>> When claiming a staged account, can the username be changed?
>>>>>>>> e.g. Having the same "@username" on GitHub and Swift Forums.
>>>>>>>> 
>>>>>>>> Will people with multiple accounts be able to merge them?
>>>>>>>> <http://swift.trydiscourse.com/u?name=Lattner&period=all 
>>>>>>>> <http://swift.trydiscourse.com/u?name=Lattner&period=all>>
>>>>>>>> 
>>>>>>>> Names with non-Latin characters are not imported correctly:
>>>>>>>> <http://swift.trydiscourse.com/u?name=1&period=all 
>>>>>>>> <http://swift.trydiscourse.com/u?name=1&period=all>>
>>>>>>>

Re: [swift-evolution] Proposal and Timeline for Discourse Transition

2017-12-14 Thread John McCall via swift-evolution

> On Dec 14, 2017, at 1:38 AM, Nicole Jacque  wrote:
> 
> Could you explain a bit more about how you think that category might be used 
> (vs. discussion) and organized?

Well, I was thinking it could be a place for people to form stable working 
groups for various projects.  I suppose Development or Evolution is a more 
appropriate category for that when the "library or open source project" is the 
Swift project itself, so this would just be for other projects, and maybe there 
isn't enough of a compelling need to split that out from Using Swift.

John.

> 
>> On Dec 13, 2017, at 9:58 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Dec 13, 2017, at 6:00 PM, Jonathan Hull via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> I would also like a place in the “Using Swift” for working on libraries or 
>>> open source projects. I think asking for collaborators is fundamentally 
>>> different than asking technical questions.
>>> 
>>> It would be nice to have support somehow for the idea of working groups for 
>>> evolution
>> 
>> Having a Workspace category for project collaboration makes a lot of sense 
>> to me.
>> 
>> John.
>> 
>>> 
>>> 
>>>> On Dec 12, 2017, at 3:31 AM, Alejandro Martinez via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> This sounds great!
>>>> Specially the new structure, it reminds me of the Rust forums. I just
>>>> have one question, is the Using Swift category expected to be the one
>>>> where the community posts project announcements for new libraries or
>>>> similar stuff? I remember a recent thread where some people wanted to
>>>> include more libs in the standard swift distribution and one of the
>>>> alternatives considered was making it easy for the community to get
>>>> together and share new projects and even join forces. This would seem
>>>> like the perfect place for it, similar to the announcements category
>>>> on Rust forum.
>>>> 
>>>> 
>>>> On Tue, Dec 12, 2017 at 7:42 AM, Ben Rimmington via swift-evolution
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> [Forum] merging multiple staged accounts
>>>>> <https://bugs.swift.org/browse/SR-6594 
>>>>> <https://bugs.swift.org/browse/SR-6594>>
>>>>> 
>>>>> [Forum] importing names with non-Latin characters
>>>>> <https://bugs.swift.org/browse/SR-6595 
>>>>> <https://bugs.swift.org/browse/SR-6595>>
>>>>> 
>>>>> -- Ben
>>>>> 
>>>>>> On 12 Dec 2017, at 06:41, Ben Rimmington wrote:
>>>>>> 
>>>>>> When claiming a staged account, can the username be changed?
>>>>>> e.g. Having the same "@username" on GitHub and Swift Forums.
>>>>>> 
>>>>>> Will people with multiple accounts be able to merge them?
>>>>>> <http://swift.trydiscourse.com/u?name=Lattner&period=all 
>>>>>> <http://swift.trydiscourse.com/u?name=Lattner&period=all>>
>>>>>> 
>>>>>> Names with non-Latin characters are not imported correctly:
>>>>>> <http://swift.trydiscourse.com/u?name=1&period=all 
>>>>>> <http://swift.trydiscourse.com/u?name=1&period=all>>
>>>>>> e.g. StringTransform("Any-Latin; Latin-ASCII; Any-Title")
>>>>>> 
>>>>>> -- Ben
>>>>> 
>>>>> ___
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Alejandro Martinez
>>>> http://alejandromp.com <http://alejandromp.com/>
>>>> ___
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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] Proposal and Timeline for Discourse Transition

2017-12-13 Thread John McCall via swift-evolution
> On Dec 13, 2017, at 6:00 PM, Jonathan Hull via swift-evolution 
>  wrote:
> I would also like a place in the “Using Swift” for working on libraries or 
> open source projects. I think asking for collaborators is fundamentally 
> different than asking technical questions.
> 
> It would be nice to have support somehow for the idea of working groups for 
> evolution

Having a Workspace category for project collaboration makes a lot of sense to 
me.

John.

> 
> 
>> On Dec 12, 2017, at 3:31 AM, Alejandro Martinez via swift-evolution 
>>  wrote:
>> 
>> This sounds great!
>> Specially the new structure, it reminds me of the Rust forums. I just
>> have one question, is the Using Swift category expected to be the one
>> where the community posts project announcements for new libraries or
>> similar stuff? I remember a recent thread where some people wanted to
>> include more libs in the standard swift distribution and one of the
>> alternatives considered was making it easy for the community to get
>> together and share new projects and even join forces. This would seem
>> like the perfect place for it, similar to the announcements category
>> on Rust forum.
>> 
>> 
>> On Tue, Dec 12, 2017 at 7:42 AM, Ben Rimmington via swift-evolution
>>  wrote:
>>> [Forum] merging multiple staged accounts
>>> 
>>> 
>>> [Forum] importing names with non-Latin characters
>>> 
>>> 
>>> -- Ben
>>> 
 On 12 Dec 2017, at 06:41, Ben Rimmington wrote:
 
 When claiming a staged account, can the username be changed?
 e.g. Having the same "@username" on GitHub and Swift Forums.
 
 Will people with multiple accounts be able to merge them?
 
 
 Names with non-Latin characters are not imported correctly:
 
 e.g. StringTransform("Any-Latin; Latin-ASCII; Any-Title")
 
 -- Ben
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> 
>> 
>> -- 
>> Alejandro Martinez
>> http://alejandromp.com
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Proposal and Timeline for Discourse Transition

2017-12-12 Thread John McCall via swift-evolution

> On Dec 12, 2017, at 3:28 PM, Alejandro Martinez  wrote:
> 
> Yes that's what I was suggesting.
> My view is that different kind of conversations would happen in a
> "help" vs. "announcements" category. Some people may be interested in
> being up to date with the more experienced users, announcements of new
> projects or putting together efforts towards a lib or even meetups or
> other IRL stuff; but don't want to spent time reading trough a more
> "stack overflowy" kind of posts.
> But I don't really have a strong view on this, I just wanted to
> clarify it as, for example, Rust forums do this differentiation and I
> figured it was worth raising it now :P

I think this would be best as a tag within the Using Swift category.

John.

> Cheers
> 
> On Tue, Dec 12, 2017 at 6:44 PM, John McCall  wrote:
>> 
>> On Dec 12, 2017, at 1:36 PM, Alejandro Martinez via swift-evolution
>>  wrote:
>> 
>> On Tue, Dec 12, 2017 at 4:15 PM, Kelvin Ma  wrote:
>> 
>> 
>> 
>> On Tue, Dec 12, 2017 at 5:31 AM, Alejandro Martinez via swift-evolution
>>  wrote:
>> 
>> 
>> This sounds great!
>> Specially the new structure, it reminds me of the Rust forums. I just
>> have one question, is the Using Swift category expected to be the one
>> where the community posts project announcements for new libraries or
>> similar stuff? I remember a recent thread where some people wanted to
>> include more libs in the standard swift distribution and one of the
>> alternatives considered was making it easy for the community to get
>> together and share new projects and even join forces. This would seem
>> like the perfect place for it, similar to the announcements category
>> on Rust forum.
>> 
>> 
>> 
>> i always thought Using Swift was going to be more for beginner questions and
>> helping newcomers
>> 
>> 
>> That's what it looks like, which is completely fine. But if that's the
>> case I think we should have another category for that kind of stuff ;)
>> 
>> 
>> I think it's open to both, just as swift-users is today.  The topic name
>> needs to
>> encourage beginner questions because otherwise the beginners won't know
>> where
>> to go; experienced forum users presumably don't need that kind of direction.
>> 
>> Are you suggesting that these ought to be split into separate categories?  I
>> don't think
>> I'd support that.
>> 
>> John.
> 
> 
> 
> -- 
> Alejandro Martinez
> http://alejandromp.com

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


Re: [swift-evolution] Proposal and Timeline for Discourse Transition

2017-12-12 Thread John McCall via swift-evolution

> On Dec 12, 2017, at 1:36 PM, Alejandro Martinez via swift-evolution 
>  wrote:
> 
> On Tue, Dec 12, 2017 at 4:15 PM, Kelvin Ma  > wrote:
>> 
>> 
>> On Tue, Dec 12, 2017 at 5:31 AM, Alejandro Martinez via swift-evolution
>>  wrote:
>>> 
>>> This sounds great!
>>> Specially the new structure, it reminds me of the Rust forums. I just
>>> have one question, is the Using Swift category expected to be the one
>>> where the community posts project announcements for new libraries or
>>> similar stuff? I remember a recent thread where some people wanted to
>>> include more libs in the standard swift distribution and one of the
>>> alternatives considered was making it easy for the community to get
>>> together and share new projects and even join forces. This would seem
>>> like the perfect place for it, similar to the announcements category
>>> on Rust forum.
>> 
>> 
>> i always thought Using Swift was going to be more for beginner questions and
>> helping newcomers
>> 
> 
> That's what it looks like, which is completely fine. But if that's the
> case I think we should have another category for that kind of stuff ;)

I think it's open to both, just as swift-users is today.  The topic name needs 
to
encourage beginner questions because otherwise the beginners won't know where
to go; experienced forum users presumably don't need that kind of direction.

Are you suggesting that these ought to be split into separate categories?  I 
don't think
I'd support that.

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


Re: [swift-evolution] Synthesizing Equatable, Hashable, and Comparable for tuple types

2017-11-26 Thread John McCall via swift-evolution
> On Nov 27, 2017, at 1:43 AM, David Hart  wrote:
> On 27 Nov 2017, at 07:32, John McCall  > wrote:
> 
>> 
>>> On Nov 22, 2017, at 2:01 AM, David Hart via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> 
 On 22 Nov 2017, at 07:48, David Hart via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 
 
 On 22 Nov 2017, at 07:41, Douglas Gregor via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> 
> 
>> On Nov 21, 2017, at 10:37 PM, Chris Lattner > > wrote:
>> 
>> On Nov 21, 2017, at 9:25 PM, Douglas Gregor > > wrote:
 Or alternatively, one could decide to make the generics system *only 
 and forever* work on nominal types, and make the syntactic sugar just 
 be sugar for named types like Swift.Tuple, Function, and Optional.  
 Either design could work.
>>> 
>>> We don’t have a way to make it work for function types, though, because 
>>> of parameter-passing conventions. Well, assuming we don’t invent 
>>> something that allows:
>>> 
>>> Function
>>> 
>>> to exist in the type system. Tuple labels have a similar problem.
>> 
>> I’m totally aware of that and mentioned it upthread.
> 
> Eh, sorry I missed it.
> 
>>  There are various encoding tricks that could make this work depending 
>> on how you want to stretch the current generics system…
> 
> I think it’s straightforward and less ugly to make structural types allow 
> extensions and protocol conformances.
 
 Can somebody explain to me what is less ugly about that? I would have 
 naturally thought that the language would be simpler as a whole if there 
 only existed nominal types and all structural types were just sugar over 
 them.
>>> 
>>> What confuses me is that I always thought that T? was sugar for Optional 
>>> by design, and found that to be quite elegant. But now you’re telling me 
>>> that its just a hack to allow conformance on Optionals until it can be made 
>>> structural. I would have thought that it would be cleaner to have specific 
>>> concepts (optionals, tuples, etc…) represented in terms of more general 
>>> concepts (enum, struct) so that the compiler had less to reason about. I’m 
>>> just trying to understand :-)
>> 
>> Don't worry too much about it.  The people in this thread are conflating a 
>> lot of different things, including some people who ought to know better.  
>> Your way of looking at it is perfectly accurate.
>> 
>> A fairly standard formalization of types is that you have these type 
>> expressions, which, in a simple system, are either type constants or type 
>> applications.
>> 
>> A type constant is something like Int, Float, or Array.  struct/enum/class 
>> declarations in Swift all introduce new type constants, where each 
>> declaration has its own identity as a type.  Since we don't allow type names 
>> to be redeclared in a scope, the identity of such declared types can be 
>> uniquely determined by (1) the type's name in its scope and (2) the path to 
>> that scope.  Hence the identity is "by name", or "nominal".
>> 
>> A type application takes a generic type and applies it at some number of 
>> arguments.  The general syntax for this in Swift is <>.  For example, Array 
>> is a generic type, and Array is a type application of the generic type 
>> Array with the argument Int.  The arguments can be arbitrary type 
>> expressions, e.g. Dictionary>.  The identity of a type 
>> application is determined purely by its applicative structure: first, the 
>> identity of the generic type being applied, and second, the identity of the 
>> type arguments it is being applied to.  That is, A is the same type as 
>> C as long as the type-expression A is the same generic type as C and B is 
>> the same type as D.  Hence the identity is "structural".
>> 
>> (Formal nitpick: we're making some assumptions about the nature of type 
>> expressions that generally work out until you get into really advanced type 
>> systems.)
>> 
>> What is a tuple type in this formalization?  Well, the rule we want is that 
>> (A, B) is the same type as (C, D) if A is identical to C and B is identical 
>> to D.  We could add this as a special new rule to our definition of type 
>> expressions above, but we don't really need to, because it turns out that 
>> it's exactly the same as if we had some sort of tuple type constant — for 
>> sake of argument, let's call it (...) — and allowed it to be applied to an 
>> arbitrary number of types.  Swift does not actually allow you to name this 
>> as an unapplied generic type — you cannot write (...) instead of 
>> (Int, Float) — but that's just a matter of syntax.  The fact that (...) is 
>> built into the language rather than being declared in the standard library 
>> as Tuple is not f

Re: [swift-evolution] Synthesizing Equatable, Hashable, and Comparable for tuple types

2017-11-26 Thread John McCall via swift-evolution

> On Nov 22, 2017, at 2:01 AM, David Hart via swift-evolution 
>  wrote:
> 
> 
> 
>> On 22 Nov 2017, at 07:48, David Hart via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> 
>> On 22 Nov 2017, at 07:41, Douglas Gregor via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> 
 On Nov 21, 2017, at 10:37 PM, Chris Lattner >>> > wrote:
 
 On Nov 21, 2017, at 9:25 PM, Douglas Gregor >>> > wrote:
>> Or alternatively, one could decide to make the generics system *only and 
>> forever* work on nominal types, and make the syntactic sugar just be 
>> sugar for named types like Swift.Tuple, Function, and Optional.  Either 
>> design could work.
> 
> We don’t have a way to make it work for function types, though, because 
> of parameter-passing conventions. Well, assuming we don’t invent 
> something that allows:
> 
>   Function
> 
> to exist in the type system. Tuple labels have a similar problem.
 
 I’m totally aware of that and mentioned it upthread.
>>> 
>>> Eh, sorry I missed it.
>>> 
  There are various encoding tricks that could make this work depending on 
 how you want to stretch the current generics system…
>>> 
>>> I think it’s straightforward and less ugly to make structural types allow 
>>> extensions and protocol conformances.
>> 
>> Can somebody explain to me what is less ugly about that? I would have 
>> naturally thought that the language would be simpler as a whole if there 
>> only existed nominal types and all structural types were just sugar over 
>> them.
> 
> What confuses me is that I always thought that T? was sugar for Optional 
> by design, and found that to be quite elegant. But now you’re telling me that 
> its just a hack to allow conformance on Optionals until it can be made 
> structural. I would have thought that it would be cleaner to have specific 
> concepts (optionals, tuples, etc…) represented in terms of more general 
> concepts (enum, struct) so that the compiler had less to reason about. I’m 
> just trying to understand :-)

Don't worry too much about it.  The people in this thread are conflating a lot 
of different things, including some people who ought to know better.  Your way 
of looking at it is perfectly accurate.

A fairly standard formalization of types is that you have these type 
expressions, which, in a simple system, are either type constants or type 
applications.

A type constant is something like Int, Float, or Array.  struct/enum/class 
declarations in Swift all introduce new type constants, where each declaration 
has its own identity as a type.  Since we don't allow type names to be 
redeclared in a scope, the identity of such declared types can be uniquely 
determined by (1) the type's name in its scope and (2) the path to that scope.  
Hence the identity is "by name", or "nominal".

A type application takes a generic type and applies it at some number of 
arguments.  The general syntax for this in Swift is <>.  For example, Array is 
a generic type, and Array is a type application of the generic type Array 
with the argument Int.  The arguments can be arbitrary type expressions, e.g. 
Dictionary>.  The identity of a type application is 
determined purely by its applicative structure: first, the identity of the 
generic type being applied, and second, the identity of the type arguments it 
is being applied to.  That is, A is the same type as C as long as the 
type-expression A is the same generic type as C and B is the same type as D.  
Hence the identity is "structural".

(Formal nitpick: we're making some assumptions about the nature of type 
expressions that generally work out until you get into really advanced type 
systems.)

What is a tuple type in this formalization?  Well, the rule we want is that (A, 
B) is the same type as (C, D) if A is identical to C and B is identical to D.  
We could add this as a special new rule to our definition of type expressions 
above, but we don't really need to, because it turns out that it's exactly the 
same as if we had some sort of tuple type constant — for sake of argument, 
let's call it (...) — and allowed it to be applied to an arbitrary number of 
types.  Swift does not actually allow you to name this as an unapplied generic 
type — you cannot write (...) instead of (Int, Float) — but that's 
just a matter of syntax.  The fact that (...) is built into the language rather 
than being declared in the standard library as Tuple is not fundamentally 
significant.  Nor is it fundamentally significant for Optional, which is 
currently declared in the standard library instead of being built-in.

(Function types in Swift are weird because, as covered previously in this 
thread, there's more to their structure than just component type identity.  You 
could still stretch the formalization to make this work, but, well, they'd 
still be weird.)

N

Re: [swift-evolution] [Pitch] Make Optional, Array, and Dictionary conditionally Equatable

2017-11-26 Thread John McCall via swift-evolution

> On Nov 22, 2017, at 1:08 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPhone
> 
> On Nov 22, 2017, at 9:48 AM, Chris Lattner  > wrote:
> 
>> IMO this is obvious and you should put it in.
>> 
>> The process serves a purpose: to ensure the evolution of the language is 
>> going in the right place, both directionally in an details.  It is obvious 
>> that we’re going to take this, and the details are clear, therefore doing an 
>> evolution cycle for this would just waste everyone’s time.
> 
> I’ve been leaning this way as well. We can treat this small addition as an 
> amendment to SE-0143 so the change is documented appropriately. 

Agreed.  I think bringing it up here and letting it "pass by acclamation" is 
the appropriate process; doing a separate proposal would be a waste.

John.

> 
>> 
>> That said, when you get to less obvious introductions and start doing more 
>> major consolidation and simplification of the stdlib, those changes may be 
>> worthy of discussion to ensure the details are right.
> 
> Right. All of the consolidation of the various Slice and lazy types is big 
> enough to warrant a proposal, for example. 
> 
>   - Doug
> 
>> 
>> -Chris
>> 
>>> On Nov 21, 2017, at 10:51 PM, Douglas Gregor via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hi all,
>>> 
>>> We’re having a bit of a debate  
>>> over the question of whether SE-0143 “Conditional Conformances” 
>>> 
>>>  actually proposes any standard library changes at all, or whether they 
>>> should all be brought up separately. So, I’ll pitch the pieces that I’d 
>>> love to put into 4.1 to see if they’re as obvious as I think they should be 
>>> :)
>>> 
>>> Proposal: make Optional, Array, ArraySlice, ContiguousArray, and Dictionary 
>>> conform to Equatable when their type parameters are Equatable (and Set 
>>> always conform to Equatable). Specifically, add to the standard library:
>>> 
>>> extension Optional: Equatable where Wrapped: Equatable { /*== already 
>>> exists */ }
>>> extension Array: Equatable where Element: Equatable { /*== already 
>>> exists */ }
>>> extension ArraySlice: Equatable where Element: Equatable { /*== already 
>>> exists */ }
>>> extension ContiguousArray: Equatable where Element: Equatable { /*== 
>>> already exists */ }
>>> extension Dictionary: Equatable where Value: Equatable { /*== already 
>>> exists */ }
>>> extension Set: Equatable { /*== already exists */ }
>>> 
>>> Motivation: we need these for ==/!= to properly compose. It’s a 
>>> highly-requested feature and an obvious “first use” of conditional 
>>> conformances for the standard library that is unlikely to break any code.
>>> 
>>> Implementation: https://github.com/apple/swift/pull/13046 
>>> 
>>> 
>>> Thoughts?
>>> 
>>> 
>>> - Doug
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [swift-evolution-announce] [Accepted and Focused Re-review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-20 Thread John McCall via swift-evolution
> On Nov 20, 2017, at 12:22 PM, BJ Homer  wrote:
>> On Nov 20, 2017, at 10:09 AM, Drew Crawford via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> The typical case for this function in my code is the identity closure, that 
>> is
>> 
>> let a: [Int?] = ...
>> print(a.filterMap {$0})
>> 
>> filterMap is quite poor for this situation because *each* component in the 
>> term is inaccurate:
> 
> filterMap is indeed an awkward name for this use case, just like flatMap is. 
> In my experience, about half of my use cases use the identity closure, and 
> half actually make use of the closure in a meaningful way. I would support a 
> proposal to add something like Sequence.dropNils (actual name to be 
> determined), and then we could let this proposal target the 
> non-identity-closure use case.

If the identity closure (i.e. "please remove the nils from this sequence") is a 
common use case, then I absolutely agree that we should consider adding a 
specific operation for that, and that name might illuminate the right name for 
the mapping version.

John.

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


Re: [swift-evolution] [Accepted and Focused Re-review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-15 Thread John McCall via swift-evolution

> On Nov 15, 2017, at 9:16 PM, Greg Parker  wrote:
> 
> 
>> On Nov 15, 2017, at 5:53 PM, John McCall > > wrote:
>> 
>>> On Nov 15, 2017, at 7:36 PM, Greg Parker via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 On Nov 15, 2017, at 2:31 PM, BJ Homer via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> On Nov 15, 2017, at 3:05 PM, Tino Heth via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> Odd… exactly that is the reason why I think filterMap is the worst choice:
> 
> Both are established terms of art, but one has a meaning that doesn’t fit 
> to the operation.
> Applying filter can remove elements, but it can never change types (I 
> feel kind of silly to repeat this over and over, but so far, nobody took 
> the time to falsify this).
 
 The concern about filter changing types is only relevant if you think of 
 the filter applying to the result of the map, instead of being a part of 
 the filterMap operation itself (an operation that is distinct from map).
 
 Let’s imagine that we had this instead:
 
 enum SelectiveMapResult {
 case use(T)
 case ignore
 }
 
 extension Sequence {
 func selectiveMap(_ selectiveTransform: 
 (Element)->SelectiveMapResult) -> [T]
 }
 
 let actualNumbers =
 ["1", "2", "apple", "banana", "5"].selectiveMap({ 
 (x)->SelectiveMapResult in
 if let value = Int(x) { return .use(value) }
 else { return .ignore }
 })
 
 actualNumbers == [1, 2, 5]
 
 The “selective” part of this operation doesn’t feel like it’s changing the 
 type of the result, because SelectiveMapResult is easily understood to not 
 be part of the mapping transformation; it just exists to tell us whether 
 we should use the result of that particular transformation. Likewise, I 
 don’t feel like the optional in filterMap is part of the mapping 
 operation; it’s just serving the same role as SelectiveMapResult. (It 
 should be obvious that SelectiveMapResult is just Optional with another 
 name here.)
>>> 
>>> "selectiveMap" feels better in part due to grammar. "map" is obviously the 
>>> verb and "selective" is obviously a modification of "map". "selectiveMap" 
>>> is therefore performing some sort of special map operation. 
>>> 
>>> "filterMap" feels bad for the same reason that "selectMap" would feel worse 
>>> than "selectiveMap". "filter" and "map" are both verbs in this context. 
>>> Grammatically the analogue to "selectiveMap" would be "filteredMap" or 
>>> "filteringMap". 
>>> 
>>> But even then "filteredMap" or "filteringMap" is insufficient to describe 
>>> the operation. You additionally need to know that the "filter" here is not 
>>> ordinary "filter", but instead the special case "filter { $0 != nil }".
>>> 
>>> 
 The name filterMap focuses on removing the ignored values, as does 
 compactMap. The name selectiveMap focuses on retaining the non-ignored 
 values. I’m not sure whether focusing on the positive or negative aspects 
 is clearer here. I don’t particularly like the name compactMap, simply 
 because I don’t have a lot of experience with languages that use “compact” 
 to mean “drop the nil values”, and without that experience it doesn’t seem 
 intuitive. I think filterMap is better. But if we introduced 
 Sequence.compact() alongside .compactMap(), I’d probably get used to it.
>>> 
>>> Swift doesn't use "filter" to mean "drop the nil values" either. 
>>> 
>>> 
>>> "compactMap" is okay if "compact" is added. Is "compact" a common enough 
>>> operation in practice to pull its own weight?
>>> 
>>> "mapSome" is great if you know about Optional.Some but terrible if you 
>>> don't. ("Okay, it maps some elements, but which ones?") 
>>> 
>>> "mapNonNil" is obvious and ugly and perhaps its obviousness makes it a 
>>> winner.
>> 
>> mapSome and especially mapNonNil both sound to me like they only map the 
>> non-nil values in the source sequence.
> 
> I thought it did map the non-nil values in the source sequence. Did I 
> misunderstand what the proposed filterMap does? It occurs to me that the 
> proposal does not have a standalone description of the filterMap operation.

func filterMap(_ f: (Element) -> T?) -> [T] {
  return self.map(f).filter { $0 != nil }.map( $0! } // not an efficient 
implementation
}

A mapping function is applied to all elements of the source sequence.  Unlike 
map, however, the mapping function can return nil, causing that value to be 
dropped from the result sequence.  Since the result sequence can therefore not 
contain any (directly) nil values, a level of optionality is removed from the 
result element type.  A common use case — perhaps the most common — is to 
simultaneously map and filter a sequence without introducing any unnecessary 
intermedia

Re: [swift-evolution] [Accepted and Focused Re-review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-15 Thread John McCall via swift-evolution

> On Nov 15, 2017, at 7:36 PM, Greg Parker via swift-evolution 
>  wrote:
> 
>> 
>> On Nov 15, 2017, at 2:31 PM, BJ Homer via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Nov 15, 2017, at 3:05 PM, Tino Heth via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Odd… exactly that is the reason why I think filterMap is the worst choice:
>>> 
>>> Both are established terms of art, but one has a meaning that doesn’t fit 
>>> to the operation.
>>> Applying filter can remove elements, but it can never change types (I feel 
>>> kind of silly to repeat this over and over, but so far, nobody took the 
>>> time to falsify this).
>> 
>> The concern about filter changing types is only relevant if you think of the 
>> filter applying to the result of the map, instead of being a part of the 
>> filterMap operation itself (an operation that is distinct from map).
>> 
>> Let’s imagine that we had this instead:
>> 
>> enum SelectiveMapResult {
>> case use(T)
>> case ignore
>> }
>> 
>> extension Sequence {
>> func selectiveMap(_ selectiveTransform: 
>> (Element)->SelectiveMapResult) -> [T]
>> }
>> 
>> let actualNumbers =
>> ["1", "2", "apple", "banana", "5"].selectiveMap({ 
>> (x)->SelectiveMapResult in
>> if let value = Int(x) { return .use(value) }
>> else { return .ignore }
>> })
>> 
>> actualNumbers == [1, 2, 5]
>> 
>> The “selective” part of this operation doesn’t feel like it’s changing the 
>> type of the result, because SelectiveMapResult is easily understood to not 
>> be part of the mapping transformation; it just exists to tell us whether we 
>> should use the result of that particular transformation. Likewise, I don’t 
>> feel like the optional in filterMap is part of the mapping operation; it’s 
>> just serving the same role as SelectiveMapResult. (It should be obvious that 
>> SelectiveMapResult is just Optional with another name here.)
> 
> "selectiveMap" feels better in part due to grammar. "map" is obviously the 
> verb and "selective" is obviously a modification of "map". "selectiveMap" is 
> therefore performing some sort of special map operation. 
> 
> "filterMap" feels bad for the same reason that "selectMap" would feel worse 
> than "selectiveMap". "filter" and "map" are both verbs in this context. 
> Grammatically the analogue to "selectiveMap" would be "filteredMap" or 
> "filteringMap". 
> 
> But even then "filteredMap" or "filteringMap" is insufficient to describe the 
> operation. You additionally need to know that the "filter" here is not 
> ordinary "filter", but instead the special case "filter { $0 != nil }".
> 
> 
>> The name filterMap focuses on removing the ignored values, as does 
>> compactMap. The name selectiveMap focuses on retaining the non-ignored 
>> values. I’m not sure whether focusing on the positive or negative aspects is 
>> clearer here. I don’t particularly like the name compactMap, simply because 
>> I don’t have a lot of experience with languages that use “compact” to mean 
>> “drop the nil values”, and without that experience it doesn’t seem 
>> intuitive. I think filterMap is better. But if we introduced 
>> Sequence.compact() alongside .compactMap(), I’d probably get used to it.
> 
> Swift doesn't use "filter" to mean "drop the nil values" either. 
> 
> 
> "compactMap" is okay if "compact" is added. Is "compact" a common enough 
> operation in practice to pull its own weight?
> 
> "mapSome" is great if you know about Optional.Some but terrible if you don't. 
> ("Okay, it maps some elements, but which ones?") 
> 
> "mapNonNil" is obvious and ugly and perhaps its obviousness makes it a winner.

mapSome and especially mapNonNil both sound to me like they only map the 
non-nil values in the source sequence.

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


[swift-evolution] [Accepted and Focused Re-review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-15 Thread John McCall via swift-evolution
Hello, Swift Community!

The initial review of "SE-0187: Introduce Sequence.filterMap(_:)" ran through 
yesterday, November 14th, 2017.  The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md
 


There was a significant amount of discussion, and people came down with 
reasonable arguments both for and against the proposal.  After reviewing that 
feedback, the core team feels that the central question is whether Swift 
benefits from overloading flatMap in this way.  There is a reasonable argument 
that an Optional is a sort of container, and therefore it makes sense to 
"flatten" that container into a surrounding container.  But Swift has resisted 
applying that interpretation in its library design; for example, you cannot 
directly iterate an Optional or append its contents to an Array.  In general, 
we feel that using different operations for working with Optionals tends to 
make code easier to both write and understand, especially given the existence 
of implicit optional promotion, which we cannot eliminate or easily suppress 
based on the context.  On reflection, we think it was a mistake to use the same 
name in the first place, and there is no better time to fix a mistake than now.

While we accept that this will cause some amount of "code churn" for developers 
when they adopt Swift 5, the required change is a simple rename that should be 
painless to automatically migrate.  Of course, sample code on the internet will 
become obsolete, but fix-its will easily update that code if pasted into a 
project, and the samples themselves (once corrected) should become clearer and 
easier to teach after this change, as is generally true when overloading is 
removed.

Accordingly, SE-0187 is accepted, at least as far as not calling the operation 
"flatMap".  We are re-opening the review until next Monday, November 20th, 
2017, in order to have a focused discussion about the new name.  Names that 
seemed to gain some traction in the first review include:

  - filterMap, which has precedent in existing functional languages, as well as 
some popular Swift libraries, but which some people view as confusing

  - compactMap, which builds off the precedent of "compact" in Ruby

But please feel free to suggest a name other than these.

Reviews

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 me as 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/0187-introduce-filtermap.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 


As always, thank you for contributing to the evolution of Swift.

John McCall
Review Manager___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-13 Thread John McCall via swift-evolution

> On Nov 12, 2017, at 11:11 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Nov 12, 2017, at 12:55 AM, David Hart via swift-evolution 
>>  wrote:
>> 
>> Hello evolution folks,
>> 
>> After the positive feedback on the idea of improving capturing semantics of 
>> local functions, Alex Lynch and I worked on a proposal. Please let us know 
>> if you have any feedback:
>> 
>> https://github.com/hartbit/swift-evolution/blob/improving-capturing-semantics-of-local-functions/proposals/-improve-capture-semantics-of-local-functions.md
> 
> So, quoting the proposal:
> 
>> First of all, this proposal suggests extending the requirement of the self. 
>> prefix to local functions, but only if the local function is used as or used 
>> inside an escaping closure.
> 
> I don't love that the use of a function many lines away can cause errors in 
> that closure. There's a "spooky action-at-a-distance" quality to this 
> behavior that I don't like.
> 
> The best idea I have is to require local functions to be annotated with 
> `@escaping` if they're to be used in an escaping closure:
> 
>func foo() {
>// `local1` is nonescaping since it isn't marked with the @escaping 
> attribute.
>func local1() {
>bar()
>}
>local1()   // OK, direct call
>{ local1() }() // OK, closure is nonescaping
>DispatchQueue.main.async(execute: local1)  // error: passing 
> non-escaping function 'local2' to function expecting an @escaping closure
>DispatchQueue.main.async { local1() }  // error: closure use 
> of non-escaping function 'local2' may allow it to escape
> 
>@escaping func local2() {
>bar()  // error: call to method 'bar' in escaping 
> local function requires explicit 'self.' to make capture semantics explicit
>}
> 
>@escaping func local3() {
>   self. bar() // OK, explicit `self`
>}
>DispatchQueue.main.async(execute: local3)  // OK, escaping function
>DispatchQueue.main.async { local3() }  // OK, escaping closure
>   }
> 
>func bar() {
>print("bar")
>}
> 
> But this would be quite source-breaking. (Maybe it could be introduced as a 
> warning first?)

I like the idea of requiring @escaping to be explicit on local funcs, but I'm 
worried that it might be too onerous; after all, we infer @escapingness on 
closures quite successfully.  At the same time, I agree that applying semantic 
rules based on how the func is used, potentially much later in the function, is 
really spooky.  I don't have a great alternative right now.

Random note: we currently infer non-escapingness for local funcs that capture 
``inout``s, since those cannot be allowed to escape.  In fact, this is the only 
way to make a local function non-escaping at all.

John.

> 
>> Secondly, this proposal suggests allowing the same capture list syntax from 
>> closures in local functions. Capture lists would still be invalid in 
>> top-level and member functions.
> 
> 
> I think this is a good idea, but I don't like bringing the already weird use 
> of `in` to actual functions.
> 
> By analogy with the current closure syntax, the capture list ought to go 
> somewhere before the parameter list, in one of these slots:
> 
> 1.func fn[foo, bar](param: T) throws -> T where T: Equatable { … }
> 2.func fn[foo, bar](param: T) throws -> T where T: Equatable { … }
> 3.func [foo, bar] fn(param: T) throws -> T where T: Equatable { … }
> 4.[foo, bar] func fn(param: T) throws -> T where T: Equatable { … }
> 
> Of these options, I actually think #4 reads best; 1 and 2 are very cluttered, 
> and 3 just seems weird. But it seems like the one that would be easiest to 
> misparse.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-08 Thread John McCall via swift-evolution
> On Nov 8, 2017, at 3:20 PM, Tino Heth via swift-evolution 
>  wrote:
>> This is a wonderful example! But it’s an argument for a different discussion 
>> (of general usefulness of implicit optional promotion). Thanks to the 
>> optional promotion, what the closure returns is not nil, but instead is 
>> .some(nil), and that is not filtered out.
> My point is: The proposed filterMap isn’t a combination of map and filter at 
> all — or can you build it just out of map & filter, like flatMap is 
> constructed from map & flatten?

You can built it out of map and filter:

  func filterMap(_ fn: (Element) -> U?) -> [U] {
return map(fn).filter { $0 != nil }.map { $0! }
  }

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


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-08 Thread John McCall via swift-evolution

> On Nov 8, 2017, at 1:20 PM, Kevin Ballard  wrote:
> 
> On Tue, Nov 7, 2017, at 09:37 PM, John McCall wrote:
>> 
>>> On Nov 7, 2017, at 6:34 PM, Kevin Ballard via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> On Tue, Nov 7, 2017, at 03:23 PM, John McCall via swift-evolution wrote:
>>>> https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md
>>>>  
>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md>
>>>> 
>>>> • What is your evaluation of the proposal?
>>> 
>>> This proposal is going to cause an insane amount of code churn. The 
>>> proposal suggests this overload of flatMap is used "in certain 
>>> circumstances", but in my experience it's more like 99% of all flatMaps on 
>>> sequences are to deal with optionals, not to flatten nested sequences.
>>> 
>>>> • Is the problem being addressed significant enough to warrant a change to 
>>>> Swift?
>>> 
>>> I don't think so. It's a fairly minor issue, one that really only affects 
>>> new Swift programmers anyway rather than all users, and it will cause far 
>>> too much code churn to be worthwhile.
>>> 
>>> I'd much rather see a proposal to add a new @available type, something like 
>>> 'warning', that lets you attach an arbitrary warning message to a call 
>>> (which you can kind of do with 'deprecated' except that makes the warning 
>>> message claim the API is deprecated).
>> 
>> As review manager, I generally try to avoid commenting on threads, but I 
>> find this point interesting in a way that, if you don't mind, I'd like to 
>> explore.
>> 
>> Would this attribute not be a form of deprecation?  Certainly it acts to 
>> discourage current and subsequent use, since every such use will evoke a 
>> warning.
>> 
>> Is the word "deprecation" just too strong?  Often we think of deprecated 
>> APIs as being ones with more functional problems, like an inability to 
>> report errors, or semantics that must have seemed like a good idea at the 
>> time.  Here it's just that the API has a name we don't like, and perhaps 
>> "deprecation" feels unnecessarily judgmental.
> 
> What I'm suggesting is that we don't change the API name at all. That's why I 
> don't want to use 'deprecated', because we're not actually deprecating 
> something. I'm just suggesting an alternative way of flagging cases where the 
> user tries to use flatMap but accidentally invokes optional hoisting, and 
> that's by making a new overload of flatMap that works for non-optional 
> (non-sequence) values and warns the user that what they're doing is better 
> done as a map. Using the 'deprecated' attribute for this would be confusing 
> because it would make it sound like flatMap itself is deprecated when it's 
> not.

I see.  Thanks.

John.

> 
>> Also, more practically, it conflates a relatively unimportant suggestion — 
>> that we should call the new method in order to make our code clearer — with 
>> a more serious one — that we should revise our code to stop using a 
>> problematic API.  Yes, the rename has a fix-it, but still: to the extent 
>> that these things demand limited attention from the programmer, that 
>> attention should clearly be focused on the latter set of problems.  Perhaps 
>> that sense of severity is something that an IDE should take into 
>> consideration when reporting problems.
>> 
>> What else would you have in mind for this warning?
> 
> The main use for this warning would be for adding overloads to methods that 
> take optionals in order to catch the cases where people invoke optional 
> hoisting, so we can tell them that there's a better way to handle it if they 
> don't have an optional. flatMap vs map is the obvious example, but I'm sure 
> there are other cases where we can do this too.
> 
> But there are also other once-off uses. For example, in the past I've written 
> a function that should only ever be used for debugging, so I marked it as 
> deprecated with a message saying 'remove this before committing your code'. 
> This warning would have been better done using the new 'warning' attribute 
> instead of as a deprecation notice.
> 
> -Kevin Ballard
> 
>> John.
>> 
>>> With that sort of thing we could then declare
>>> 
>>&g

Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-07 Thread John McCall via swift-evolution

> On Nov 7, 2017, at 6:34 PM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> On Tue, Nov 7, 2017, at 03:23 PM, John McCall via swift-evolution wrote:
>> https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md
>>  
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md>
>> 
>> • What is your evaluation of the proposal?
> 
> This proposal is going to cause an insane amount of code churn. The proposal 
> suggests this overload of flatMap is used "in certain circumstances", but in 
> my experience it's more like 99% of all flatMaps on sequences are to deal 
> with optionals, not to flatten nested sequences.
> 
>> • Is the problem being addressed significant enough to warrant a change to 
>> Swift?
> 
> I don't think so. It's a fairly minor issue, one that really only affects new 
> Swift programmers anyway rather than all users, and it will cause far too 
> much code churn to be worthwhile.
> 
> I'd much rather see a proposal to add a new @available type, something like 
> 'warning', that lets you attach an arbitrary warning message to a call (which 
> you can kind of do with 'deprecated' except that makes the warning message 
> claim the API is deprecated).

As review manager, I generally try to avoid commenting on threads, but I find 
this point interesting in a way that, if you don't mind, I'd like to explore.

Would this attribute not be a form of deprecation?  Certainly it acts to 
discourage current and subsequent use, since every such use will evoke a 
warning.

Is the word "deprecation" just too strong?  Often we think of deprecated APIs 
as being ones with more functional problems, like an inability to report 
errors, or semantics that must have seemed like a good idea at the time.  Here 
it's just that the API has a name we don't like, and perhaps "deprecation" 
feels unnecessarily judgmental.

Also, more practically, it conflates a relatively unimportant suggestion — that 
we should call the new method in order to make our code clearer — with a more 
serious one — that we should revise our code to stop using a problematic API.  
Yes, the rename has a fix-it, but still: to the extent that these things demand 
limited attention from the programmer, that attention should clearly be focused 
on the latter set of problems.  Perhaps that sense of severity is something 
that an IDE should take into consideration when reporting problems.

What else would you have in mind for this warning?

John.

> With that sort of thing we could then declare
> 
> extension Sequence {
> @available(*, warning: "Use map instead")
> func flatMap(_ f: (Element) -> U) -> [U] {
> return map(f)
> }
> }
> 
> And now if someone writes flatMap in a way that invokes optional hoisting, 
> it'll match this overload instead and warn them.
> 
>> • How much effort did you put into your review? A glance, a quick reading, 
>> or an in-depth study?
> 
> A quick reading, and a couple of minutes testing overload behavior with 
> availability attributes (to confirm that we can't simply use 'unavailable' 
> for this).
> 
> -Kevin Ballard
> 
> ___
> 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] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-07 Thread John McCall via swift-evolution
Hello, Swift community!

The review of "SE-0187: Introduce Sequence.filterMap(_:)" begins now and runs 
through November 14th, 2017.  The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0187-introduce-filtermap.md
 


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 me as 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/0187-introduce-filtermap.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 


As always, thank you for contributing to the evolution of Swift.

John McCall
Review Manager
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread John McCall via swift-evolution

> On Oct 31, 2017, at 12:43 AM, Chris Lattner  wrote:
> 
> JohnMC: question for you below.
> 
> On Oct 30, 2017, at 1:25 PM, Douglas Gregor  > wrote:
>>> 
>>> Thinking about the Perl case makes it clear to me that this should not be 
>>> built into the compiler as a monolithic thing.  Perl supports several 
>>> different types (SV/AV/HV) which represent different concepts (scalars, 
>>> arrays, hashes) so baking it all together into one thing would be the wrong 
>>> way to map it.  In fact, the magic we need is pretty small, and seems 
>>> generally useful for other things. Consider a design like this:
>>> 
>>> 
>>> // not magic, things like Int, String and many other conform to this. 
>>> protocol Pythonable {
>>>  init?(_ : PythonObject)
>>>  func toPython() -> PythonObject
>>> }
>> 
>> It’s not magic unless you expect the compiler or runtime to help with 
>> conversion between Int/String/etc. and PythonObject, as with 
>> _ObjectiveCBridgeable.
> 
> Right, as I said above “not magic”.  The conformances would be manually 
> implemented in the Python overlay.  This provides a free implicit conversion 
> from "T -> Pythonable” for the T’s we care about, and a failable init from 
> Python back to Swift types.
> 
>>> // Not magic.
>>> struct PythonObject : /*protocols below*/ {
>>>   var state : UnsafePointer
>>> 
>>>   subscript(_ : Pythonable…) -> PythonObject {
>>> ...
>>>   }
>>> }
>>> 
>>> // Magic, must be on the struct definition.  
>>> // Could alternatively allow custom copy/move/… ctors like C++.
>>> protocol CustomValueWitnessTable {
>>>  static func init(..)
>>>  static func copy(..)
>>>  static func move(..)
>>>  static func destroy(..)
>>> }
>> 
>> Swift’s implementation model supports this. As a surface-level construct 
>> it’s going to be mired in UnsafeMutablePointers, and it’s not at all clear 
>> to me that we want this level of control there. 
> 
> There are two ways to implement it:
> 1) static func’s like the above, which are implemented as UnsafePointer's
> 2) Proper language syntax akin to the C++ “rule of 5”.
> 
> The pro’s and con’s of the first approach:
> 
> pro) full explicit control over what happens
> pro) no other new language features necessary to implement this.  The second 
> approach would need something like ownership to be in place.
> con) injects another avenue of unsafety (though it would be explicit, so it 
> isn’t that bad).  It isn’t obvious to me that approach #2 can be safe, but I 
> haven’t thought about it enough.
> ???) discourages people from using this protocol because of its explicit 
> unsafety.
> 
> I can think of two things that could tip the scale of the discussion:
> 
> a) The big question is whether we *want* the ability to write custom 
> rule-of-5 style behavior for structs, or if we want it to only be used in 
> extreme cases (like bridging interop in this proposal).  If we *want* to 
> support it someday, then adding proper “safe” support is best (if possible).  
> If we don’t *want* people to use it, then making it Unsafe and ugly is a 
> reasonable way to go.
> 
> b) The ownership proposal is likely to add deinit's to structs.  If it also 
> adds explicit move initializers, then it is probably the right thing to add 
> copy initializers also (and thus go with approach #2).  That said,  I’m not 
> sure how the move initializers will be spelled or if that is the likely 
> direction.  If it won’t add these, then it is probably better to go with 
> approach #1.  John, what do you think?

I was hoping not to have to add explicit move/copy initializers, perhaps ever.  
I would suggest one of two things:
  - We could add a Builtin type for these types in Swift.  Because of our 
architecture, this is mostly an IRGen task.
  - We could start working on C++ import.  C++ import is a huge task, but we 
don't really need most of it for this.

John.

> 
>> Presumably, binding to Python is going to require some compiler 
>> effort—defining how it is that Python objects are 
>> initialized/copied/moved/destroyed seems like a reasonable part of that 
>> effort.
> 
> Actually no.  If we add these three proposals, there is no other python (or 
> perl, etc…) specific support needed.  It is all implementable in the overlay.
> 
>>> // Magic, allows anyobject-like member lookup on a type when lookup 
>>> otherwise fails.
>>> protocol DynamicMemberLookupable {
>>>   associatedtype MemberLookupResultType
>>>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
>>> }
>> 
>> AnyObject lookup looks for an actual declaration on any type anywhere. One 
>> could extend that mechanism to, say, return all Python methods and assume 
>> that you can call any Python method with any PythonObject instance. 
>> AnyObject lookup is fairly unprincipled as a language feature, because 
>> there’s no natural scope in which to perform name lookup, and involves hacks 
>> at many levels that don’t always work (e.g., AnyObject lookup… sometimes… 
>> f

Re: [swift-evolution] Making capturing semantics of local

2017-10-28 Thread John McCall via swift-evolution

> On Oct 28, 2017, at 6:05 AM, Johannes Weiß via swift-evolution 
>  wrote:
> 
> Hi Mike,
> 
>> On 27 Oct 2017, at 7:05 pm, Mike Kluev  wrote:
>> 
>> on Date: Fri, 27 Oct 2017 17:52:54 +0100 Johannes Weiß 
>>  wrote:
>> 
>>> On 27 Oct 2017, at 6:27 am, Howard Lovatt via swift-evolution 
>>>  wrote:
>>> 
>>> In terms of recursion you can fiddle it:
>>> 
>>> struct RecursiveClosure {
>>>var c: C! = nil
>>> }
>>> func factorial(_ n: Int) -> Int {
>>>var recursive = RecursiveClosure<(Int) -> Int>()
>>>recursive.c = { x in
>>>(x == 0) ? 1 : x * recursive.c(x - 1)
>>>}
>>>return recursive.c(n)
>>> }
>>> factorial(5) // 120
>> 
>> what a hack and a half :)
>> 
>> sorry, offtopic to the thread but that you can have easier with the 
>> fixed-point combinator (https://en.wikipedia.org/wiki/Fixed-point_combinator)
>> 
>> // the fixed-point combinator
>> func fix(_ f: @escaping ((@escaping (T) -> T) -> (T) -> T)) -> (T) -> T {
>>return { (x: T) in (f(fix(f)))(x) }
>> }
>> 
>> // demo
>> let fact = fix { fact_ in { n in n == 1 ? 1 : n * fact_(n-1) } }
>> for i in 1..<10 {
>>print(fact(i))
>> }
>> 
>> that would be a serious crime against humanity if swift allows this type of 
>> code at all :-)
> 
> the fixed-point combinator and Y combinator are pretty important in 
> functional languages.

They're important in the theory of functional languages.  Anyone seriously 
promoting using the Y combinator in actual programming instead of using the 
language's native recursive-binding features is, frankly, someone you should 
not being taking advice from.

John.

> And the above code works in Swift. The good thing is that you need to write 
> `fix` only once and you can then use it for all closures that need to be 
> recursive.
> 
> 
> -- Johannes
> 
>> 
>> Mike
>> 
> 
> ___
> 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] stack classes

2017-10-27 Thread John McCall via swift-evolution

> On Oct 27, 2017, at 9:27 AM, Mike Kluev via swift-evolution 
>  wrote:
> 
> if it wasn't already discussed here is the preliminary proposal, if it was 
> then my +1 to the feature.
> 
> i propose we have an explicit apparatus to denote classes having stack 
> storage.
> 
> stack class StackObject { // guaranteed to be on stack
> }
> 
> class NonStackObject { // is not guaranteed to be on stack, can be on heap as 
> well
> }
> 
> this is for performance reasons. sometimes what we need is “structs with 
> deinit” and as this is not going to happen the next best thing could be 
> “lightweight” classes. this shall be self obvious, here are few examples:

Move-only struct types will be able to provide deinit.  See the ownership 
manifesto.

John.

> 
> stack class StackObject {
> var variable = 0
> 
> func foo() {
> print(“i am ok to live on stack”)
> }
> }
> 
> stack class BadObject {
> var variable = 0
> 
> func foo() {
> DispatchQueue.main.async {  // error: can’t be a stack class
> self.variable = 1
> }
> }
> }
> 
> class NonStackObject {
> …
> }
> 
> foo() {
> let stackObject = StackObject()
> 
> DispatchQueue.main.async {
> stackObject.foo()  // error: can’t use a stack object in this context
> }
> }
> 
> ___
> 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] Making capturing semantics of local

2017-10-26 Thread John McCall via swift-evolution
> On Oct 26, 2017, at 3:24 PM, David Hart  wrote:
>> On 26 Oct 2017, at 21:16, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Oct 26, 2017, at 2:19 PM, Mike Kluev via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> on Wed, 25 Oct 2017 13:41:40 +0200 David Hart >> <mailto:da...@hartbit.com>> wrote:
>>> 
>>> class A {
>>> func foo() {
>>> func local() {
>>> bar() // error: Call to method ‘bar' in function ‘local' 
>>> requires explicit 'self.' to make capture semantics explicit
>>> }
>>> 
>>> // ...
>>> }
>>> }
>>> 
>>> it's not only about calling "bar"... any variable access will require self. 
>>> which will be quite annoying, especially given the fact that "local" my not 
>>> even be used in an escaping context discussed. (*)
>>> 
>>> i think it is more consistent to prepend local with self if it is used in 
>>> an escaping context:
>> 
>> I think this would be possible, yes.  If nothing else, we could allow the 
>> function to be explicitly declared escaping or non-ecaping to get this rule.
> 
> I don’t see how this makes any sense or be possible:
> 
> * It doesn’t make sense for me because local is not a member function of A.
> * It would cause ambiguity when trying to call another member function with 
> the same name as the local function.

Oh, sorry, I should've actually read the rest of the email instead of leaping 
to conclusions.  I meant that it would make sense to disallow implicit "self." 
in a local function that's used as an escaping function (and by implication, 
allow implicit "self." in a local function that's only used as a non-escaping 
function), not that we should require uses of local functions that capture self 
to explicitly mention that fact at the use site.

John.


> 
>> John.
>> 
>>> 
>>> func foo() {
>>> 
>>> func local() {
>>> bar()  // no self needed here ever
>>> variable = 1   // no self needed here, ever
>>> }
>>> 
>>> func otherLocal() {
>>> print("i am not capturing self")
>>> }
>>> 
>>> DispatchQueue.main.async {
>>> local()// error without self
>>> self.local()   // ok
>>> otherLocal()   // ok without self
>>> }
>>> }
>>> 
>>> (*) interestingly, closures always treat themselves as "escaping", even if 
>>> it's not the case, e.g. even if i only use them in a non-escaping contexts. 
>>> worth to add an explicit attribute to denote non-escaping closures?
>>> 
>>> let closure = @nonescaping {
>>> print("i am not escaping")
>>> variable = 1 // ok without self
>>> }
>>> 
>>> DispatchQueue.main.async(execute: closure) // error, non escaping closure 
>>> passed
>>> 
>>> Mike
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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] Making capturing semantics of local

2017-10-26 Thread John McCall via swift-evolution
> On Oct 26, 2017, at 2:19 PM, Mike Kluev via swift-evolution 
>  wrote:
> on Wed, 25 Oct 2017 13:41:40 +0200 David Hart  > wrote:
> 
> class A {
> func foo() {
> func local() {
> bar() // error: Call to method ‘bar' in function ‘local' requires 
> explicit 'self.' to make capture semantics explicit
> }
> 
> // ...
> }
> }
> 
> it's not only about calling "bar"... any variable access will require self. 
> which will be quite annoying, especially given the fact that "local" my not 
> even be used in an escaping context discussed. (*)
> 
> i think it is more consistent to prepend local with self if it is used in an 
> escaping context:

I think this would be possible, yes.  If nothing else, we could allow the 
function to be explicitly declared escaping or non-ecaping to get this rule.

John.

> 
> func foo() {
> 
> func local() {
> bar()  // no self needed here ever
> variable = 1   // no self needed here, ever
> }
> 
> func otherLocal() {
> print("i am not capturing self")
> }
> 
> DispatchQueue.main.async {
> local()// error without self
> self.local()   // ok
> otherLocal()   // ok without self
> }
> }
> 
> (*) interestingly, closures always treat themselves as "escaping", even if 
> it's not the case, e.g. even if i only use them in a non-escaping contexts. 
> worth to add an explicit attribute to denote non-escaping closures?
> 
> let closure = @nonescaping {
> print("i am not escaping")
> variable = 1 // ok without self
> }
> 
> DispatchQueue.main.async(execute: closure) // error, non escaping closure 
> passed
> 
> Mike
> 
> ___
> 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] Making capturing semantics of local functions explicit

2017-10-25 Thread John McCall via swift-evolution
> On Oct 25, 2017, at 4:21 PM, David Hart  wrote:
>> On 25 Oct 2017, at 19:01, John McCall > > wrote:
>> 
>>> On Oct 25, 2017, at 7:41 AM, David Hart via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> I got bit again by a sneaky memory leak concerning local functions and 
>>> would like to discuss a small language change. I vaguely remember this 
>>> being discussed in the past, but can’t find the thread (if anybody could 
>>> point me to it, I’d appreciate it). Basically, here’s an example of the 
>>> leak:
>>> 
>>> class A {
>>> func foo() {
>>> func local() {
>>> bar()
>>> }
>>> 
>>> methodWithEscapingClosure { [unowned self] _ in
>>> self.bar()
>>> local() // this leaks because local captures self
>>> }
>>> }
>>> 
>>> func bar() {
>>> }
>>> }
>>> 
>>> Its sneaky because local’s capturing of self is not obvious if you’ve 
>>> trained your brain to watch out for calls prefixed with self. I would 
>>> suggest having the compiler force users to make self capturing explicit, 
>>> the same way it does for closures:
>> 
>> I think this is a good idea.  Ideally the proposal would also allow explicit 
>> capture lists in local functions.
> 
> Ideally, yes. But the only sensible syntax I can come up for that seems odd 
> in the context of functions:
> 
> class A {
> func foo() {
> func local() -> Int { [weak self] in
> }
> }
> }
> 
> Don’t you think?

You could leave the "in" off, but it's only a little weird to have it, and the 
inconsistency would probably be worse.

John.

> 
> David.
> 
>> John.
>> 
>>> 
>>> class A {
>>> func foo() {
>>> func local() {
>>> bar() // error: Call to method ‘bar' in function ‘local' 
>>> requires explicit 'self.' to make capture semantics explicit
>>> }
>>> 
>>> // ...
>>> }
>>> }
>>> 
>>> What do you think?
>>> 
>>> David.
>>> 
>>> ___
>>> 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] Making capturing semantics of local functions explicit

2017-10-25 Thread John McCall via swift-evolution
> On Oct 25, 2017, at 7:41 AM, David Hart via swift-evolution 
>  wrote:
> I got bit again by a sneaky memory leak concerning local functions and would 
> like to discuss a small language change. I vaguely remember this being 
> discussed in the past, but can’t find the thread (if anybody could point me 
> to it, I’d appreciate it). Basically, here’s an example of the leak:
> 
> class A {
> func foo() {
> func local() {
> bar()
> }
> 
> methodWithEscapingClosure { [unowned self] _ in
> self.bar()
> local() // this leaks because local captures self
> }
> }
> 
> func bar() {
> }
> }
> 
> Its sneaky because local’s capturing of self is not obvious if you’ve trained 
> your brain to watch out for calls prefixed with self. I would suggest having 
> the compiler force users to make self capturing explicit, the same way it 
> does for closures:

I think this is a good idea.  Ideally the proposal would also allow explicit 
capture lists in local functions.

John.

> 
> class A {
> func foo() {
> func local() {
> bar() // error: Call to method ‘bar' in function ‘local' requires 
> explicit 'self.' to make capture semantics explicit
> }
> 
>   // ...
> }
> }
> 
> What do you think?
> 
> David.
> 
> ___
> 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] superscripts, subscripts, etc.

2017-10-05 Thread John McCall via swift-evolution
> On Oct 5, 2017, at 2:31 AM, Taylor Swift via swift-evolution 
>  wrote:
> not to rain on anyone’s parade here but y’all are aware unicode superscripts 
> don’t even form a complete alphabet right? This kind of syntax would really 
> only work for positive integer literals and I don’t think making a wholesale 
> change to the language like this is worth that.

I agree with this and would add only that making Swift code look like idiomatic 
math notation is a huge problem and will probably never yield satisfactory 
results.  Anyone who's really interested in this would probably be much better 
off writing a source-to-source transformation that started with the 
mathematical markup of their choice and just rewrote it as idiomatically as 
possible.

John.

> 
> On Thu, Oct 5, 2017 at 1:19 AM, Swift via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Going a little further...
> 
> It’s not hard to imagine a situation where the order of a trailing annotation 
> matters. Ie, that X²₃ is a different thing from X₃². (X squared sub 3 ≠ X sub 
> 3 squared)
> 
> So i think you’d want an array of trailing annotations and an array of 
> leading annotations, where an annotation is either a .superscript(U) or a 
> .subscript(V). That way you’d be able to preserve the (potentially) relevant 
> order. 
> 
> Dave
> 
> Sent from my iPhone
> 
> On Oct 5, 2017, at 12:04 AM, John Payne via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
 On Oct 2, 2017, at 10:56 PM, John Payne via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 Chris Lattner wrote:
 
> Just FWIW, IMO, these make sense as operators specifically because they 
> are commonly used by math people as operations that transform the thing 
> they are attached to.  Superscript 2 is a function that squares its 
> operand.  That said, perhaps there are other uses that I’m not aware of 
> which get in the way of the utilitarian interpretation.
 
 But there are SO MANY uses for superscripts, subscripts, and other such 
 annotations, and they are all context specific, just in math, without 
 getting into chemistry, physics, statistics, and so forth.
 
 They’re really more like methods on the object to which they’re attached, 
 or the combination of a method and an argument.  
>>> 
>>> I agree.
>>> 
 Wouldn’t classing them as identifiers lend itself better to this?
>>> 
>>> No, making them an operator is better for this usecase.
>>> 
>>> You want:
>>> 
>>> x²  to parse as “superscript2(x)” - not as an identifier “xsuperscript2” 
>>> which is distinct from x.
>>> 
>>> -Chris
>> 
>> I’m not competent to evaluate the implications of that, but let me just pass 
>> along what makes sense to me.  For all I know it may be a restatement in 
>> different words, or a higher level view which your approach enables, or I 
>> may just have no grasp at all of what’s involved.
>> 
>> For brevity I’ll refer to superscripts, subscripts, etc. as annotations.
>> 
>> An object may have more than one annotation, as with chemical elements which 
>> are usually presented at least with both their atomic number and atomic 
>> weight.  Moreover, in some circumstances it might not be possible to 
>> evaluate the significance of any single annotation without taking one or 
>> more others into account, so it might be important to present them together, 
>> as in a struct or a collection.
>> 
>> Taking them singly, their significance is three part: 1) the type of the 
>> object, 2) the position of the annotation, and 3) the value of the 
>> annotation.
>> 
>> I would parse x² as x.trailingSuperscript(2), or better yet…
>> 
>> where X is the type of x, X.annotations would be a struct, similar to the 
>> following
>> 
>> struct annotations {
>> leadingSuperscript: T?
>> leadingSubscript: U?
>> triailingSuperscript: V?
>> trailingSubscript: W?
>> }
>> 
>> Taking this approach, x² would parse as x.annotations.trailingSuperscript = 
>> 2, and would fail if X made no allowance for trailingSuperscripts.
>> 
>> Annotation values are frequently variables, xⁿ for example, and this is the 
>> main reason it seems reasonable to me to class the value as anything 
>> permitted by the type associated with an annotation in that position for the 
>> overall type in question.
>> 
>> I’ll read any replies with interest, but I don’t think I'll have anything 
>> more to say on this subject myself.
>> 
>> ___
>> 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] Question about async await

2017-09-25 Thread John McCall via swift-evolution
> On Sep 25, 2017, at 3:14 PM, Jean-Daniel via swift-evolution 
>  wrote:
>> Le 25 sept. 2017 à 18:54, Trevör Anne Denise via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>>> 
>>> Le 25 sept. 2017 à 13:33, Trevör ANNE DENISE >> > a écrit :
>>> 
>>> 
>>> Le 25 sept. 2017 à 11:55, Thomas >> > a écrit :
>>> 
 
> On 25 Sep 2017, at 10:23, Trevör Anne Denise via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> 
>> Le 24 sept. 2017 à 12:00, Jean-Daniel > > a écrit :
>> 
>> 
>> 
>>> Le 23 sept. 2017 à 12:23, Trevör Anne Denise via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> 
 Le 20 sept. 2017 à 21:15, Jean-Daniel >>> > a écrit :
 
 
 
> Le 20 sept. 2017 à 08:36, Trevör Anne Denise via swift-evolution 
> mailto:swift-evolution@swift.org>> a 
> écrit :
> 
>> 
>> Le 18 sept. 2017 à 18:07, Pierre Habouzit > > a écrit :
>> 
>> 
>> -Pierre
>> 
>>> On Sep 18, 2017, at 2:04 AM, Trevör Anne Denise 
>>> >> > wrote:
>>> 
 
 Le 18 sept. 2017 à 07:57, Pierre Habouzit >>> > a écrit :
 
> On Sep 17, 2017, at 3:52 AM, Trevör ANNE DENISE via 
> swift-evolution  > wrote:
> 
> Hello everyone,
> 
> I have a few questions about async await in Swift.
> 
> Say that you have :
> 
> func foo() async {
>   print("Hey")
>   await bar()
>   print("How are you ?")
> }
> 
> First of all, am I right to say that :
> 1) If the bar function wasn't an async function, the thread would 
> be blocked until bar returns, at this point print("How are you 
> ?") would be executed and its only after that that the function 
> calling foo() would get back "control"
 
 I don't think you can quite call await without marking foo() as 
 async (?).
>>> 
>>> 
>>> Yes, that's what I meant, case one would call foo() without await 
>>> if it wasn't async.
>>> 
>>> 
 
> 2) Here (with async bar function), if bar() takes some time to 
> execute,
 
 Not quite, `await bar()` is afaict syntactic sugar for:
 
 bar {
 printf("How are you ?");
 }
 
 Where bar used to take a closure before, the compiler is just 
 making it for you. bar itself will be marked async and will handle 
 its asynchronous nature e.g. using dispatch or something else 
 entirely.
 This has nothing to do with "time".
>>> 
>>> 
>>> If it's just syntactic sugar then how does this solve this issue 
>>> mentioned in the concurrency manifesto ?
>>> "Beyond being syntactically inconvenient, completion handlers are 
>>> problematic because their syntax suggests that they will be called 
>>> on the current queue, but that is not always the case. For example, 
>>> one of the top recommendations on Stack Overflow is to implement 
>>> your own custom async operations with code like this (Objective-C 
>>> syntax):"
>> 
>> "where" things run is not addressed by async/await afaict, but 
>> Actors or any library-level usage of it.
>> 
> 
> 
> So since async await don't have any impact on where things are 
> executed, what would happen concretely with this code ?
> 
> func slowFunction(_ input: [Int]) async -> [Int] {
>   var results = [Int]()
>   for element in input {
>   results += [someLongComputation(with: element)]
>   }
>   return results
> }
> 
> beginAsync {
>   await slowFunction(manyElements)
> }
> 
> I didn't specified anything about which queue/thread runs this code, 
> so what would happen ? Would beginAsync block until slowFunction 
> completes ?
> 
 
 If I understand correctly, In real code you are not supposed to call 
 beginAsync.
 It should be wrapped by high level frameworks. GCD may provide a 
 method that take an async lambda as parameter and dispatch it on a the 
 gl

Re: [swift-evolution] Subscripts assignable to closure vars

2017-09-15 Thread John McCall via swift-evolution

> On Sep 15, 2017, at 3:45 PM, Joanna Carter via swift-evolution 
>  wrote:
> 
> Just came across this.
> 
> I want to be able to hold onto the reference to a subscript "method" for 
> later use.
> 
> Assigning the subscript to a var in the init of a type raises a segmentation 
> fault.
> 
> Should this - could this - be allowed?

It really shouldn't be allowed.  I think KeyPaths are the intended language 
solution here.

Please file a bug about the crash, though.

John.

> 
> protocol DataProvider
> {
>  associatedtype ItemType
> 
>  subscript(index: Int) -> ItemType { get }
> }
> 
> struct AnyDataProvider : DataProvider
> {
>  private var _subscript: (Int) -> providerType.ItemType
> 
>  subscript(index: Int) -> providerType.ItemType
>  {
>return _subscript(index)
>  }
> 
>  init(_ base: P) where P.ItemType == providerType.ItemType
>  {
>_subscript = base.subscript
>  }
> }
> 
> Joanna
> 
> --
> Joanna Carter
> Carter Consulting
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


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

2017-09-12 Thread John McCall via swift-evolution

> On Sep 12, 2017, at 2:19 AM, Pierre Habouzit via swift-evolution 
>  wrote:
> 
>> On Sep 11, 2017, at 9:00 PM, Chris Lattner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> On Sep 4, 2017, at 12:18 PM, Pierre Habouzit > > wrote:
>>> Something else I realized, is that this code is fundamentally broken in 
>>> swift:
>>> 
>>> actor func foo()
>>> {
>>> NSLock *lock = NSLock();
>>> lock.lock();
>>> 
>>> let compute = await someCompute(); <--- this will really break `foo` in 
>>> two pieces of code that can execute on two different physical threads.
>>> lock.unlock();
>>> }
>>> 
>>> 
>>> The reason why it is broken is that mutexes (whether it's NSLock, 
>>> pthread_mutex, os_unfair_lock) have to be unlocked from the same thread 
>>> that took it. the await right in the middle here means that we can't 
>>> guarantee it.
>> 
>> Agreed, this is just as broken as:
>> 
>> func foo()
>> {
>> let lock = NSLock()
>> lock.lock()
>> 
>> someCompute {
>>  lock.unlock()
>> }
>> }
>> 
>> and it is just as broken as trying to do the same thing across queues.  
>> Stuff like this, or the use of TLS, is just inherently broken, both with GCD 
>> and with any sensible model underlying actors.  Trying to fix this is not 
>> worth it IMO, it is better to be clear that they are different things and 
>> that (as a programmer) you should *expect* your tasks to run on multiple 
>> kernel threads.
>> 
>> BTW, why are you using a lock in a single threaded context in the first 
>> place??? ;-)
> 
> I don't do locks, I do atomics as a living.
> 
> Joke aside, it's easy to write this bug we should try to have the 
> compiler/analyzer help here for these broken patterns.
> TSD is IMO less of a problem because people using them are aware of their 
> sharp edges. Not so much for locks.

Maybe we could somehow mark a function to cause a warning/error when directly 
using it from an async function.  You'd want to use that on locks, synchronous 
I/O, probably some other things.

Trying to hard-enforce it would pretty quickly turn into a big, annoying 
effects-system problem, where even a program not using async at all would 
suddenly have to mark a ton of functions as "async-unsafe".  I'm not sure this 
problem is worth that level of intrusion for most programmers.  But a soft 
enforcement, maybe an opt-in one like the Clang static analyzer, could do a lot 
to prod people in the right direction.

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


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

2017-09-02 Thread John McCall via swift-evolution

> On Sep 2, 2017, at 3:19 PM, Pierre Habouzit via swift-evolution 
>  wrote:
> 
>> On Sep 2, 2017, at 11:15 AM, Chris Lattner > > wrote:
>> 
>> On Aug 31, 2017, at 7:24 PM, Pierre Habouzit > > wrote:
>>> 
>>> I fail at Finding the initial mail and am quite late to the party of 
>>> commenters, but there are parts I don't undertsand or have questions about.
>>> 
>>> Scalable Runtime
>>> 
>>> [...]
>>> 
>>> The one problem I anticipate with GCD is that it doesn't scale well enough: 
>>> server developers in particular will want to instantiate hundreds of 
>>> thousands of actors in their application, at least one for every incoming 
>>> network connection. The programming model is substantially harmed when you 
>>> have to be afraid of creating too many actors: you have to start 
>>> aggregating logically distinct stuff together to reduce # queues, which 
>>> leads to complexity and loses some of the advantages of data isolation.
>>> 
>>> 
>>> What do you mean by this?
>> 
>> My understanding is that GCD doesn’t currently scale to 1M concurrent queues 
>> / tasks.
> 
> It completely does provided these 1M queues / tasks are organized on several 
> well known independent contexts.
> The place where GCD "fails" at is that if you target your individual serial 
> queues to the global concurrent queues (a.k.a. root queues) which means 
> "please pool, do your job", then yes it doesn't scale, because we take these 
> individual serial queues as proxies for OS threads.
> 
> If however you target these queues to either:
> - new serial queues to segregate your actors per subsystem yourself
> - or some more constrained pool than what the current GCD runtime offers 
> (where we don't create threads to run your work nearly as eagerly)
> 
> Then I don't see why the current implementation of GCD wouldn't scale.

More importantly, the basic interface of GCD doesn't seem to prevent an 
implementation from scaling to fill the resource constraints of a machine.   
The interface to dispatch queues does not imply any substantial persistent 
state besides the task queue itself, and tasks have pretty minimal quiescent 
storage requirements.  Queue-hopping is an unfortunate overhead, but a 
constant-time overhead doesn't really damage scalability and can be addressed 
without a major overhaul of the basic runtime interface.  OS threads can be 
blocked by tasks, but that's not a Dispatch-specific problem, and any solution 
that would fix it in other runtimes would equally fix it in Dispatch.

Now, an arbitrarily-scaling concurrent system is probably a system that's 
destined to eventually become distributed, and there's a strong argument that 
unbounded queues are an architectural mistake in a distributed system: instead, 
every channel of communication should have an opportunity to refuse further 
work, and the entire system should be architected to handle such failures 
gracefully.  But I think that can be implemented reasonably on top of a runtime 
where most local queues are still unbounded and "optimistic".

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


Re: [swift-evolution] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-09-01 Thread John McCall via swift-evolution

> On Sep 1, 2017, at 2:33 PM, David Sweeris  wrote:
> 
> 
>> On Aug 31, 2017, at 6:27 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I would argue that there is a much broader philosophical truth here.  
>> Programming is not, and never can be, a pure exercise in mathematics, and 
>> the concepts necessary for understanding programming are related to but 
>> ultimately different from the concepts necessary for understanding 
>> mathematics.  That is, Dave Sweeris's mathematicians and physicists are 
>> almost certainly misunderstanding their confusion: saying that the syntax is 
>> wrong implies that there could be a syntax that could be right, i.e. a 
>> syntax that would allow them to simply program in pure mathematics.
> 
> I don't think any of them claimed that any particular programming language's 
> syntax was wrong, just that they were confused by it. I only have a 
> clear(ish) recollection of one of them -- the others were too long ago -- and 
> he said something along the lines of "Mathematica is as close as I get to 
> programming because I don't have time to learn how the CS people write 
> things" (and I think his hand was forced WRT learning even just that, because 
> Mathematica was part of a class he was teaching). Anyway, at the time, his 
> sentiment struck me as "not unique", so I'd guess that it tickled a memory of 
> someone(s) expressing somewhat similar views to me before. To be clear, I'm 
> not claiming that view towards programming is common in the general 
> mathematician/physicist population... When I find out someone's an expert in 
> some field in math or physics, I'll probably talk to them about that; 
> programming isn't a subject I'd be likely to raise unless their area of 
> expertise is "Computational Whatever". So not only is my dataset far too 
> small, and merely anecdotal, it also suffers from selection bias.
> 
> Anyway, the point I'm taking my own sweet time getting to is that if Swift's 
> goal is world domination, I think a good place to start with the scientific 
> community could be to let them use the same syntax they learned while 
> spending the better part of decade or more studying. Obviously, Swift already 
> goes a long way towards that goal by allowing custom unicode operators and 
> such, but if you're telling me that getting prettyprint might be 
> in-scope(ish), too...

Pretty-rendering of expressions and/or formula editing ultimately feel like 
editor features to me.  If there's something you'd specifically like from the 
language to assist with that, that's in scope to discuss.  As someone else 
pointed out, a language feature here isn't strictly necessary: existing formula 
editors typically render on-demand from a textual representation of the formula 
instead of storing layout information in the source.  Now, I could imagine an 
editor wanting some way to embed structured rendering hints in the source 
without affecting compilation; that seems like a reasonable feature to request. 
 However, we'd want to make sure it was actually going to be used, which means 
we'd want to be collaborating on it with someone working on an actual editor, 
not just designing it in the abstract; and of course we at Apple would not be 
promising that Xcode would actually adopt any of those hints.

John.

> Well, I still think that in the long run that problem should to be solved by 
> the OS so that whatever data that ends up getting prettyprinted as "x²" will 
> render that same way in every application, even when sent to the console via 
> `print()` or `cout`. In the meantime I won't complain if the first step 
> towards that goal is getting it in the editor, but I worry that such an 
> approach would lead to us creating the 15th standard (https://xkcd.com/927/ 
> <https://xkcd.com/927/>). And it's like my momma always said, "you should be 
> part of the solution, not part of the precipitate".
> 
> - Dave Sweeris

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


Re: [swift-evolution] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-09-01 Thread John McCall via swift-evolution

> On Sep 1, 2017, at 6:04 AM, André “Zephyz” Videla  
> wrote:
> 
>> It's not a group operation, but it is consistent with the concept of scalar 
>> multiplication in a vector space.  
> 
> That is exactly what I am suggesting: Have a dedicated scalar multiplication 
> operator.
> 
> I think there is a misunderstanding here, I do not think that anyone here 
> wants to write Swift like they write mathematical proofs. The link with 
> operators and mathematics is that mathematics makes heavy use of “notation 
> abuse” where everything has a special notation and a lot of those notation 
> are confusing, inconsistent and conflict with other notation. And infix (and 
> mixifx) operators allow some form of abuse.
> 
> I cannot talk for Dave Sweeris’s mathematician and physicists, but I can give 
> you an example where users have no mathematical expectations but still expect 
> some consistency in notation: Children learning programming.
> 
> Whenever you explain that you can use operators on your keyboard to do simple 
> things like “adding two numbers together with +” and “combining two strings 
> with +” you will often find students that ask “does that mean we can add 
> together strings of text?” or “I do not understand why “3” + “4” is “34” and 
> not “7”. My proposition to alleviate this problem woud make “3” + “4” a type 
> error (since strings are not a commutative monoid)

Floating-point addition isn't associative, and integer addition as we define it 
in Swift isn't even total.

Anyway, we're not going to re-syntax string concatenation in the 5th major 
release of the language.  If you want to use a different operator for it, you 
are welcome to define one in your own code, as well as to ask for ways to hide 
the one from the standard library.

John.

> On 1 Sep 2017, at 03:27, John McCall  > wrote:
> 
>>> On Aug 31, 2017, at 8:51 PM, André “Zephyz” Videla via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
 these versions of the math operators don't quite work the same way as the 
 standard ones (e.g. `+` can throw), but they still carry math semantics 
>>> 
>>> 
>>> That is exactly what I argue should be avoided. When you see `+` you don’t 
>>> expect it to throw. What’s more they don’t carry “math” semantics at all 
>>> because for example
>>> 
>>> Func * (Double, Measurement) -> Measurement is not even associative.
>> 
>> People sometimes forget that mathematical notations are in fact human 
>> languages, which is it say that they're heavily ambiguous and contextual; 
>> there are plenty of texts where you see things like S_ij and it's simply 
>> understood that i and j are in fact independent indices into the family S.  
>> You could undoubtedly design a parser that understood that sort of rule, but 
>> would it ultimately parse a reasonable programming language?  I don't think 
>> so.
>> 
>> I would argue that there is a much broader philosophical truth here.  
>> Programming is not, and never can be, a pure exercise in mathematics, and 
>> the concepts necessary for understanding programming are related to but 
>> ultimately different from the concepts necessary for understanding 
>> mathematics.  That is, Dave Sweeris's mathematicians and physicists are 
>> almost certainly misunderstanding their confusion: saying that the syntax is 
>> wrong implies that there could be a syntax that could be right, i.e. a 
>> syntax that would allow them to simply program in pure mathematics.  That is 
>> a misapprehension just as deep as the belief that there could be a 
>> programming language that would allow one to simply program in 
>> conversational English or Korean.  Even the ability to extract code from a 
>> proof assistant like Coq or Agda — and writing a proof in Coq or Agda is 
>> pretty far from the daily grind of most mathematicians — doesn't belie this, 
>> because ultimately the exact code extracted matters to a programmer in a way 
>> that the exact form of a known-valid proof does not matter to a 
>> mathematician.
>> 
>> John.
>> 
>>> I agree that operators for this kind of functions should exist and are the 
>>> right syntactic tool. But I disagree with the current implementation. My 
>>> proposition for the example of `*` is as follow:
>>> 
>>> This signature happens quite often `(Number, T) -> T`. It would seem quite 
>>> intuitive to have a dedicated operator for all “Scalar multiplication” 
>>> which would be visually distinct from `*` (for example **, or Unicode ⊗) 
>>> and consistent across codebases. 
>>> 
>>> For a + operator that throws, I would imagine a “TryAddable” protocol with 
>>> a `+!` operator which can throw. I agree that it is visual noise, but I 
>>> argue that it has tremendous value: consistant operator semantics.
>>> 
 (Also, I really doubt changing concatenation to `++` is going to fly. 
 Swift is not Haskell.)
>>> I doubt those remarks are very constructive. The point still stands: I find 
>>> value in havi

Re: [swift-evolution] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-08-31 Thread John McCall via swift-evolution
> On Aug 31, 2017, at 8:51 PM, André “Zephyz” Videla via swift-evolution 
>  wrote:
>> these versions of the math operators don't quite work the same way as the 
>> standard ones (e.g. `+` can throw), but they still carry math semantics 
> 
> 
> That is exactly what I argue should be avoided. When you see `+` you don’t 
> expect it to throw. What’s more they don’t carry “math” semantics at all 
> because for example
> 
> Func * (Double, Measurement) -> Measurement is not even associative.

It's not a group operation, but it is consistent with the concept of scalar 
multiplication in a vector space.  People sometimes forget that mathematical 
notations are in fact human languages, which is it say that they're heavily 
ambiguous and contextual; there are plenty of texts where you see things like 
S_ij and it's simply understood that i and j are in fact independent indices 
into the family S.  You could undoubtedly design a parser that understood that 
sort of rule, but would it ultimately parse a reasonable programming language?  
I don't think so.

I would argue that there is a much broader philosophical truth here.  
Programming is not, and never can be, a pure exercise in mathematics, and the 
concepts necessary for understanding programming are related to but ultimately 
different from the concepts necessary for understanding mathematics.  That is, 
Dave Sweeris's mathematicians and physicists are almost certainly 
misunderstanding their confusion: saying that the syntax is wrong implies that 
there could be a syntax that could be right, i.e. a syntax that would allow 
them to simply program in pure mathematics.  That is a misapprehension just as 
deep as the belief that there could be a programming language that would allow 
one to simply program in conversational English or Korean.  Even the ability to 
extract code from a proof assistant like Coq or Agda — and writing a proof in 
Coq or Agda is pretty far from the daily grind of most mathematicians — doesn't 
belie this, because ultimately the exact code extracted matters to a programmer 
in a way that the exact form of a known-valid proof does not matter to a 
mathematician.

John.

> I agree that operators for this kind of functions should exist and are the 
> right syntactic tool. But I disagree with the current implementation. My 
> proposition for the example of `*` is as follow:
> 
> This signature happens quite often `(Number, T) -> T`. It would seem quite 
> intuitive to have a dedicated operator for all “Scalar multiplication” which 
> would be visually distinct from `*` (for example **, or Unicode ⊗) and 
> consistent across codebases. 
> 
> For a + operator that throws, I would imagine a “TryAddable” protocol with a 
> `+!` operator which can throw. I agree that it is visual noise, but I argue 
> that it has tremendous value: consistant operator semantics.
> 
>> (Also, I really doubt changing concatenation to `++` is going to fly. Swift 
>> is not Haskell.)
> I doubt those remarks are very constructive. The point still stands: I find 
> value in having different operators for different semantics.
> 
> On 1 Sep 2017, at 01:54, Brent Royal-Gordon  > wrote:
> 
>>> On Aug 31, 2017, at 3:40 PM, André Videla via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Something I could imagine is deprecate operator overloading and constrain 
>>> them to a single Type. For example, the operator `+` could be constrained 
>>> to the protocol `Addable` and has the signature `infix func + (Self, Self) 
>>> -> Self` and is commutative. Similarly, we could have a protocol 
>>> `Concatenable` which has its own operator (e.g.: ++ ) and is not 
>>> commutative.
>> 
>> 
>> These are basically "bag of syntax protocols" which aren't really usable 
>> generically, so we don't want this design. And if you tied this to the 
>> numeric protocols, then you couldn't use `+` for things that are numeric-ish 
>> but don't quite fit the protocols. For instance, I have a library that adds 
>> `+` and `*` operators to `Foundation.Measurement`; these versions of the 
>> math operators don't quite work the same way as the standard ones (e.g. `+` 
>> can throw), but they still carry math semantics and so `+` is the right 
>> operator for them. If `+` was exclusively tied to a particular protocol with 
>> a particular signature, I wouldn't be able to do that.
>> 
>> (Also, I really doubt changing concatenation to `++` is going to fly. Swift 
>> is not Haskell.)
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
> ___
> 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] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-08-31 Thread John McCall via swift-evolution
> On Aug 31, 2017, at 3:16 PM, Taylor Swift via swift-evolution 
>  wrote:
> Where is the source for this number? XCode is not even available for Linux. 
> And XCode’s market share is only shrinking as Swift expands more into the 
> open source world. To make Swift depend on proprietary XCode features would 
> nullify all of the work that has been done in the past 2 years to bring Swift 
> to Linux platforms.
> 
> On Thu, Aug 31, 2017 at 12:44 PM, John Pratt  > wrote:
> XCode is not just one of many editors to edit Swift you asshole.

John, this sort of personal attack is not acceptable behavior in the Swift 
community, and sending it privately does not alter that.  If you would like to 
continue participating in this community, please learn to treat your fellow 
contributors with respect.

I don't think this thread is entirely off-topic.  While Swift as a language is 
committed to allowing code to be edited in a simple text editor, we also 
recognize the importance of graphical programming environments, and we are 
certainly open to adding features that primarily benefit them — as we did with 
color and resource literals.  Of course, it would necessary to show that the 
language feature was both necessary and likely to see significant editor 
adoption.  At least some of these ideas, like rendering a power operator with a 
superscript, do seem like they could implemented in an editor without any 
language support.

John.

> 
> 
> 
>> On Aug 31, 2017, at 11:27 AM, Taylor Swift > > wrote:
>> 
>> If you ask me this thread is off topic and belongs on an Apple issue tracker 
>> or forum. XCode is just one of many editors used to edit Swift code, and it 
>> should by no means be used as a baseline for language design considering it 
>> is closed source and only available on one platform, compared to a large 
>> number of great open source editors.
>> 
>> On Thu, Aug 31, 2017 at 7:53 AM, Jonathan Hull via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> A few thoughts:
>> 
>> 1) I would like to see Xcode gain a couple more literal types using the same 
>> strategy it does for Image and Color literals
>> 
>> 2) I would LOVE to see simple equation typesetting in Xcode
>> 
>> (Those two are mostly up to the Xcode team as opposed to swift, I suppose)
>> 
>> 3) Why are we pretending like we can always edit swift in a ASCII editor?  
>> The argument that actually using unicode would break things doesn’t seem 
>> valid, because Swift has supported unicode since version 1, and people have 
>> been using it since that time to name both variables and operators. That 
>> doesn’t mean we need a super fancy editor, but I think requiring unicode 
>> awareness is completely reasonable.  If your editor from the 1970’s breaks 
>> something, it is both your and your editor’s fault, not the code or the 
>> library, because Swift has unicode in it’s spec.
>> 
>> 4) I don’t think we should let the difficulty of typing certain things stop 
>> us.  It is an issue we need to consider, but it is an issue which can be 
>> solved fairly easily with good UI design if there is a need. Sure, different 
>> editors might solve it in different ways, but they will all solve it if it 
>> is useful (and in a few years, we will have all settled on the best 
>> approach).  As people have mentioned, it can be difficult to type ‘{‘ on 
>> certain language layouts, so if we limited ourselves by that we couldn’t do 
>> anything.  We shouldn’t adopt a lowest common denominator approach.
>> 
>> 5) The lack of ‘≤’ has driven me absolutely nuts since Swift 1. It won’t be 
>> confusing if we let people do either ‘<=‘ or ‘≤’ (there is research by Apple 
>> in the late 80’s that proves this).  We all learned the symbol in math 
>> class. Even non-programmers know what it means.  Assigning it any other 
>> meaning would be confusing because it’s meaning is so widely known.  Every 
>> time I bring this up, I am told to just roll my own (which I have)… but it 
>> means that my code will now clash with everyone else’s identical 
>> implementation (because there is only one sane way to implement it).  The 
>> fact that there are multiple identical implementations interfering with each 
>> other (and no real way to make a significantly different implementation) 
>> tells me it really should be part of swift itself. Every time I bring it up, 
>> people complain about it being extended ASCII instead of pure ASCII, and 
>> that it is hard to type on a German keyboard (those people can either just 
>> type ‘<=‘ or use a better editor which autocompletes ‘<=‘ to ‘≤’).
>> 
>> 6) My recommendations for typing symbols would be:
>>  a) Choose a subset of useful and well-known symbols instead of every 
>> symbol
>>  b) Allow autocomplete on those symbols by name
>>  c) Optionally choose a little-used guardian character to start the 
>> names of symbols (to avoid accidental autocompletion). 
>> 

Re: [swift-evolution] Retain cycles in closures

2017-08-30 Thread John McCall via swift-evolution

> On Aug 30, 2017, at 7:02 PM, Yvo van Beek  wrote:
> 
> Hi John,
> 
> I see that I've used DispatchQueue.main in my example which is probably a 
> poor choice to demonstrate the issue:
> 
>   class MyClass {
> let queue = DispatchQueue(label: "MyApp.MyQueue")
> 
> func start() {
>   queue.async {
> otherClass.doSomethingThatTakesAWhile()
>   }
> 
>   ...
> 
>   queue.async {
> self.doSomething()
>   }
> }
>   }
> 
> This would create a retain cycle wouldn't it?

You're correct that there's a temporary cycle which lasts until the queue 
executes the closure.  However, temporary cycles like this rarely cause memory 
leaks for the same reason that local variables rarely cause memory leaks: 
eventually the closure will be executed or the function will return.  The only 
way that a closure on a dispatch queue can cause a memory leak is if it 
constantly enqueues new closures that recreate the same cycle.

If you're doing a dispatch with a very substantial delay (in the hundreds of 
milliseconds), it can still be a good idea to use a weak reference just so 
objects can be collected faster.  But it's not strictly necessary just to avoid 
leaks.

John.

> 
> - Yvo
> 
> 
> On Wed, Aug 30, 2017 at 6:48 PM, John McCall  > wrote:
> 
>> On Aug 30, 2017, at 6:45 PM, Yvo van Beek via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> When I'm writing code I like it to be free from any distractions that aren't 
>> really relevant to the problem that I'm trying to solve. One of these 
>> distractions is having to pay a lot of attention to retain cycles. As my 
>> code grows, I start making extensions to simplify my code.
>> 
>> I've created the following helper for DispatchQueues:
>> 
>>   extension DispatchQueue {
>> func async(weak arg: T, execute: @escaping (T) -> Void) {
>>   async { [weak arg] in
>> if let argRef = arg { execute(argRef) }
>>   }
>> }
>>   }
>> 
>> It allows you to do this:
>> 
>>DispatchQueue.main.async(weak: self) { me in
>> me.updateSomePartOfUI()
>>   }
>> 
> 
> Closures handed off to dispatch queues will not cause retain cycles.
> 
> John.
> 
>> When functions are passed as a closure, the compiler won't warn about a 
>> possible retain cycle (there is no need to prefix with self). That's why 
>> I've also created helpers for calling instance functions:
>> 
>> func blockFor(_ target: Target, method: @escaping 
>> (Target) -> () -> Void) -> () -> Void {
>> return { [weak target] in
>>   if let targetRef = target { method(targetRef)() }
>> }
>>   }
>> 
>>   func blockFor(_ target: Target, method: @escaping 
>> (Target) -> (Args) -> Void, args: Args) -> () -> Void {
>> return { [weak target] in
>>   if let targetRef = target { method(targetRef)(args) }
>> }
>>   }
>> 
>> Calls look like this:
>> 
>>   class MyClass {
>> func start() {
>>   performAction(completion: blockFor(self, method: MyClass.done))
>> }
>> 
>> func done() {
>>   ...
>> }
>>   }
>> 
>> When you look at code samples online or when I'm reviewing code of 
>> colleagues this seems a real issue. A lot of people probably aren't aware of 
>> the vast amounts of memory that will never be released (until their apps 
>> start crashing). I see people just adding self. to silence the complier :(
>> 
>> I'm wondering what can be done to make this easier for developers. Maybe 
>> introduce a 'guard' keyword for closures which skips the whole closure if 
>> the instances aren't around anymore. Since guard is a new keyword in this 
>> context it shouldn't break any code?
>> 
>>DispatchQueue.main.async { [guard self] in
>> self.updateSomePartOfUI()
>>   }
>> 
>> I don't have any ideas yet for a better way to pass functions as closures.
>> 
>> - Yvo
>> ___
>> 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] Retain cycles in closures

2017-08-30 Thread John McCall via swift-evolution

> On Aug 30, 2017, at 6:45 PM, Yvo van Beek via swift-evolution 
>  wrote:
> 
> When I'm writing code I like it to be free from any distractions that aren't 
> really relevant to the problem that I'm trying to solve. One of these 
> distractions is having to pay a lot of attention to retain cycles. As my code 
> grows, I start making extensions to simplify my code.
> 
> I've created the following helper for DispatchQueues:
> 
>   extension DispatchQueue {
> func async(weak arg: T, execute: @escaping (T) -> Void) {
>   async { [weak arg] in
> if let argRef = arg { execute(argRef) }
>   }
> }
>   }
> 
> It allows you to do this:
> 
>DispatchQueue.main.async(weak: self) { me in
> me.updateSomePartOfUI()
>   }
> 

Closures handed off to dispatch queues will not cause retain cycles.

John.

> When functions are passed as a closure, the compiler won't warn about a 
> possible retain cycle (there is no need to prefix with self). That's why I've 
> also created helpers for calling instance functions:
> 
> func blockFor(_ target: Target, method: @escaping 
> (Target) -> () -> Void) -> () -> Void {
> return { [weak target] in
>   if let targetRef = target { method(targetRef)() }
> }
>   }
> 
>   func blockFor(_ target: Target, method: @escaping 
> (Target) -> (Args) -> Void, args: Args) -> () -> Void {
> return { [weak target] in
>   if let targetRef = target { method(targetRef)(args) }
> }
>   }
> 
> Calls look like this:
> 
>   class MyClass {
> func start() {
>   performAction(completion: blockFor(self, method: MyClass.done))
> }
> 
> func done() {
>   ...
> }
>   }
> 
> When you look at code samples online or when I'm reviewing code of colleagues 
> this seems a real issue. A lot of people probably aren't aware of the vast 
> amounts of memory that will never be released (until their apps start 
> crashing). I see people just adding self. to silence the complier :(
> 
> I'm wondering what can be done to make this easier for developers. Maybe 
> introduce a 'guard' keyword for closures which skips the whole closure if the 
> instances aren't around anymore. Since guard is a new keyword in this context 
> it shouldn't break any code?
> 
>DispatchQueue.main.async { [guard self] in
> self.updateSomePartOfUI()
>   }
> 
> I don't have any ideas yet for a better way to pass functions as closures.
> 
> - Yvo
> ___
> 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] typed throws

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

Them's fighting words. :)

John.

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

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


Re: [swift-evolution] [Concurrency] do async

2017-08-23 Thread John McCall via swift-evolution

> On Aug 23, 2017, at 1:16 PM, Joe Groff via swift-evolution 
>  wrote:
> 
>> 
>> On Aug 21, 2017, at 11:23 PM, Jonathan Hull via swift-evolution 
>>  wrote:
>> 
>> I have seen a lot of examples which use both do and beginAsync:
>> 
>>  beginAsync {
>>  do {
>>  try await foo()
>>  } catch let e {
>>  //Handle Error
>>  }
>>  }
>> 
>> I twitch every time I see this, because I thought part of the point of this 
>> was to avoid pyramiding.  It would seem to be an argument for combining try 
>> and await, but as others have pointed out, that causes issues with try? and 
>> try!.  I also really like the explicitness of knowing what could actually 
>> throw errors.
>> 
>> I propose that we instead combine do and beginAsync.  There are 3 cases:
>> 
>> 
>> 1) Just throws (i.e what we have now):
>> 
>>  do {
>>  try foo()
>>  } catch let e {
>>  //Handle Error
>>  }
>> 
>> 
>> 2) Just async (no catch needed):
>> 
>>  do async {
>>  await foo()
>>  }
>> 
>> 
>> 3) Both throws and async:
>> 
>>  do async {
>>  try await foo()
>>  }catch let e{
>>  //It would be a compiler error not to have a catch statement 
>> when there is a try in the do block.
>>  }
>> 
>> 
>> This feels much less messy to me, and will avoid unnecessary pyramids while 
>> still allowing throws and async to be separately declared.
>> 
>> Thanks,
>> Jon
> 
> The proposal is perhaps a bit beginAsync-heavy because it puts a lot of 
> attention on how to adapt existing frameworks to work with coroutines. My 
> feeling is that, in a system with frameworks that have more fully adopted 
> coroutines in all the appropriate places, that you won't need to explicitly 
> enter an async context as frequently since more contexts will already be 
> `async` where they need to be, and that in the situations where you do need 
> to enter a new async context, raw `beginAsync` won't be the best way to do 
> so. `beginAsync` is still going to begin its coroutine body immediately on 
> the current thread, but you're likely to want to associate it with a specific 
> context using something like a version of dispatch_async that takes a `() 
> async -> ()` block. There are also APIs that could provide for coordination 
> with the coroutine, such as a constructor for Future that takes an () 
> async -> T block which is automatically fulfilled by the completion of the 
> block. I'm not against the idea of providing language sugar to make working 
> with coroutines nicer (that is, after all, their whole reason to exist!), but 
> I'm not sure this is the right thing to sugar, and we can always add sugar 
> later once the core language model is set.

Right.  I would only add to this that I'm specifically worried about adding 
features that make blocking the current thread more sugared.

John.___
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-21 Thread John McCall via swift-evolution

> On Aug 20, 2017, at 3:56 PM, Yuta Koshizawa  wrote:
> 
> 2017-08-21 2:20 GMT+09:00 John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>>:
>> On Aug 19, 2017, at 7:17 PM, Chris Lattner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>>> On Aug 19, 2017, at 8:14 AM, Karim Nassar via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> This looks fantastic. Can’t wait (heh) for async/await to land, and the 
>>> Actors pattern looks really compelling.
>>> 
>>> One thought that occurred to me reading through the section of the 
>>> "async/await" proposal on whether async implies throws:
>>> 
>>> If ‘async' implies ‘throws' and therefore ‘await' implies ‘try’, if we want 
>>> to suppress the catch block with ?/!, does that mean we do it on the 
>>> ‘await’ ? 
>>> 
>>> guard let foo = await? getAFoo() else {  …  }
>> 
>> Interesting question, I’d lean towards “no, we don’t want await? and 
>> await!”.  My sense is that the try? and try! forms are only occasionally 
>> used, and await? implies heavily that the optional behavior has something to 
>> do with the async, not with the try.  I think it would be ok to have to 
>> write “try? await foo()” in the case that you’d want the thrown error to 
>> turn into an optional.  That would be nice and explicit.
> 
> try? and try! are quite common from what I've seen.
> 
> As analogous to `throws` and `try`, I think we have an option that `await!` 
> means blocking.
> 
> First, if we introduce something like `do/catch` for `async/await`, I think 
> it should be for blocking. For example:
> 
> ```
> do {
>   return await foo()
> } block
> ```
> 
> It is consistent with `do/try/catch` because it should allow to return a 
> value from inside `do` blocks for an analogy of `throws/try`.
> 
> ```
> // `throws/try`
> func foo() -> Int {
>   do {
> return try bar()
>   } catch {
> ...
>   }
> }
> 
> // `async/await`
> func foo() -> Int {
>   do {
> return await bar()
>   } block
> }
> ```
> 
> And `try!` is similar to `do/try/catch`.
> 
> ```
> // `try!`
> let x = try! foo()
> // uses `x` here
> 
> // `do/try/catch`
> do {
>   let x = try foo()
>   // uses `x` here
> } catch {
>   fatalError()
> }
> ```
> 
> If `try!` is a sugar of `do/try/catch`, it also seems natural that `await!` 
> is a sugar of `do/await/block`. However, currently all `!` in Swift are 
> related to a logic failure. So I think using `!` for blocking is not so 
> natural in point of view of symbology.
> 
> Anyway, I think it is valuable to think about what `do` blocks for 
> `async/await` mean. It is also interesting that thinking about combinations 
> of `catch` and `block` for `async throws` functions: e.g. If only `block`, 
> the enclosing function should be `throws`.

Personally, I think these sources of confusion are a good reason to keep the 
feature separate.

The idea of using await! to block a thread is interesting but, as you say, does 
not fit with the general meaning of ! for logic errors.  I think it's fine to 
just have an API to block waiting for an async operation, and we can choose the 
name carefully to call out the danger of deadlocks.

John.

> 
> That aside, I think `try!` is not so occasional and is so important. Static 
> typing has limitations. For example, even if we has a text field which allows 
> to input only numbers, we still get an input value as a string and parsing it 
> may fail on its type though it actually never fails. If we did not have easy 
> ways to convert such a simple domain error or a recoverable error to a logic 
> failure, people would start ignoring them as we has seen in Java by 
> `catch(Exception e) {}`. Now we have `JSONDecoder` and we will see much more 
> `try!` for bundled JSON files in apps or generated JSONs by code, for which 
> decoding fails as a logic failure.
> 
> --
> Yuta

___
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-20 Thread John McCall via swift-evolution
> On Aug 19, 2017, at 7:17 PM, Chris Lattner via swift-evolution 
>  wrote:
>> On Aug 19, 2017, at 8:14 AM, Karim Nassar via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> This looks fantastic. Can’t wait (heh) for async/await to land, and the 
>> Actors pattern looks really compelling.
>> 
>> One thought that occurred to me reading through the section of the 
>> "async/await" proposal on whether async implies throws:
>> 
>> If ‘async' implies ‘throws' and therefore ‘await' implies ‘try’, if we want 
>> to suppress the catch block with ?/!, does that mean we do it on the ‘await’ 
>> ? 
>> 
>> guard let foo = await? getAFoo() else {  …  }
> 
> Interesting question, I’d lean towards “no, we don’t want await? and await!”. 
>  My sense is that the try? and try! forms are only occasionally used, and 
> await? implies heavily that the optional behavior has something to do with 
> the async, not with the try.  I think it would be ok to have to write “try? 
> await foo()” in the case that you’d want the thrown error to turn into an 
> optional.  That would be nice and explicit.

try? and try! are quite common from what I've seen.

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


Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 8:13 PM, Jonathan Hull  wrote:
> 
> It is different though.
> 
> Sure, with a little bit of sugar, it can be used to make something that looks 
> a bit like union types, but it should avoid the complexity in the type 
> checker which caused that to be on the rejected list.  In this case 'Int | 
> String' is just sugar for '.int(Int) | .string(String)’, which creates an 
> anonymous enum similar to the actual enum shown below. 
> 
> Without the sugar, it really just is a quick way to build enums.  Without the 
> sugar, it can be used to make something that looks a bit like union types as 
> well, but you just have to type .int(Int) | .string(String).  I can do that 
> with enums right now though:
> 
>   enum myType {
>   case int(Int)
>   case string(String)
>   }
> 
> This is just a shorthand way of quickly doing the above without giving it a 
> name.

I see your point, but I think this is still very solidly in a space that we've 
expressed interest in not pursuing, especially with the long chain of "wouldn't 
it be great" additions you're suggesting.

John.


> 
> 
> 
> 
>> On Aug 18, 2017, at 11:35 AM, John McCall  wrote:
>> 
>>> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>>>  wrote:
>>> The typed throws discussion brought me back to an old thought.
>>> 
>>> I would really like to see a new structural type, similar to tuples, which 
>>> act as an anonymous enum.  These would actually be a distinct type from 
>>> enums (not sure what to call them), in the same way that structs and tuples 
>>> are different.  They would have a very similar syntax to enums though, so 
>>> they would be easy to learn.
>> 
>> This is the commonly-rejected "Disjunctions in type constraints" feature.
>> 
>> John.
>> 
>>> 
>>> There would be two major difference from enums:
>>> 
>>> 1) Because they are structural, they can’t have associated functions or 
>>> extensions
>>> 
>>> 2) They can concatenate with one another freely 
>>> 
>>> For example:
>>> 
>>> func foo( speed: .slow | .med | .fast ){
>>> bar(speed: speed)
>>> }
>>> 
>>> func bar(speed: .slow | .med | .fast | .ludicrous) {
>>> //but we couldn't call foo here because it doesn’t take 
>>> .ludicrous
>>> }
>>> 
>>> Each case is it’s own mini-type in a way.  One ‘.slow’ is equivalent to any 
>>> ‘.slow’ (even one from a regular enum). Essentially, it is a loosely bound 
>>> group of cases, and type checking just means seeing if the list/value being 
>>> passed is a subset of the list of possible cases.
>>> 
>>> I’d also like to see sugar for quick conversion from normal Swift enums:
>>> 
>>> enum Speed {
>>> case slow
>>> case med
>>> case fast
>>> }
>>> 
>>> func foo(speed: Speed | .ludicrous) {
>>> //we can’t call any functions/extensions of Speed, just like we 
>>> can’t call a func from int on (Int, Int) 
>>> }
>>> 
>>> In the above case, Speed gets converted via sugar to “.speed(Speed)” and 
>>> then gets concatenated with .ludicrous. Ideally, it would have the added 
>>> ability to truly convert to ".slow | .med | .fast | .ludicrous” when passed 
>>> to something that doesn’t know about Speed:
>>> 
>>> func foo(speed: Speed | .ludicrous) {
>>> switch speed {
>>> case .speed(let s): //Do something with the Speed value
>>> case .ludicrous: //Do something ludicrous
>>> } 
>>> bar(speed: speed) //This can convert to pass by unwrapping 
>>> Speed to a bag of cases
>>> }
>>> 
>>> func bar(speed: .slow | .med | .fast | .ludicrous) {
>>> switch speed {
>>> case .slow: //
>>> case .med: //
>>> case .fast: //
>>> case .ludicrous: //
>>> }
>>> //We can’t reference Speed above because we just passed a bag 
>>> of potential cases
>>> }
>>> 
>>> 
>>> The end result here is that in addition to building one-off enums quickly, 
>>> it lets us concatenate and extend enums for use in a limited scope.  I 
>>> don’t know about you, but I run into the situation of “I want exactly this 
>>> enum, but with one extra case” all the time.
>>> 
>>> I don’t know if we want typed throws, but this type of quick concatability 
>>> would be very useful for adding/merging potential errors.  With the same 
>>> sugar used on Speed above, it would also allow something similar to Union 
>>> types, but without the most of the implementation headache that would 
>>> cause.  You can take in multiple types, and you get back something you can 
>>> switch on to recover the type which was passed:
>>> 
>>> func myFakeUnion(_ intOrStr: Int | String){
>>> switch intOrStr {
>>> case .int(let i): //Do something with int
>>> case .string(let s): //Do something with string
>>> }
>>> } 
>>> 
>>> myFakeUnion(12) //Sugar!
>

Re: [swift-evolution] typed throws

2017-08-18 Thread John McCall via swift-evolution
> On Aug 19, 2017, at 12:25 AM, John McCall via swift-evolution 
>  wrote:
>> On Aug 18, 2017, at 11:43 PM, Mark Lilback > <mailto:m...@lilback.com>> wrote:
>> 
>>> 
>>> On Aug 18, 2017, at 2:27 AM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Even for non-public code.  The only practical merit of typed throws I have 
>>> ever seen someone demonstrate is that it would let them use contextual 
>>> lookup in a throw or catch.  People always say "I'll be able to 
>>> exhaustively switch over my errors", and then I ask them to show me where 
>>> they want to do that, and they show me something that just logs the error, 
>>> which of course does not require typed throws.  Every.  Single.  Time.
>> 
>> We're doing it in the project I'm working on. Sure, there are some places 
>> where we just log the error. But the vast majority of the time, we're 
>> handling them. Maybe that's because we're using reactive programming and 
>> errors bubble to the top, so there's no need to write that many error 
>> handlers. And if I am just logging, either the error doesn't really matter 
>> or there is a TODO label reminding me to fix it at some point.
> 
> I'm not saying people only log errors instead of handling them in some more 
> reasonable way.  I'm saying that logging functions are the only place I've 
> ever seen someone switch over an entire error type.
> 
> I keep bringing exhaustive switches up because, as soon as you have a default 
> case, it seems to me that you haven't really lost anything vs. starting from 
> an opaque type like Error.
> 
>>> On Aug 18, 2017, at 3:11 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> The primary goal for me personally is to factor out and centralize code 
>>> that categorizes an error, allowing catch sites to focus on implementing 
>>> recovery instead of figuring out what went wrong.  Here’s some concrete 
>>> sample code building on the example scenario above:
>> 
>> I'm using a similar approach. Here is some stripped down code:
>> 
>> //error object used throughout project
>> public struct Rc2Error: LocalizedError, CustomStringConvertible, 
>> CustomDebugStringConvertible {
>>  /// basic categories of errors
>>  public enum Rc2ErrorType: String, Error {
>>  /// a requested object was not found
>>  case noSuchElement
>>  /// a requested operation is already in progress
>>  case alreadyInProgress
>>  /// problem parsing json, Freddy error is nested
>>  case invalidJson
>>  /// nestedError will be the NSError 
>>  case cocoa 
>>  /// nested error is related to the file system 
>>  case file 
>>  /// a wrapped error from a websocket 
>>  case websocket 
>>  /// a generic network error 
>>  case network 
>>  /// an invalid argument was passed (or parsed from json)
>>  /// wraps an unknown error
>>  case unknown
>>  }
>> 
>>  /// the generic type of the error
>>  public let type: Rc2ErrorType
>>  /// the underlying error that caused the problem
>>  public let nestedError: Error?
>>  /// location in source code of where error happened
>>  public let location: String
>> }
> 
> Okay.  I mean, this seems essentially like Swift's Error design.  The comment 
> says you use this type ubiquitously in your project.  The type completely 
> erases any differences between functions in terms of what errors they can 
> throw.  Predictably, it includes an unknown case.  Code that processes values 
> of this type must look essentially exactly like switching over an Error, 
> except that the unknown case involves explicitly matching '.unknown' instead 
> of using 'default'.
> 
>> //a domain-specific error type that will be nested
>> public enum NetworkingError {
>>  case unauthorized
>>  case unsupportedFileType
>>  case timeout
>>  case connectionError(Error)
>>  case canceled
>>  case uploadFailed(Error)
>>  case invalidHttpStatusCode(HTTPURLResponse)
>>  case restError(code: Int, message: String)
>> }
> 
> Okay.  So you're doing semantic tagging of errors — you're communicating out 
> that an error arose d

Re: [swift-evolution] typed throws

2017-08-18 Thread John McCall via swift-evolution

> On Aug 18, 2017, at 11:43 PM, Mark Lilback  wrote:
> 
>> 
>> On Aug 18, 2017, at 2:27 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>> Even for non-public code.  The only practical merit of typed throws I have 
>> ever seen someone demonstrate is that it would let them use contextual 
>> lookup in a throw or catch.  People always say "I'll be able to exhaustively 
>> switch over my errors", and then I ask them to show me where they want to do 
>> that, and they show me something that just logs the error, which of course 
>> does not require typed throws.  Every.  Single.  Time.
> 
> We're doing it in the project I'm working on. Sure, there are some places 
> where we just log the error. But the vast majority of the time, we're 
> handling them. Maybe that's because we're using reactive programming and 
> errors bubble to the top, so there's no need to write that many error 
> handlers. And if I am just logging, either the error doesn't really matter or 
> there is a TODO label reminding me to fix it at some point.

I'm not saying people only log errors instead of handling them in some more 
reasonable way.  I'm saying that logging functions are the only place I've ever 
seen someone switch over an entire error type.

I keep bringing exhaustive switches up because, as soon as you have a default 
case, it seems to me that you haven't really lost anything vs. starting from an 
opaque type like Error.

>> On Aug 18, 2017, at 3:11 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> The primary goal for me personally is to factor out and centralize code that 
>> categorizes an error, allowing catch sites to focus on implementing recovery 
>> instead of figuring out what went wrong.  Here’s some concrete sample code 
>> building on the example scenario above:
> 
> I'm using a similar approach. Here is some stripped down code:
> 
> //error object used throughout project
> public struct Rc2Error: LocalizedError, CustomStringConvertible, 
> CustomDebugStringConvertible {
>   /// basic categories of errors
>   public enum Rc2ErrorType: String, Error {
>   /// a requested object was not found
>   case noSuchElement
>   /// a requested operation is already in progress
>   case alreadyInProgress
>   /// problem parsing json, Freddy error is nested
>   case invalidJson
>   /// nestedError will be the NSError 
>   case cocoa 
>   /// nested error is related to the file system 
>   case file 
>   /// a wrapped error from a websocket 
>   case websocket 
>   /// a generic network error 
>   case network 
>   /// an invalid argument was passed (or parsed from json)
>   /// wraps an unknown error
>   case unknown
>   }
> 
>   /// the generic type of the error
>   public let type: Rc2ErrorType
>   /// the underlying error that caused the problem
>   public let nestedError: Error?
>   /// location in source code of where error happened
>   public let location: String
> }

Okay.  I mean, this seems essentially like Swift's Error design.  The comment 
says you use this type ubiquitously in your project.  The type completely 
erases any differences between functions in terms of what errors they can 
throw.  Predictably, it includes an unknown case.  Code that processes values 
of this type must look essentially exactly like switching over an Error, except 
that the unknown case involves explicitly matching '.unknown' instead of using 
'default'.

> //a domain-specific error type that will be nested
> public enum NetworkingError {
>   case unauthorized
>   case unsupportedFileType
>   case timeout
>   case connectionError(Error)
>   case canceled
>   case uploadFailed(Error)
>   case invalidHttpStatusCode(HTTPURLResponse)
>   case restError(code: Int, message: String)
> }

Okay.  So you're doing semantic tagging of errors — you're communicating out 
that an error arose during a specific operation.  And having some static 
enforcement here makes it easier to ensure that you've tagged all the errors.

> The most common errors don't need a nested error. The call site can figure 
> out how to recover based on this. Using Result I can specifically limit 
> what kind of errors are possible from a function without using the wrapper 
> error. E can always be specified as Error to ignore the typed system.

I see.  So you do have some functions that use a more spec

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

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 3:11 PM, Joe Groff via swift-evolution 
>  wrote:
> 
>> On Aug 18, 2017, at 11:57 AM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> I think that awaiting on the result of an actor method ends up being pretty 
>> similar (in terms of implementation and design tradeoffs) as dispatch_sync.  
>> That said, my understanding is that thread explosion in GCD happens whenever 
>> something blocks a GCD thread, not when it politely yields control back to 
>> GCD.  Am I misunderstanding what you mean.
> 
> dispatch_sync isn't quite the ideal way of thinking about it, since it will 
> block the calling context, and as you note this would potentially deadlock 
> the current thread if an actor invokes one of its own methods.

As well as more perniciously creating deadlock opportunities if there are 
cycles in actors dispatching to each other.  It really has to be a "re-queue 
when there's a response" model.

John.

> This isn't a desirable or fundamentally necessary pitfall, since really, the 
> caller actor is suspending in wait simultaneously with the callee actor 
> taking control. This is more like a "tail-dispatch_async" kind of operation, 
> where you don't really want the calling context to block, but you still want 
> to be able to reuse the current thread since it'll be immediately freed up by 
> blocking on the async operation. That's something we could conceivably build 
> into runtime support for this model.
> 
> -Joe
> ___
> 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] typed throws

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 4:40 AM, Gwendal Roué  wrote:
> Hello all,
> 
> I'm also on the "side" of untyped errors, but I can imagine how other 
> developers may like a stricter error hierarchy. It surely fits some 
> situations.
> 
> Enter Result and Result:
> 
> Since Swift "native" errors don't fit well with asynchronous APIs, various 
> ways to encapsulate them have emerged, most of them eventually relying on 
> some kind of variant of those `Result` type:
> 
>   // Untyped errors
>   enum Result {
>   case success(T)
>   case failure(Error)
>   }
>   
>   // Typed errors
>   enum Result {
>   case success(T)
>   case failure(E)
>   }
> 
> The first Result fits well people who like untyped errors. And Result E> fits people who prefer typed errors. Result is objectively closer to 
> the "spirit" of Swift 2-4. Yet Result has the right to live as well.
> 
> When Swift 5 brings sugar syntax around async/await/etc, most needs for 
> Result will naturally vanish.
> 
> However, the need for Result will remain. The debate about "typed 
> throws", for me, sums up to this question: will the typed folks be able to 
> take profit from the syntax sugar brought by async/await/etc of Swift 5? Or 
> will they have to keep on carrying Result with them?

If I understand correctly, the people really attached to Result often use 
it as a normal result type rather than using the built-in error machinery at 
all.  That is, of course, their right.  If they're doing that, then they can 
have an async function that does that just as well as they can have a non-async 
function.  However, "async" implying "throws" would undermine them to a 
significant extent.

John.

> 
> Gwendal Roué
> 
> 
> 
>> Le 18 août 2017 à 10:23, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>>> On Aug 18, 2017, at 3:28 AM, Charlie Monroe >> <mailto:char...@charliemonroe.net>> wrote:
>>>> On Aug 18, 2017, at 8:27 AM, John McCall via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> On Aug 18, 2017, at 12:58 AM, Chris Lattner via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> Splitting this off into its own thread:
>>>>> 
>>>>>> On Aug 17, 2017, at 7:39 PM, Matthew Johnson >>>>> <mailto:matt...@anandabits.com>> wrote:
>>>>>> One related topic that isn’t discussed is type errors.  Many third party 
>>>>>> libraries use a Result type with typed errors.  Moving to an async / 
>>>>>> await model without also introducing typed errors into Swift would 
>>>>>> require giving up something that is highly valued by many Swift 
>>>>>> developers.  Maybe Swift 5 is the right time to tackle typed errors as 
>>>>>> well.  I would be happy to help with design and drafting a proposal but 
>>>>>> would need collaborators on the implementation side.
>>>>> 
>>>>> Typed throws is something we need to settle one way or the other, and I 
>>>>> agree it would be nice to do that in the Swift 5 cycle.
>>>>> 
>>>>> For the purposes of this sub-discussion, I think there are three kinds of 
>>>>> code to think about: 
>>>>> 1) large scale API like Cocoa which evolve (adding significant 
>>>>> functionality) over the course of many years and can’t break clients. 
>>>>> 2) the public API of shared swiftpm packages, whose lifecycle may rise 
>>>>> and fall - being obsoleted and replaced by better packages if they 
>>>>> encounter a design problem.  
>>>>> 3) internal APIs and applications, which are easy to change because the 
>>>>> implementations and clients of the APIs are owned by the same people.
>>>>> 
>>>>> These each have different sorts of concerns, and we hope that something 
>>>>> can start out as #3 but work its way up the stack gracefully.
>>>>> 
>>>>> Here is where I think things stand on it:
>>>>> - There is consensus that untyped throws is the right thing for a large 
>>>>> scale API like Cocoa.  NSError is effectively proven here.  Even if typed 
>>>>> throws is introduced, Apple is unlikely to adopt it in their APIs for 
>>>>> this reason.
>>>>> - There is consensus that 

Re: [swift-evolution] Fast enums (was: typed throws)

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>  wrote:
> The typed throws discussion brought me back to an old thought.
> 
> I would really like to see a new structural type, similar to tuples, which 
> act as an anonymous enum.  These would actually be a distinct type from enums 
> (not sure what to call them), in the same way that structs and tuples are 
> different.  They would have a very similar syntax to enums though, so they 
> would be easy to learn.

This is the commonly-rejected "Disjunctions in type constraints" feature.

John.

> 
> There would be two major difference from enums:
> 
> 1) Because they are structural, they can’t have associated functions or 
> extensions
> 
> 2) They can concatenate with one another freely 
> 
> For example:
> 
>   func foo( speed: .slow | .med | .fast ){
>   bar(speed: speed)
>   }
> 
>   func bar(speed: .slow | .med | .fast | .ludicrous) {
>   //but we couldn't call foo here because it doesn’t take 
> .ludicrous
>   }
> 
> Each case is it’s own mini-type in a way.  One ‘.slow’ is equivalent to any 
> ‘.slow’ (even one from a regular enum). Essentially, it is a loosely bound 
> group of cases, and type checking just means seeing if the list/value being 
> passed is a subset of the list of possible cases.
> 
> I’d also like to see sugar for quick conversion from normal Swift enums:
> 
>   enum Speed {
>   case slow
>   case med
>   case fast
>   }
> 
>   func foo(speed: Speed | .ludicrous) {
>   //we can’t call any functions/extensions of Speed, just like we 
> can’t call a func from int on (Int, Int) 
>   }
> 
> In the above case, Speed gets converted via sugar to “.speed(Speed)” and then 
> gets concatenated with .ludicrous. Ideally, it would have the added ability 
> to truly convert to ".slow | .med | .fast | .ludicrous” when passed to 
> something that doesn’t know about Speed:
> 
>   func foo(speed: Speed | .ludicrous) {
>   switch speed {
>   case .speed(let s): //Do something with the Speed value
>   case .ludicrous: //Do something ludicrous
>   } 
>   bar(speed: speed) //This can convert to pass by unwrapping 
> Speed to a bag of cases
>   }
> 
>   func bar(speed: .slow | .med | .fast | .ludicrous) {
>   switch speed {
>   case .slow: //
>   case .med: //
>   case .fast: //
>   case .ludicrous: //
>   }
>   //We can’t reference Speed above because we just passed a bag 
> of potential cases
>   }
>   
> 
> The end result here is that in addition to building one-off enums quickly, it 
> lets us concatenate and extend enums for use in a limited scope.  I don’t 
> know about you, but I run into the situation of “I want exactly this enum, 
> but with one extra case” all the time.
> 
> I don’t know if we want typed throws, but this type of quick concatability 
> would be very useful for adding/merging potential errors.  With the same 
> sugar used on Speed above, it would also allow something similar to Union 
> types, but without the most of the implementation headache that would cause.  
> You can take in multiple types, and you get back something you can switch on 
> to recover the type which was passed:
> 
>   func myFakeUnion(_ intOrStr: Int | String){
>   switch intOrStr {
>   case .int(let i): //Do something with int
>   case .string(let s): //Do something with string
>   }
>   } 
> 
>   myFakeUnion(12) //Sugar!
>   myFakeUnion(.string(“Hey”)) //This works too
> 
> 
> Finally, I would love to see the switch equivalent of ‘a ? b : c’ in Swift.  
> I am not sure what the best syntax would be, but it would essentially work a 
> bit like like a dictionary:
> 
>   let mph = speed ? [.slow:10, .med:35, .fast:75]
> 
> 
> Thanks,
> Jon
> 
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] typed throws

2017-08-18 Thread John McCall via swift-evolution

> On Aug 18, 2017, at 10:19 AM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On Aug 18, 2017, at 1:27 AM, John McCall  wrote:
> 
>>> On Aug 18, 2017, at 12:58 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> Splitting this off into its own thread:
>>> 
 On Aug 17, 2017, at 7:39 PM, Matthew Johnson  
 wrote:
 One related topic that isn’t discussed is type errors.  Many third party 
 libraries use a Result type with typed errors.  Moving to an async / await 
 model without also introducing typed errors into Swift would require 
 giving up something that is highly valued by many Swift developers.  Maybe 
 Swift 5 is the right time to tackle typed errors as well.  I would be 
 happy to help with design and drafting a proposal but would need 
 collaborators on the implementation side.
>>> 
>>> Typed throws is something we need to settle one way or the other, and I 
>>> agree it would be nice to do that in the Swift 5 cycle.
>>> 
>>> For the purposes of this sub-discussion, I think there are three kinds of 
>>> code to think about: 
>>> 1) large scale API like Cocoa which evolve (adding significant 
>>> functionality) over the course of many years and can’t break clients. 
>>> 2) the public API of shared swiftpm packages, whose lifecycle may rise and 
>>> fall - being obsoleted and replaced by better packages if they encounter a 
>>> design problem.  
>>> 3) internal APIs and applications, which are easy to change because the 
>>> implementations and clients of the APIs are owned by the same people.
>>> 
>>> These each have different sorts of concerns, and we hope that something can 
>>> start out as #3 but work its way up the stack gracefully.
>>> 
>>> Here is where I think things stand on it:
>>> - There is consensus that untyped throws is the right thing for a large 
>>> scale API like Cocoa.  NSError is effectively proven here.  Even if typed 
>>> throws is introduced, Apple is unlikely to adopt it in their APIs for this 
>>> reason.
>>> - There is consensus that untyped throws is the right default for people to 
>>> reach for for public package (#2).
>>> - There is consensus that Java and other systems that encourage lists of 
>>> throws error types lead to problematic APIs for a variety of reasons.
>>> - There is disagreement about whether internal APIs (#3) should use it.  It 
>>> seems perfect to be able to write exhaustive catches in this situation, 
>>> since everything in knowable. OTOH, this could encourage abuse of error 
>>> handling in cases where you really should return an enum instead of using 
>>> throws.
>>> - Some people are concerned that introducing typed throws would cause 
>>> people to reach for it instead of using untyped throws for public package 
>>> APIs.
>> 
>> Even for non-public code.  The only practical merit of typed throws I have 
>> ever seen someone demonstrate is that it would let them use contextual 
>> lookup in a throw or catch.  People always say "I'll be able to exhaustively 
>> switch over my errors", and then I ask them to show me where they want to do 
>> that, and they show me something that just logs the error, which of course 
>> does not require typed throws.  Every.  Single.  Time.
> 
> I agree that exhaustive switching over errors is something that people are 
> extremely likely to actually want to do.  I also think it's a bit of a red 
> herring.  The value of typed errors is *not* in exhaustive switching.  It is 
> in categorization and verified documentation.
> 
> Here is a concrete example that applies to almost every app.  When you make a 
> network request there are many things that could go wrong to which you may 
> want to respond differently:
> * There might be no network available.  You might recover by updating the UI 
> to indicate that and start monitoring for a reachability change.
> * There might have been a server error that should eventually be resolved 
> (500).  You might update the UI and provide the user the ability to retry.
> * There might have been an unrecoverable server error (404).  You will update 
> the UI.
> * There might have been a low level parsing error (bad JSON, etc).  Recovery 
> is perhaps similar in nature to #2, but the problem is less likely to be 
> resolved quickly so you may not provide a retry option.  You might also want 
> to do something to notify your dev team that the server is returning JSON 
> that can't be parsed.
> * There might have been a higher-level parsing error (converting JSON to 
> model types).  This might be treated the same as bad JSON.  On the other 
> hand, depending on the specifics of the app, you might take an alternate path 
> that only parses the most essential model data in hopes that the problem was 
> somewhere else and this parse will succeed.
> 
> All of this can obviously be accomplished with untyped errors.  That said, 
> using types to categorize errors would significantly improve the clarity of 
> such code.

Recall that we'r

Re: [swift-evolution] typed throws

2017-08-18 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 3:28 AM, Charlie Monroe  wrote:
>> On Aug 18, 2017, at 8:27 AM, John McCall via swift-evolution 
>>  wrote:
>>> On Aug 18, 2017, at 12:58 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> Splitting this off into its own thread:
>>> 
>>>> On Aug 17, 2017, at 7:39 PM, Matthew Johnson  
>>>> wrote:
>>>> One related topic that isn’t discussed is type errors.  Many third party 
>>>> libraries use a Result type with typed errors.  Moving to an async / await 
>>>> model without also introducing typed errors into Swift would require 
>>>> giving up something that is highly valued by many Swift developers.  Maybe 
>>>> Swift 5 is the right time to tackle typed errors as well.  I would be 
>>>> happy to help with design and drafting a proposal but would need 
>>>> collaborators on the implementation side.
>>> 
>>> Typed throws is something we need to settle one way or the other, and I 
>>> agree it would be nice to do that in the Swift 5 cycle.
>>> 
>>> For the purposes of this sub-discussion, I think there are three kinds of 
>>> code to think about: 
>>> 1) large scale API like Cocoa which evolve (adding significant 
>>> functionality) over the course of many years and can’t break clients. 
>>> 2) the public API of shared swiftpm packages, whose lifecycle may rise and 
>>> fall - being obsoleted and replaced by better packages if they encounter a 
>>> design problem.  
>>> 3) internal APIs and applications, which are easy to change because the 
>>> implementations and clients of the APIs are owned by the same people.
>>> 
>>> These each have different sorts of concerns, and we hope that something can 
>>> start out as #3 but work its way up the stack gracefully.
>>> 
>>> Here is where I think things stand on it:
>>> - There is consensus that untyped throws is the right thing for a large 
>>> scale API like Cocoa.  NSError is effectively proven here.  Even if typed 
>>> throws is introduced, Apple is unlikely to adopt it in their APIs for this 
>>> reason.
>>> - There is consensus that untyped throws is the right default for people to 
>>> reach for for public package (#2).
>>> - There is consensus that Java and other systems that encourage lists of 
>>> throws error types lead to problematic APIs for a variety of reasons.
>>> - There is disagreement about whether internal APIs (#3) should use it.  It 
>>> seems perfect to be able to write exhaustive catches in this situation, 
>>> since everything in knowable. OTOH, this could encourage abuse of error 
>>> handling in cases where you really should return an enum instead of using 
>>> throws.
>>> - Some people are concerned that introducing typed throws would cause 
>>> people to reach for it instead of using untyped throws for public package 
>>> APIs.
>> 
>> Even for non-public code.  The only practical merit of typed throws I have 
>> ever seen someone demonstrate is that it would let them use contextual 
>> lookup in a throw or catch.  People always say "I'll be able to exhaustively 
>> switch over my errors", and then I ask them to show me where they want to do 
>> that, and they show me something that just logs the error, which of course 
>> does not require typed throws.  Every.  Single.  Time.
> 
> The issue I see here with non-typed errors is that relying on documentation 
> is very error-prone. I'll give an example where I've used exhaustive error 
> catching (but then again, I was generally the only one using exhaustive enum 
> switches when we discussed those). I've made a simple library for reporting 
> purchases to a server. The report needs to be signed using a certificate and 
> there are some validations to be made.
> 
> This generally divides the errors into three logical areas - initialization 
> (e.g. errors when loading the certificate, etc.), validation (when the 
> document doesn't pass validation) and sending (network error, error response 
> from the server, etc.).
> 
> Instead of using a large error enum, I've split this into three enums. At 
> this point, especially for a newcommer to the code, he may not realize which 
> method can throw which of these error enums.
> 
> I've found that the app can take advantage of knowing what's wrong. For 
> example, if some required information is missing e.g. 
> Validation.subjectNameMissing is thrown. In such case the application can 
> inform the user that nam

Re: [swift-evolution] typed throws

2017-08-18 Thread John McCall via swift-evolution

> On Aug 18, 2017, at 3:24 AM, Tino Heth <2...@gmx.de> wrote:
> 
> 
>> The only practical merit of typed throws I have ever seen someone 
>> demonstrate is that it would let them use contextual lookup in a throw or 
>> catch.  People always say "I'll be able to exhaustively switch over my 
>> errors", and then I ask them to show me where they want to do that, and they 
>> show me something that just logs the error, which of course does not require 
>> typed throws.  Every.  Single.  Time.
> 
> I think the aspect of documentation shouldn't be underestimated:
> People want to know what might go wrong — even if they have only a single 
> reaction to all cases at their disposal.

There's no reason we couldn't do some tooling work to expose emergent 
information about what kinds of errors are thrown by the current implementation 
of a function, and maybe even check that against the current documentation.  
Certainly, it should be possible to document particularly interesting errors 
that a function might throw.  I'm just challenging the idea that this should be 
reflected and enforced in the type system.

> Typed throws could also help to lessen the tight coupling to Objective-C:
> Being forced to declare conformance to a protocol without requirements or 
> even public methods feels very awkward to me.

Error is not about Objective-C interop; we could make the feature work without 
a protocol, and in fact the protocol alone isn't sufficient for what we try to 
do with it.  The protocol's value is mostly communicative, a way of making it 
obvious that a type is meant to be thrown, as well as to verify that you aren't 
accidentally throwing something nonsensical.

It also gives us a hook to add defaulted requirements in a later release.

> In some way, throws are typed already, but there's just one type allowed, and 
> it can't be changed.
> 
> Imho the big problem of the whole topic is the bad experience people had with 
> typed throws in Java; I don't see a problem in adding typed throws and 
> keeping Error as default type to be thrown if nothing else is specified.

The problems people have with typed throws in Java aren't ultimately because of 
some specific failure of Java (although there are certainly ways in which 
Java's design could be better in my opinion).  They pretty much all arise 
directly from conceptual problems with the idea of "restricted" sets of errors.

> If people want to build huge lists of possible errors… why not? As long as 
> I'm still able to write my own throwing functions as today, I'm fine with 
> that.

Language features have to meet a higher bar than "why not?".

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


Re: [swift-evolution] typed throws

2017-08-17 Thread John McCall via swift-evolution
> On Aug 18, 2017, at 12:58 AM, Chris Lattner via swift-evolution 
>  wrote:
> Splitting this off into its own thread:
> 
>> On Aug 17, 2017, at 7:39 PM, Matthew Johnson  wrote:
>> One related topic that isn’t discussed is type errors.  Many third party 
>> libraries use a Result type with typed errors.  Moving to an async / await 
>> model without also introducing typed errors into Swift would require giving 
>> up something that is highly valued by many Swift developers.  Maybe Swift 5 
>> is the right time to tackle typed errors as well.  I would be happy to help 
>> with design and drafting a proposal but would need collaborators on the 
>> implementation side.
> 
> Typed throws is something we need to settle one way or the other, and I agree 
> it would be nice to do that in the Swift 5 cycle.
> 
> For the purposes of this sub-discussion, I think there are three kinds of 
> code to think about: 
> 1) large scale API like Cocoa which evolve (adding significant functionality) 
> over the course of many years and can’t break clients. 
> 2) the public API of shared swiftpm packages, whose lifecycle may rise and 
> fall - being obsoleted and replaced by better packages if they encounter a 
> design problem.  
> 3) internal APIs and applications, which are easy to change because the 
> implementations and clients of the APIs are owned by the same people.
> 
> These each have different sorts of concerns, and we hope that something can 
> start out as #3 but work its way up the stack gracefully.
> 
> Here is where I think things stand on it:
> - There is consensus that untyped throws is the right thing for a large scale 
> API like Cocoa.  NSError is effectively proven here.  Even if typed throws is 
> introduced, Apple is unlikely to adopt it in their APIs for this reason.
> - There is consensus that untyped throws is the right default for people to 
> reach for for public package (#2).
> - There is consensus that Java and other systems that encourage lists of 
> throws error types lead to problematic APIs for a variety of reasons.
> - There is disagreement about whether internal APIs (#3) should use it.  It 
> seems perfect to be able to write exhaustive catches in this situation, since 
> everything in knowable. OTOH, this could encourage abuse of error handling in 
> cases where you really should return an enum instead of using throws.
> - Some people are concerned that introducing typed throws would cause people 
> to reach for it instead of using untyped throws for public package APIs.

Even for non-public code.  The only practical merit of typed throws I have ever 
seen someone demonstrate is that it would let them use contextual lookup in a 
throw or catch.  People always say "I'll be able to exhaustively switch over my 
errors", and then I ask them to show me where they want to do that, and they 
show me something that just logs the error, which of course does not require 
typed throws.  Every.  Single.  Time.

Sometimes we then go on to have a conversation about wrapping errors in other 
error types, and that can be interesting, but now we're talking about adding a 
big, messy feature just to get "safety" guarantees for a fairly minor need.

Programmers often have an instinct to obsess over error taxonomies that is very 
rarely directed at solving any real problem; it is just self-imposed busy-work.

> - Some people think that while it might be useful in some narrow cases, the 
> utility isn’t high enough to justify making the language more complex 
> (complexity that would intrude on the APIs of result types, futures, etc)
> 
> I’m sure there are other points in the discussion that I’m forgetting.
> 
> One thing that I’m personally very concerned about is in the systems 
> programming domain.  Systems code is sort of the classic example of code that 
> is low-level enough and finely specified enough that there are lots of 
> knowable things, including the failure modes.

Here we are using "systems" to mean "embedded systems and kernels".  And 
frankly even a kernel is a large enough system that they don't want to 
exhaustively switch over failures; they just want the static guarantees that go 
along with a constrained error type.

> Beyond expressivity though, our current model involves boxing thrown values 
> into an Error existential, something that forces an implicit memory 
> allocation when the value is large.  Unless this is fixed, I’m very concerned 
> that we’ll end up with a situation where certain kinds of systems code (i.e., 
> that which cares about real time guarantees) will not be able to use error 
> handling at all.  
> 
> JohnMC has some ideas on how to change code generation for ‘throws’ to avoid 
> this problem, but I don’t understand his ideas enough to know if they are 
> practical and likely to happen or not.

Essentially, you give Error a tagged-pointer representation to allow 
payload-less errors on non-generic error types to be allocated globally, and 
then you can (1) tell

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

2017-08-17 Thread John McCall via swift-evolution

> On Aug 17, 2017, at 9:58 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
>> On Aug 17, 2017, at 4:56 PM, Rod Brown > > wrote:
>> 
>> 
>> Hi Chris,
>> 
>> I love what I’ve read so far. I just have one curiosity from my cursory look 
>> over the proposal.
>> 
>> It seems that in transitioning API to an Async Await system, the completion 
>> handler’s type becomes the return type. How would you handle bridging in 
>> Foundation API that already has a return type, eg URLSession returns you 
>> data tasks, and then fires a completion handler. Perhaps I missed something. 
>> I’m sure you could always form a tuple as well, just curious the thoughts on 
>> that.
> 
> Ah, e.g. this one:
> 
> extension URLSession {
> 
> /*
>  * data task convenience methods.  These methods create tasks that
>  * bypass the normal delegate calls for response and data delivery,
>  * and provide a simple cancelable asynchronous interface to receiving
>  * data.  Errors will be returned in the NSURLErrorDomain, 
>  * see .  The delegate, if any, will still be
>  * called for authentication challenges.
>  */
> open func dataTask(with request: URLRequest, completionHandler: @escaping 
> (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask
> }
> 
> Returning a tuple is an option, but probably wouldn’t provide the right 
> semantics.  The URLSessionDataTask is supposed to be available immediately, 
> not just when the completion handler is called.  The most conservative thing 
> to do is to not have the importer change these.  If they should have async 
> semantics, they can be manually handled with an overlay.
> 
> In any case, I wasn’t aware of those APIs, thanks for pointing them out.  I 
> added a mention of this to the proposal!

Arguably these could be converted to return both the formal return value and a 
future.  That would be a rather heroic rule for automatic import, though.

John.

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

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


Re: [swift-evolution] [Accepted] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-16 Thread John McCall via swift-evolution
> On Aug 16, 2017, at 6:35 PM, Rudolf Adamkovič via swift-evolution 
>  wrote:
> 
> This is fantastic news! Any chance of this landing in Swift 4.x instead of 5?

It it likely to be available in 4.1, but not 4.0.

John.

> 
> R+
> 
>> On 17 Aug 2017, at 00:29, Chris Lattner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Proposal Link: 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
>> 
>> The review of SE-0185 “Synthesizing Equatable and Hashable conformance” ran 
>> from August 9…15, 2017. Feedback for the feature was glowingly positive, and 
>> the proposal is accepted.  The core team discussed the concerns raised in 
>> the feedback thread for the proposal.  Here are some rough notes (not 
>> intended to be exhaustive), but it is important to recognize that the 
>> proposal follows the design of the auto-synthesized Codable proposal, and 
>> that many of these same points were discussed when it came up:
>> 
>> - The core team feels that adding compiler magic for this case is reasonable 
>> because it solves an important user need, and doesn’t preclude the 
>> introduction of a more general feature (e.g. like a macro system, or Rust's 
>> ‘deriving’ feature) in the future.  When/if that feature is designed and 
>> built, the compiler magic can be replaced with standard library magic.
>> 
>> - The hash value of a type is not intended to be stable across rebuilds or 
>> other changes to the code.  It is ok to change if fields are reordered, the 
>> standard library changes the hash function, etc.  Tony pointed this out 
>> on-thread, saying:  The stdlib documentation for hashValue states "Hash 
>> values are not guaranteed to be equal across different executions of your 
>> program. Do not save hash values to use during a future execution.”
>> 
>> - The code synthesized is meant to feel like a default implementation that 
>> you’re getting for free from a (constrained) extension on the protocol.  
>> This is why conformance to the protocol itself is all that is required, not 
>> something like “AutoEquatable”.  
>> 
>> Many thanks to Tony Allevato for driving forward this proposal.  The patch 
>> just needs final code review now - I think we’re all looking forward to this 
>> landing, congrats!
>> 
>> Chris Lattner 
>> Review Manager
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] Swift 5: start your engines

2017-08-09 Thread John McCall via swift-evolution
> On Aug 9, 2017, at 8:52 PM, Howard Lovatt via swift-evolution 
>  wrote:
> I am not against these changes, of requiring an implementation, but I am a 
> little nervous. Let me expand.
> 
> I was involved in the Java Coin initiative for community driven changes to 
> Java 7. In that process the implementation barrier was set very high and it 
> effectively meant that only changes from Sun got through, a number of people 
> put considerable effort in only for the proposals to be rejected. I felt the 
> process was in the end a little disingenuous and I think that view was held 
> by many, perhaps tellingly the process has never run again for subsequent 
> Java versions.
> 
> So my cautionary note is that this requirement of implementation requires 
> careful stewardship and in particular there needs to be some means of getting 
> 'in principle' approval before the implementation stage. If done correctly it 
> could work very well.

This seems very sensible to me.  Certainly we would want some way of flushing 
out "in principle" concerns before too much implementation time gets spent.

John.

> 
>   -- Howard.
> 
> On 9 August 2017 at 02:23, Ted Kremenek  > wrote:
> Hi everyone,
> 
> The proposal phase for Swift 4 is now officially over, and the release is now 
> in endgame engineering convergence for an expected release later this year.  
> Swift 4 has turned out to be one of the highest quality, well-rounded 
> releases of Swift, and I am grateful to everyone in the community who made 
> this release come together!
> 
> Now it is time to turn our attention to Swift 5.  I have just posted updates 
> to the README.md file on the swift-evolution repository, which outlines the 
> core themes and focus areas for Swift 5:
> 
>   https://github.com/apple/swift-evolution 
> 
> 
> and a more persistent URL (invariant to future README.md changes):
> 
>   
> https://github.com/apple/swift-evolution/blob/9cc90f33b6659adeaf92355c359e34e6fed73254/README.md
>  
> 
> 
> I am not going to repeat all of that information here, but I wanted to 
> highlight a few important things.
> 
> ## ABI Stability
> 
> First, ABI stability is the center focus of Swift 5 — and we will pivot much 
> of our prioritization of efforts for Swift 5 around it.  With Swift 4, ABI 
> stability was a strong goal.  In Swift 5, it is a *requirement* of the 
> release.  Whatever ABI we have at the end of Swift 5 is the ABI that we will 
> have.  ABI stability is an important inflection point for the maturity of the 
> language, and it cannot be delayed any longer.
> 
> Please note that there is a difference between ABI stability and module 
> stability.   If you are not aware of the difference — which is rather 
> important — please read the first few paragraphs of the ABI stability 
> manifesto:
> 
>   https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md 
> 
> 
> Module stability is a stretch goal for Swift 5, but even without module 
> stability we can still achieve the primary value of ABI stability.
> 
> ##  Other focus areas (including laying the groundwork for concurrency)
> 
> There are several other areas mentioned for Swift 5 which I won’t repeat 
> here, but there is a general theme of refining and broadening out the core 
> ergonomics of the language and standard library.
> 
> One of those that I wanted to highlight is laying the groundwork for 
> concurrency.  It is a non-goal of Swift 5 to roll out a full new concurrency 
> model.  That is simply too large an effort to do alongside ABI stability.  
> However, it is important that we start making progress on discussing the 
> directions for concurrency and laying some of the groundwork.  This may take 
> the form of specific enhancements to the language that get implemented, 
> depending on where the discussions for concurrency lead and how they align 
> with the priorities for delivering ABI stability in Swift 5.
> 
> ## Changes to the language evolution process
> 
> Last, I want to highlight important changes to the evolution process:
> 
>   https://github.com/apple/swift-evolution 
> #evolution-process-for-swift-5 
> 
> 
> With Swift 4, the release period was divided up into “stage 1” and “stage 2” 
> for setting guidelines for the kind of evolution proposals that were in scope 
> for the release.  This was needed to establish focus — especially after the 
> churn we saw during Swift 3 — on some core themes that were aligned with 
> converging the language towards source & ABI stability.  One downside is that 
> “stage 2” opened up discussion for potentially disruptive changes fairly late 
> in the release

Re: [swift-evolution] Swift 5: start your engines

2017-08-09 Thread John McCall via swift-evolution

> On Aug 9, 2017, at 2:30 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Aug 8, 2017, at 3:07 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> 
>> Upfront costs *will* be higher. Not only do you have to believe that a 
>> change is good, you must develop a working group that includes coders to 
>> create a prototype without any guarantee that the change will pass muster. 
>> 
>> Finding those coders and convincing them this will be a great change means 
>> that proposals will naturally skew towards Apple-driven rather than wider 
>> community-driven. However it does not exclude the latter, especially for 
>> passionate proposals that can find the coders to champion them.
> 
> I too think this is probably a positive step. I'd also like to point out a 
> couple things (while reminding you that I am *not* on the core team and speak 
> for nobody but myself):
> 
>   1. Compiler engineering is not magic. It is *especially* not magic when 
> you're largely dealing with syntax and semantics, rather than code 
> generation. I know it's intimidating, because a year ago I was pretty 
> intimidated by it, but it's basically just programming in a large, 
> complicated project with lots of weird speed hacks. And most of the standard 
> library isn't compiler engineering at all—it's just Swift code written with a 
> weird house style that forbids `private` and `fileprivate`. Anybody who knows 
> enough Swift to express an intelligent opinion on its evolution should know 
> enough to do some standard library work.
> 
>   2. We have persistently had too many designs for the available 
> implementers. If we find that this new process overshoots and we now have too 
> many implementers for the available designs, we can change the process again 
> to loosen the "must include an implementation" requirement. (For instance, we 
> might allow simpler testbed or proof-of-concept implementations, like hacky 
> preprocessors or slightly different userspace syntaxes of things that will 
> move into the compiler, when a full implementation would be too difficult to 
> provide ahead of time.)
> 
> I do have some concerns about this process. I'm worried that, unless we 
> really firm up the pre-review process, we'll end up wasting a lot of 
> implementation time on stuff that never actually makes it into the language.

The formal review has always just been a capstone of the real design process, 
i.e. the process of developing the proposal.  Up until now, that capstone has 
been a lot less meaningful than it could be because there's no choice but to 
speculate about the actual effects of the change: whether they'll really be 
able to use it in all the places they think they will, how disruptive a 
potential source break would be, how much performance the feature actually 
gains/loses, etc.  Some amount of speculation is appropriate — we shouldn't 
design just for the code that exists today — but there's no replacement for the 
experience of actually trying to use a feature in code that you're comfortable 
with.

So today we have this basic development process for proposals:
  1. initial proposal development (often semi-private)
  2. presentation to swift-evolution
  3. iterative open proposal development
  4. formal review, goto 3 until confluence
  5. implementation
  6. feedback from implementation experience, goto 3 until confluence
  7. available in a nightly build or official developer preview
  8. feedback from adopters, goto 3 until confluence
  9. ship it

6 and 8 will always be meaningful sources of feedback with a potential to 
provoke a revision.  We can never completely eliminate the potential for such 
feedback to arrive after the formal review, because sometimes use or 
implementation problems only become fully apparent after you've been living 
with the design for a while.  Still, it's somewhat absurd to ask for "final" 
approval for something that hasn't gone through 6 or 8 at all, and we're seeing 
the predictable result, where far too many proposals that are going through 
re-review or requiring follow-up proposals.

The Swift 5 process will hopefully look more like this:
  1. initial proposal development (often semi-private)
  2. presentation to swift-evolution
  3. iterative open proposal development
  5. implementation
  6. feedback from implementation experience, goto 3 until confluence
  7. available for early "adoption" testing as a PR branch, ideally as a 
special toolchain build
  8. feedback from early "adopters", goto 3 until confluence
  "4". formal review, goto 3 until confluence
  9. ship it

Your role as a proposal author really hasn't substantially changed.  It's 
always been the case that getting something through formal review is no 
guarantee that it will ever be implemented, so you've never been able to just 
wash your hands and walk way, and you've always needed to find an implementor.  
The only thing that's different that we're formally recognizing the importance 
of ha

Re: [swift-evolution] How does "Sequence.joined" work?

2017-08-08 Thread John McCall via swift-evolution
> On Aug 8, 2017, at 3:24 PM, Daryle Walker via swift-evolution 
>  wrote:
>> On Aug 8, 2017, at 12:35 AM, Félix Cloutier > > wrote:
>> 
>> All this means is that `joined()` does not create an array that contains the 
>> new result. It's only as magic as the COW semantics on arrays.
> 
> So you’re saying the COW semantics for Array and other standard library types 
> have secret references/pointers that work even for “let”-mode objects, and 
> the Sequence variants the various forms of “joined” need use a 
> Sequence/Collection of those secret references?

Why would .joined() need some sort of special reference instead of just storing 
the collection values as normal values?

John.


> 
>>> Le 7 août 2017 à 21:12, Daryle Walker via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> I was looking at random items at SwiftDoc.org , and 
>>> noticed the “FlattenBidirectionalCollection” structure. It helps implement 
>>> some versions of “joined” from Sequence (probably when the Sequence is also 
>>> a BidirectionalCollection). The directions for the type state that “joined” 
>>> does not create new storage. Then wouldn’t it have to refer to the source 
>>> objects by reference? How; especially how does it work without requiring a 
>>> “&” with “inout” or how it works with “let”-mode objects? Or am I 
>>> misunderstanding how it works behind the covers?
>>> 
>>> (If there is a secret sauce to have one object refer to another without 
>>> “&”/“inout”/“UnsafeWhateverPointer”, I like to know. It may help with 
>>> implementing an idea. The idea involves extending the language, so 
>>> “compiler magic” that the user can’t access is OK; I’d just claim to use 
>>> the same sauce in my proposal.)
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> 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-06 Thread John McCall via swift-evolution
> On Aug 6, 2017, at 11:59 PM, Daryle Walker  wrote:
>> On Aug 1, 2017, at 2:58 PM, John McCall > > wrote:
>> 
>>> 
>>> On Aug 1, 2017, at 9:53 AM, Daryle Walker >> > wrote:
>>> 
 On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan >>> > wrote:
 
 Well, yeah, knowing its size statically is not a requirement, but having a 
 guarantee of in-place allocation is. As long as non-escaped local 
 fixed-size arrays live on the stack, I'm happy. 🙂
>>> 
>>> I was neutral on this, but after waking up I realized a problem. I want to 
>>> use the LLVM type primitives to implement fixed-size arrays. Doing a 
>>> run-time determination of layout and implementing it with alloca forfeits 
>>> that (AFAIK). Unless the Swift run-time library comes with LLVM (which I 
>>> doubt). Which means we do need compile-time constants after all.
>> 
>> We are not going to design the Swift language around the goal of producing 
>> exact LLVM IR sequences.  If you can't phrase this in real terms, it is 
>> irrelevant.
> 
> It isn’t being LLVM-specific, but for any similar system. The instruction 
> generator has certain primitives, like 16-bit integers or 32-bit floats. LLVM 
> (and probably rivals) also has aggregate primitives, heterogenous and 
> homogenous (and the latter as standard and vector-unit). I want to use those 
> primitives when possible. Saving sizing allocations until run-time, after 
> it’s too late for sized-array-specific generated instructions, means that the 
> array is probably implemented with general buffer pointer and length 
> instructions. Any opportunities for IR-level optimization of the types is 
> gone.

> How often do you expect a statically sized array to need said size determined 
> at run-time (with a function) versus a compile-time specification (with an 
> integer literal or “constexpr” expression)? This may enable a 1% solution 
> that anti-optimizes the 99% case.

If the array type is ultimately written with a constant bound, it will reliably 
end up having a constant static size for the same reason that (Either, Float) has a constant static size despite tuples, optionals, and 
Either all being generic types: the compiler automatically does this sort of 
deep substitution when it's computing type layouts.

Now, a generic method on all bounded array types would not know the size of 
'self', for two reasons: it wouldn't know the bound, and it wouldn't know the 
layout of the element type.  But of course we do have optimizations to generate 
specialized implementations of generic functions, and the specialized 
implementation would obviously be able to compute a static size of 'self' 
again.  Moreover, a language design which required bounds to always be constant 
would only help this situation in an essentially trivial way: by outlawing such 
a method from being defined in the first place.

John.

___
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-06 Thread John McCall via swift-evolution

> On Aug 6, 2017, at 11:15 AM, Karl Wagner  wrote:
> 
> 
>> On 4. Aug 2017, at 20:15, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> That's not a concern with the `let` case that Robert brought up, since you 
>>> can't mutate a `let` array at all.
>>> 
>>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>>> Swift array storage is COW, any function that receives the array as a 
>>> parameter is allowed to take a reference on its storage. If the storage 
>>> lives on the stack and that reference outlives the stack frame, you've got 
>>> a problem. It's the same problem that motivated @escaping for closures.
>>> 
>>> You could allow storage to be on the stack by forcing user to make a 
>>> pessimistic copy, which is possibly not an improvement.
>> 
>> Right.  I think maybe the name people keeping using for this feature is 
>> misleading; a better name would be "inline arrays" or "directly-stored 
>> arrays".  Having a fixed size is a necessary condition for storing the array 
>> elements directly, but the people asking for this feature are really asking 
>> for the different representation, not just the ability to statically 
>> constrain the size of an array.
>> 
>> That representation difference comes with a lot of weaknesses and 
>> trade-offs, but it's also useful sometimes.
>> 
>> John.
>> 
> 
> Right, and the question I’ve been asking (indirectly) is: why is this only 
> useful for arrays? Doesn’t it really apply to any value-type which allocates 
> storage which it manages with COW semantics (e.g. Dictionary, Set, Data, your 
> own custom types…)? Really, we want to inform the compiler that the 
> dynamically-allocated memory is part of the value - and if it sees that the 
> storage is only allocated once, it should be allowed to allocate that storage 
> inline with the value, on the stack.

There are absolutely things we could do as part of the Array implementation to 
dynamically avoid heap allocations for temporary arrays.  However, it would be 
very difficult to take advantage of that for arrays stored in temporary structs 
or enums; worse, even if we could, it still wouldn't have the optimal 
representation that people want for mathematical types like vectors and 
matrices.

John.


> 
> As I understand it, the only problem with this is when a function takes such 
> a value as a parameter and assigns it to some escaping reference (an ivar, 
> global, or capturing it inside an escaping closure).
> 
> So why can’t such assignments simply check if the value has inline storage 
> and copy it to the heap if necessary? The compiler should be able to optimise 
> the function so the check (which is really cheap anyway) only needs to happen 
> once per function. Because the entire type has value semantics, we can 
> substitute the original value with the copy for the rest of the function 
> (preventing further copies down the line).
> 
> 
> // Module one
> 
> import ModuleTwo
> 
> func doSomething() {
> 
> let values = (0..<5).map { _ in random() }// allocated inline, since 
> the size can never change
> ModuleTwo.setGlobalItems(values)  // passes a stack-allocated 
> array to the (opaque) function
> }
> 
> // Module two
> 
> var GlobalItems = [Int]()
> var MoreGlobalItems = [Int]()
> 
> func setGlobalItems(_ newItems: [Int]) {
> 
> GlobalItems = newItems  // assignment to escaping reference: 
> checks for inline storage, copies to heap if needed
> 
> // all references to ‘newItems’ from this point refer to the copy known 
> to be on the heap
> 
> MoreGlobalItems = newItems  // we already have a known out-of-line copy 
> of the value; no checks or copying needed
> }
> 
> // To make it more explicit...
> 
> func setGlobalItems_explicit(_ newItems: [Int]) {
> 
> let newItems_heap = newItems.backing.isAllocatedInline ? 
> newItems(withBacking: newItems.backing.clone()) : newItems
> GlobalItems   = newItems_heap
> MoreGlobalItems   = newItems_heap
> }
> 
> 
> This would require some special language support for values that allocate 
> memory which is managed as COW.
> 
> - Karl
> 

___
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-04 Thread John McCall via swift-evolution

> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> That's not a concern with the `let` case that Robert brought up, since you 
> can't mutate a `let` array at all.
> 
> The big thing is that unconstrained escape analysis is uncomputable. Since 
> Swift array storage is COW, any function that receives the array as a 
> parameter is allowed to take a reference on its storage. If the storage lives 
> on the stack and that reference outlives the stack frame, you've got a 
> problem. It's the same problem that motivated @escaping for closures.
> 
> You could allow storage to be on the stack by forcing user to make a 
> pessimistic copy, which is possibly not an improvement.

Right.  I think maybe the name people keeping using for this feature is 
misleading; a better name would be "inline arrays" or "directly-stored arrays". 
 Having a fixed size is a necessary condition for storing the array elements 
directly, but the people asking for this feature are really asking for the 
different representation, not just the ability to statically constrain the size 
of an array.

That representation difference comes with a lot of weaknesses and trade-offs, 
but it's also useful sometimes.

John.



> 
>> Le 4 août 2017 à 09:21, Taylor Swift via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>> No, that doesn’t work. In many cases you want to mutate the elements of the 
>> array without changing its size. For example, a Camera struct which contains 
>> a matrix buffer, and some of the matrices get updated on each frame that the 
>> camera moves. The matrix buffer also stores all of the camera’s stored 
>> properties, so what would be conceptually stored properties are actually 
>> computed properties that get and set a Float at an offset into the buffer. 
>> Of course this could all be avoided if we had fixed layout guarantees in the 
>> language, and then the Camera struct could be the matrix buffer and dispense 
>> with the getters and setters instead of managing a heap buffer.
>> 
>> On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> So, I’m getting into this thread kind of late, and I’ve only skimmed most of 
>> it, but…
>> 
>> A special FSA on the stack seems like the wrong direction. Wouldn’t it make 
>> more sense to have *all* value types that don’t change in size — including 
>> `let` Arrays — live on the stack? In which case, FSA would merely act like a 
>> normal `let` Array, without RangeReplaceableCollection conformance, whose 
>> elements could be changed via subscripting. I know nothing about the 
>> underlying implementation details of Swift, so I may be way off base here.
>> 
>>> On Aug 4, 2017, at 2:18 AM, David Hart >> > wrote:
>>> 
>>> Don’t small arrays live on the stack?
>>> 
 On 4 Aug 2017, at 06:35, Félix Cloutier via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 As far as I can tell, currently, all arrays live on the heap.
 
> Le 3 août 2017 à 19:03, Robert Bennett via swift-evolution 
> mailto:swift-evolution@swift.org>> a écrit :
> 
> Where do constant Arrays currently live? I hope the answer is on the 
> stack, since their size doesn’t change.
> 
> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>> 
>> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
 
 The root cause, of course, is that the VLAs require new stack 
 allocations each time, and the stack is only deallocated as one lump 
 when the frame ends.
>>> 
>>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go 
>>> out of scope.
>>> 
>> 
>> Learned something today.
>> 
>> Anyway, if the goal is stack allocation, I would prefer that we explored 
>> other ways to achieve it before jumping to a new array-type. I’m not 
>> really a fan of a future where [3; Double] is one type and (Double, 
>> Double, Double) is something else, and Array is yet another 
>> thing.
>> 
>> They are completely different things. 
>> 
>> [3; Double] is three contiguous Doubles which may or may not live on the 
>> stack. 
>> 
>> (Double, Double, Double) is three Doubles bound to a single variable 
>> name, which the compiler can rearrange for optimal performance and may 
>> or may not live on the stack. 
>> 
>> Array is an vector of Doubles that can dynamically grow and 
>> always lives in the heap.
>>  
>> 
>> From what I’ve read so far, the problem with stack-allocating some Array 
>> that you can pass to another function and which otherwise does not 
>> escape, is that the function may make an escaping reference (e.g. 
>> assigning it to an 

Re: [swift-evolution] [Pitch] New Version of Array Proposal

2017-08-02 Thread John McCall via swift-evolution
> On Aug 3, 2017, at 12:45 AM, Daryle Walker  wrote:
>> On Aug 2, 2017, at 4:44 PM, Karl Wagner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I’m -1 on adding a fixed-sized Array type.
>> 
>> It goes back to something which I remember reading from John McCall earlier 
>> this week but can’t find any more: about tuple indices being nominal and not 
>> ordinal. How do fixed-size Arrays differ? Are their indexes truly not 
>> nominal?
> 
> I think he meant that the numbered names for tuple members were originally 
> (?) there because the Swift authors didn’t mandate each member needing a 
> label, so there needed some way to refer to unnamed members. Note that 
> numbered names are not true integer variables, not even useable as such. 
> Array indexes are programmable objects; algorithms on the indexes is how we 
> select array subsets to apply algorithms on.

Yes, essentially.  I was making this argument on a slightly higher level, just 
thinking about the meaning of values separate from any syntax.

A fixed-sized array is still fundamentally an array: it's a sequence of 
homogenous elements, where relative positions generally have some level of 
meaning.  In an array like [A,B,C,D], it's probably *significant* that A comes 
first and that C comes before D.  On some level, if it wasn't true that the 
order was significant, it wouldn't "really" be an array, it would be a set (or 
multiset) being represented using an array.

In contrast, a tuple is more like a jumble of independent values, ordered only 
because in this benighted world we can't really write them down at the same 
time. If you know someone's name and age, and you have to scribble them both 
down on a piece of paper, it doesn't really change anything which one you write 
first.  At most there's some arbitrary convention for the order, like putting x 
before y in Cartesian coordinates.

We can choose different types for different purposes because they convey 
different things about the values they store.  Isomorphism is not meaning.

>> The difference between a fixed-size array and the dynamically-sized Array we 
>> already have is that the programmer expects specific data at each element. 
>> Maybe it’s elements of a vector or matrix, or some other structure, but in 
>> general I think that constraints about the size/shape of the sequence 
>> implies expectations about what you’re going to find at each location. Maybe 
>> you would normally write a struct for it, but it’s not worth writing out. In 
>> that sense, how is it different from a homogenous tuple?
> 
> I’m not sure what you mean here. How do elements of dynamically-sized arrays 
> not have expectations?
> 
> The big innovation arrays (and loops) brought was no longer having a 
> per-sub-object declaration/command for elements. Just tweak a number.
> 
> I’m not good at explicit explanations, so having to justify adding a type 
> that’s been around for a long time (at least FORTRAN 4+ decades ago) an 
> almost every systems programming language has is frustrating. I thought the 
> desire would be obvious; if there were FSAs in Swift 1, would there be any 
> “just slap Collection on tuples and be done with it” suggestions now? It 
> doesn’t help that I still don’t know why FSAs where skipped in Swift 1; did 
> they forget or was there some high-level type-theory reason? (Were the type 
> description records in the Swift ABI too fragile for a type that wouldn’t 
> have per-sub-object entries (assuming theoretical Swift-1-FSAs weren’t 
> translated to massive homogenous tuples)?)

They just weren't a priority.  There are many things I wish we had done more 
work on before we released Swift 1, but trying to perfectly represent 
everything in C type system is not one of them.

Reasons not to prioritize fixed-sized arrays:
1. Variably-sized arrays are a much more important data structure.  Fixed sized 
arrays are easier to make perform well, but they are inflexible and only 
narrowly useful.
2. The bound introduces significant expressional complexity to the type system. 
 What types are eligible as bounds?  What sorts of inference and 
meta-programming are possible on bounds? etc.
3. The language/library interactions are complex.  It's a general data 
structure that demands proper integration with the rest of the collections 
library, but the language also really needs to hard-code an exact 
representation.  So it would take a lot of work to integrate.

Honestly, a lot of this still applies.  I would like to see fixed-sized arrays 
in the language eventually, but they are not going to become a priority, 
because there's a lot of other stuff that is more important to work on.

John.

> 
> I mentioned in my proposal that no language (that I know of) splatted tuple 
> and array syntax together, either declaration syntax or dereferencing syntax. 
> (Lua has shared dereferencing syntax, but they both rip-off dictionaries.) 
> Where do people think every one else over the l

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-08-02 Thread John McCall via swift-evolution

> On Aug 2, 2017, at 6:29 PM, Karl Wagner  wrote:
> 
> 
>> On 3. Aug 2017, at 00:21, John McCall > <mailto:rjmcc...@apple.com>> wrote:
>> 
>> 
>>> On Aug 2, 2017, at 6:10 PM, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> On Aug 2, 2017, at 5:56 PM, Karl Wagner >>> <mailto:razie...@gmail.com>> wrote:
>>>>> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>>>>>> mailto:gor.f.gyolchan...@icloud.com>> 
>>>>>> wrote:
>>>>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >>>>>>> <mailto:dary...@mac.com>> wrote:
>>>>>>>> The parameters for a fixed-size array type determine the type's 
>>>>>>>> size/stride, so how could the bounds not be needed during 
>>>>>>>> compile-time? The compiler can't layout objects otherwise. 
>>>>>>> 
>>>>>>> Swift is not C; it is perfectly capable of laying out objects at run 
>>>>>>> time.  It already has to do that for generic types and types with 
>>>>>>> resilient members.  That does, of course, have performance 
>>>>>>> consequences, and those performance consequences might be unacceptable 
>>>>>>> to you; but the fact that we can handle it means that we don't 
>>>>>>> ultimately require a semantic concept of a constant expression, except 
>>>>>>> inasmuch as we want to allow users to explicitly request guarantees 
>>>>>>> about static layout.
>>>>>> 
>>>>>> Doesn't this defeat the purpose of generic value parameters? We might as 
>>>>>> well use a regular parameter if there's no compile-time evaluation 
>>>>>> involved. In that case, fixed-sized arrays will be useless, because 
>>>>>> they'll be normal arrays with resizing disabled.
>>>>> 
>>>>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>>>>> feature is to allow the array to be allocated "inline" in its context 
>>>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
>>>>> There is no reason that that representation would not be supportable just 
>>>>> because the array's bound is not statically known; the only thing that 
>>>>> matters is whether the bound is consistent for all instances of the 
>>>>> container.
>>>>> 
>>>>> That is, it would not be okay to have a type like:
>>>>>  struct Widget {
>>>>>let length: Int
>>>>>var array: [length x Int]
>>>>>  }
>>>>> because the value of the bound cannot be computed independently of a 
>>>>> specific value.
>>>>> 
>>>>> But it is absolutely okay to have a type like:
>>>>>  struct Widget {
>>>>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>>>  }
>>>>> It just means that the bound would get computed at runtime and, 
>>>>> presumably, cached.  The fact that this type's size isn't known 
>>>>> statically does mean that the compiler has to be more pessimistic, but 
>>>>> its values would still get allocated inline into their containers and 
>>>>> even on the stack, using pretty much the same techniques as C99 VLAs.
>>>> 
>>>> Do we really want to make that guarantee about heap/stack allocation? 
>>>> C99’s VLAs are not very loop-friendly:
>>>> 
>>>> echo "int main() { 
>>>> for(int i = 0; i<100; i++) {
>>>>   int myArray[i * 1000]; myArray[0] = 32;
>>>> }
>>>> return 0;
>>>>   }" | clang -x c - && ./a.out
>>>> 
>>>> Segmentation Fault: 11
>>>> 
>>>> C compilers also do not inline code with VLAs by default. If you force it, 
>>>> you expose yourself to possible stack ov

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-08-02 Thread John McCall via swift-evolution

> On Aug 2, 2017, at 6:10 PM, John McCall via swift-evolution 
>  wrote:
> 
>> On Aug 2, 2017, at 5:56 PM, Karl Wagner > <mailto:razie...@gmail.com>> wrote:
>>> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >>> <mailto:gor.f.gyolchan...@icloud.com>> wrote:
>>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >>>>> <mailto:dary...@mac.com>> wrote:
>>>>>> The parameters for a fixed-size array type determine the type's 
>>>>>> size/stride, so how could the bounds not be needed during compile-time? 
>>>>>> The compiler can't layout objects otherwise. 
>>>>> 
>>>>> Swift is not C; it is perfectly capable of laying out objects at run 
>>>>> time.  It already has to do that for generic types and types with 
>>>>> resilient members.  That does, of course, have performance consequences, 
>>>>> and those performance consequences might be unacceptable to you; but the 
>>>>> fact that we can handle it means that we don't ultimately require a 
>>>>> semantic concept of a constant expression, except inasmuch as we want to 
>>>>> allow users to explicitly request guarantees about static layout.
>>>> 
>>>> Doesn't this defeat the purpose of generic value parameters? We might as 
>>>> well use a regular parameter if there's no compile-time evaluation 
>>>> involved. In that case, fixed-sized arrays will be useless, because 
>>>> they'll be normal arrays with resizing disabled.
>>> 
>>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>>> feature is to allow the array to be allocated "inline" in its context 
>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>>> is no reason that that representation would not be supportable just because 
>>> the array's bound is not statically known; the only thing that matters is 
>>> whether the bound is consistent for all instances of the container.
>>> 
>>> That is, it would not be okay to have a type like:
>>>  struct Widget {
>>>let length: Int
>>>var array: [length x Int]
>>>  }
>>> because the value of the bound cannot be computed independently of a 
>>> specific value.
>>> 
>>> But it is absolutely okay to have a type like:
>>>  struct Widget {
>>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>  }
>>> It just means that the bound would get computed at runtime and, presumably, 
>>> cached.  The fact that this type's size isn't known statically does mean 
>>> that the compiler has to be more pessimistic, but its values would still 
>>> get allocated inline into their containers and even on the stack, using 
>>> pretty much the same techniques as C99 VLAs.
>> 
>> Do we really want to make that guarantee about heap/stack allocation? C99’s 
>> VLAs are not very loop-friendly:
>> 
>> echo "int main() { 
>> for(int i = 0; i<100; i++) {
>>   int myArray[i * 1000]; myArray[0] = 32;
>> }
>> return 0;
>>   }" | clang -x c - && ./a.out
>> 
>> Segmentation Fault: 11
>> 
>> C compilers also do not inline code with VLAs by default. If you force it, 
>> you expose yourself to possible stack overflows:
>> 
>> echo "static inline void doSomething(int i) {
>> int myArray[i * 1000]; myArray[0] = 32;
>>   }
>>   int main() {
>> for(int i = 0; i<100; i++) {
>>   doSomething(i);
>> }
>>   return 0;
>>   }" | clang -x c - && ./a.out
>> 
>> Segmentation Fault: 11
>> 
>> I wouldn’t like us to import these kinds of issues in to Swift
> 
> We probably would not make an absolute guarantee of stack allocation, no.

Although I will note that the problem in your example has nothing to do with it 
being a loop and everything to do with it asking for an almost 4GB array. :)

John.___
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-02 Thread John McCall via swift-evolution
> On Aug 2, 2017, at 5:56 PM, Karl Wagner  wrote:
>> On 31. Jul 2017, at 21:09, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >> <mailto:gor.f.gyolchan...@icloud.com>> wrote:
>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >>>> <mailto:dary...@mac.com>> wrote:
>>>>> The parameters for a fixed-size array type determine the type's 
>>>>> size/stride, so how could the bounds not be needed during compile-time? 
>>>>> The compiler can't layout objects otherwise. 
>>>> 
>>>> Swift is not C; it is perfectly capable of laying out objects at run time. 
>>>>  It already has to do that for generic types and types with resilient 
>>>> members.  That does, of course, have performance consequences, and those 
>>>> performance consequences might be unacceptable to you; but the fact that 
>>>> we can handle it means that we don't ultimately require a semantic concept 
>>>> of a constant expression, except inasmuch as we want to allow users to 
>>>> explicitly request guarantees about static layout.
>>> 
>>> Doesn't this defeat the purpose of generic value parameters? We might as 
>>> well use a regular parameter if there's no compile-time evaluation 
>>> involved. In that case, fixed-sized arrays will be useless, because they'll 
>>> be normal arrays with resizing disabled.
>> 
>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>> feature is to allow the array to be allocated "inline" in its context 
>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>> is no reason that that representation would not be supportable just because 
>> the array's bound is not statically known; the only thing that matters is 
>> whether the bound is consistent for all instances of the container.
>> 
>> That is, it would not be okay to have a type like:
>>  struct Widget {
>>let length: Int
>>var array: [length x Int]
>>  }
>> because the value of the bound cannot be computed independently of a 
>> specific value.
>> 
>> But it is absolutely okay to have a type like:
>>  struct Widget {
>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>  }
>> It just means that the bound would get computed at runtime and, presumably, 
>> cached.  The fact that this type's size isn't known statically does mean 
>> that the compiler has to be more pessimistic, but its values would still get 
>> allocated inline into their containers and even on the stack, using pretty 
>> much the same techniques as C99 VLAs.
> 
> Do we really want to make that guarantee about heap/stack allocation? C99’s 
> VLAs are not very loop-friendly:
> 
> echo "int main() { 
> for(int i = 0; i<100; i++) {
>   int myArray[i * 1000]; myArray[0] = 32;
> }
> return 0;
>   }" | clang -x c - && ./a.out
> 
> Segmentation Fault: 11
> 
> C compilers also do not inline code with VLAs by default. If you force it, 
> you expose yourself to possible stack overflows:
> 
> echo "static inline void doSomething(int i) {
> int myArray[i * 1000]; myArray[0] = 32;
>   }
>   int main() {
> for(int i = 0; i<100; i++) {
>   doSomething(i);
> }
>   return 0;
>   }" | clang -x c - && ./a.out
> 
> Segmentation Fault: 11
> 
> I wouldn’t like us to import these kinds of issues in to Swift

We probably would not make an absolute guarantee of stack allocation, no.

John.___
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-02 Thread John McCall via swift-evolution
> On Aug 2, 2017, at 12:17 PM, Félix Cloutier  wrote:
> `[Int x N]` solves all of the problems that I mentioned, and I'm happy with 
> that syntax. In fact, I'm championing its merits versus an approach that 
> doesn't include the number of elements. :)
> 
> Unless I got things wrong this entire time, the proposed spelling 
> 
>  was `fixed [Int]`, with no mention of the number of elements.

I agree that an array with a dynamic, value-specific but fixed bound seems 
basically pointless.  It's more of a minor optimization hint than a real type.

John.


> 
> Félix
> 
>> Le 2 août 2017 à 09:00, John McCall > > a écrit :
>>> 
 var foo = fixed [Int]()
 for i in 0..>>>foo.append(i)
 }
>>> 
>>> Arrays can't work if elements don't have a fixed size. How big is an 
>>> element in this example?
>> 
>> This is not the idea.  The idea is more like
>> 
>>   let n = ...
>>   var foo = [Int x n](repeating: 13)
>> 
>> The bound value is still fundamentally part of the type of the variable; 
>> it's just that the actual value is not known statically.
>> 
>> John.
> 

___
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-02 Thread John McCall via swift-evolution

> On Aug 2, 2017, at 11:44 AM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> 
>> Le 31 juil. 2017 à 18:54, Xiaodi Wu > > a écrit :
>> It doesn't allow you to specify the size of the array, it's just a promise 
>> that the array is some immutable size. For instance, a `fixed [CGFloat]` 
>> would be a terrible type to represent a vector, but a 
>> FixedSizeArray would be appropriate, at least for the backing 
>> storage. A raw tuple would be a poor choice because dynamically indexing 
>> into them is painful.
>> 
>> Shouldn't this be solved by improvements to tuples? It's a highly desired 
>> feature (by me and at least a few others) to allow tuples to conform to 
>> protocols, whether fixed-size arrays are added or not. I expect that 
>> conforming homogeneous tuples to Collection and enabling subscripting is 
>> simply a matter of time.
> 
> Of course, if this happens, the point is moot and we have the type of 
> fixed-size arrays that I've been asking for. However, crystal-balling Chris's 
> last comment on the matter, it looks like it might not be happening too soon 
> .
> 
>> `fixed` is only useful when the compiler can determine the size of the array 
>> statically. This makes it mostly useless as a storage qualifier if you 
>> received the array as a parameter (*even* if you received a `fixed` array), 
>> because you know that it has a constant size but you don't know what that 
>> size is.
>> Therefore, using a fixed-size array as a generic parameter (crucially, such 
>> as `fixed [fixed [Int]]`) is unlikely to work.
>> Even if that semantic hurdle is overcome, we'd still have no idea how much 
>> memory to allocate for the outer array's buffer to make it work.
>> 
>> As John McCall has replied, the array's bounds don't need to be statically 
>> known for fixed-size arrays to have benefits.
> 
> This (partially) applies to the first point, but it leaves a lot of holes. 
> The size does not need to be statically known, but you need to know how much 
> memory you're going to need ahead of allocating it. How much memory do you 
> need for this?
> 
>> var foo = fixed [Int]()
>> for i in 0..>  foo.append(i)
>> }
> 
> Arrays can't work if elements don't have a fixed size. How big is an element 
> in this example?

This is not the idea.  The idea is more like

  let n = ...
  var foo = [Int x n](repeating: 13)

The bound value is still fundamentally part of the type of the variable; it's 
just that the actual value is not known statically.

John.

>> var foo = fixed [fixed [Int]]()
>> foo.append([1])
>> foo.append([2, 3])
> 
> 
> Where do you allocate this array's storage, and how big is it?
> 
>> struct Foo {
>>  var array: fixed [Int]
>> }
>> 
>> var foo = Foo()
>> foo.array.append(4)
> 
> 
> In the general case, this makes `fixed` meaningful as a type annotation for 
> parameters, but instantiating such an object in the first place would require 
> you to give up a lot of flexibility in how it's populated. The unconstrained 
> problem of finding how many elements you'll have in an array is uncomputable.
> 
> You could say that a fixed-size array stays as big as it was when it was 
> instantiated, but this still causes problems with fixed-size arrays in 
> structures (storage has already been allocated when the initializer runs), 
> and with generic collections (you couldn't initialize a variable-sized array 
> of fixed-size arrays, for instance).
>> Even if `fixed [fixed [Int]]` could work, then each inner array could still 
>> have a different size, which is almost certainly not what you intend by 
>> nesting two fixed-size arrays.
>> 
>> That's fair, but why at that point wouldn't you make your own Matrix type of 
>> fixed size, which uses an Array of fixed size as the underlying storage?
> 
> I'd do it if I needed to, but there are plenty of 2D arrays that are just 
> that and don't need their own wrapper type to function, and I'd be happier to 
> not do it.
>> Layout compatibility is important if you want to use fixed-size arrays to 
>> replace the clunky tuples that currently represent fixed-size arrays in 
>> structs exported from C (which is probably my one single biggest motivation 
>> for fixed-size arrays). You can't achieve layout compatibility if the size 
>> is part of the data instead of part of the type.
>> 
>> For me, that's an anti-goal, as IMO tuples are the most sensible way of 
>> bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue 
>> that the most idiomatic way to represent four CGFloat instances is 
>> `(CGFloat, CGFloat, CGFloat, CGFloat)`. The solution to certain operations 
>> being clunky with tuples is to improve the ergonomics of tuples. For 
>> instance, if we need a shorthand to avoid typing all those `CGFloat`s, then 
>> add one: `(4 * CGFloat)`. If we need subscripting, then add it.
> 
> I think that any template-based fixed-s

Re: [swift-evolution] [Pitch] New Version of Array Proposal

2017-08-01 Thread John McCall via swift-evolution
> On Aug 1, 2017, at 5:49 PM, David Sweeris via swift-evolution 
>  wrote:
>> On Aug 1, 2017, at 10:54 AM, Daryle Walker via swift-evolution 
>>  wrote:
>> 
>> A tuple can have its members initialized in piecemeal and still satisfy 
>> deterministic initialization. The named types need to do all their 
>> sub-objects' initializations before any designated initializer ends. I want 
>> the former for array instances, not the latter. It’s important for numeric 
>> applications, so math arrays don’t have to be set twice, once for an 
>> arbitrary default and again for the real data.
> 
> Eh? What do you mean by "initialized in piecemeal"? These both give errors:
> let x:(Int, Int) = (0) // something about not being able to convert `Int` to 
> `(Int, Int)`
> let x:(Int, Int) = (0, _) // something about "_" only being allowed in 
> patterns
> 
> Is that what you're talking about?

I think he means that you can do

var x: (Int,Int)
x.0 = 0
x.1 = 1

This is generally not allowed for other aggregates outside of initializers.

John.
___
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-01 Thread John McCall via swift-evolution

> On Aug 1, 2017, at 9:53 AM, Daryle Walker  wrote:
> 
>> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan > <mailto:gor.f.gyolchan...@icloud.com>> wrote:
>> 
>>> 
>>> On Jul 31, 2017, at 11:23 PM, John McCall >> <mailto:rjmcc...@apple.com>> wrote:
>>> 
>>>> 
>>>> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >>> <mailto:gor.f.gyolchan...@icloud.com>> wrote:
>>>> 
>>>> 
>>>>> On Jul 31, 2017, at 10:09 PM, John McCall >>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>> 
>>>>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>>>>>> mailto:gor.f.gyolchan...@icloud.com>> 
>>>>>> wrote:
>>>>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >>>>>>> <mailto:dary...@mac.com>> wrote:
>>>>>>>> The parameters for a fixed-size array type determine the type's 
>>>>>>>> size/stride, so how could the bounds not be needed during 
>>>>>>>> compile-time? The compiler can't layout objects otherwise. 
>>>>>>> 
>>>>>>> Swift is not C; it is perfectly capable of laying out objects at run 
>>>>>>> time.  It already has to do that for generic types and types with 
>>>>>>> resilient members.  That does, of course, have performance 
>>>>>>> consequences, and those performance consequences might be unacceptable 
>>>>>>> to you; but the fact that we can handle it means that we don't 
>>>>>>> ultimately require a semantic concept of a constant expression, except 
>>>>>>> inasmuch as we want to allow users to explicitly request guarantees 
>>>>>>> about static layout.
>>>>>> 
>>>>>> Doesn't this defeat the purpose of generic value parameters? We might as 
>>>>>> well use a regular parameter if there's no compile-time evaluation 
>>>>>> involved. In that case, fixed-sized arrays will be useless, because 
>>>>>> they'll be normal arrays with resizing disabled.
>>>>> 
>>>>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>>>>> feature is to allow the array to be allocated "inline" in its context 
>>>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
>>>>> There is no reason that that representation would not be supportable just 
>>>>> because the array's bound is not statically known; the only thing that 
>>>>> matters is whether the bound is consistent for all instances of the 
>>>>> container.
>>>>> 
>>>>> That is, it would not be okay to have a type like:
>>>>>  struct Widget {
>>>>>let length: Int
>>>>>var array: [length x Int]
>>>>>  }
>>>>> because the value of the bound cannot be computed independently of a 
>>>>> specific value.
>>>>> 
>>>>> But it is absolutely okay to have a type like:
>>>>>  struct Widget {
>>>>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>>>  }
>>>>> It just means that the bound would get computed at runtime and, 
>>>>> presumably, cached.  The fact that this type's size isn't known 
>>>>> statically does mean that the compiler has to be more pessimistic, but 
>>>>> its values would still get allocated inline into their containers and 
>>>>> even on the stack, using pretty much the same techniques as C99 VLAs.
>>>> 
>>>> 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.
>>

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 9:54 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> On Mon, Jul 31, 2017 at 11:45 AM, Félix Cloutier  > wrote:
> 
>> Sure, and hence my point: suppose now `foo` is a function in the stdlib, and 
>> the stdlib authors have annotated the function so that it is `func foo(arr: 
>> fixed [Int])`. Then, any user who writes `var array = ...` could benefit 
>> from a performance boost because the compiler will not longer have to be 
>> pessimistic about copying in order to maintain COW semantics. This is why I 
>> made an explicit analogy to the design proposed for ownership in Swift, 
>> where end users don't have to understand it in order to benefit from the 
>> feature because the functions they call can give sufficiently important 
>> hints to help the compiler avoid unnecessary copying.
>>  
>> I don't think that you claimed that this should be a solution to the 
>> fixed-size array problem, but just in case, also note that it's not. We 
>> can't make any [Int] layout-compatible with C fixed-size arrays because the 
>> length has to be encoded in the type (as it cannot be encoded in the data 
>> itself).
>> 
>> I don't understand this point. Can you elaborate on what you mean here? Why 
>> does it have to be layout-compatible?
> 
> 
> Then it seems that I have stricter requirements for fixed-size arrays than 
> you do, and I'd be curious to hear what you want to get out of fixed-size 
> arrays. If we compare a hypothetical `fixed [int]` to a hypothetical 
> `FixedSizeArray`, these are some of the things that matter to me which 
> `fixed` can't offer:
> 
> It doesn't allow you to specify the size of the array, it's just a promise 
> that the array is some immutable size. For instance, a `fixed [CGFloat]` 
> would be a terrible type to represent a vector, but a FixedSizeArray 4> would be appropriate, at least for the backing storage. A raw tuple would 
> be a poor choice because dynamically indexing into them is painful.
> 
> Shouldn't this be solved by improvements to tuples? It's a highly desired 
> feature (by me and at least a few others) to allow tuples to conform to 
> protocols, whether fixed-size arrays are added or not. I expect that 
> conforming homogeneous tuples to Collection and enabling subscripting is 
> simply a matter of time.

I disagree; it seems to me that a homogeneous fixed-size sequence is its own 
concept, and there isn't any natural link between that concept and that of a 
tuple.  The elements of a tuple are independent with no naturally-implied 
relationship; or put another way, tuple indices are nominal, not ordinal.

Importing C arrays as tuples is a big old hack that has never really worked out 
well.

John.
> `fixed` is only useful when the compiler can determine the size of the array 
> statically. This makes it mostly useless as a storage qualifier if you 
> received the array as a parameter (*even* if you received a `fixed` array), 
> because you know that it has a constant size but you don't know what that 
> size is.
> Therefore, using a fixed-size array as a generic parameter (crucially, such 
> as `fixed [fixed [Int]]`) is unlikely to work.
> Even if that semantic hurdle is overcome, we'd still have no idea how much 
> memory to allocate for the outer array's buffer to make it work.
> 
> As John McCall has replied, the array's bounds don't need to be statically 
> known for fixed-size arrays to have benefits.
>  
> Even if `fixed [fixed [Int]]` could work, then each inner array could still 
> have a different size, which is almost certainly not what you intend by 
> nesting two fixed-size arrays.
> 
> That's fair, but why at that point wouldn't you make your own Matrix type of 
> fixed size, which uses an Array of fixed size as the underlying storage?
> 
> Layout compatibility is important if you want to use fixed-size arrays to 
> replace the clunky tuples that currently represent fixed-size arrays in 
> structs exported from C (which is probably my one single biggest motivation 
> for fixed-size arrays). You can't achieve layout compatibility if the size is 
> part of the data instead of part of the type.
> 
> For me, that's an anti-goal, as IMO tuples are the most sensible way of 
> bridging a lot of these fixed-size arrays from C. Quite simply, I'd argue 
> that the most idiomatic way to represent four CGFloat instances is `(CGFloat, 
> CGFloat, CGFloat, CGFloat)`. The solution to certain operations being clunky 
> with tuples is to improve the ergonomics of tuples. For instance, if we need 
> a shorthand to avoid typing all those `CGFloat`s, then add one: `(4 * 
> CGFloat)`. If we need subscripting, then add it.
> 
> Besides, attaching fixed-size array semantics to an inherently variable-size 
> Array is awkward. For `fixed` to be effective, it needs to disable methods 
> that change the size of the array, or warn that you're using them. I don't 
> like the cross-concern impact: now a keyword needs to know about me

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 11:29 PM, Félix Cloutier  wrote:
> No, this is a misunderstanding: I mean "you" as yourself, not "you" as the 
> compiler. As far as I know, given a type variable, as in `let foo: 
> NSObject.Type = NSArray.self`, you (the developer) can't use `foo` to 
> instantiate a generic type.

Ah, yes, I did misunderstand what you were saying.

> The question stands again: are there any specific reasons that you can't do 
> that right now, or is it just because the need for this is not particularly 
> evident?

There is no specific reason you can't do that right now.  We could certainly 
just allow you to name a local constant in type contexts if it happens to be of 
metatype type — I don't know if that would be the best language design, but 
there's nothing inherent about the language model that makes it unreasonable.  
I do think we would at least demand that it be a constant and not a variable.

John.


> 
> Félix
> 
>> Le 31 juil. 2017 à 11:29, John McCall  a écrit :
>> 
>>> On Jul 31, 2017, at 3:58 AM, Félix Cloutier  wrote:
>>> It seems to me that this applies just the same to type generic parameters. 
>>> Are there any reason that you can't instantiate a generic type at runtime, 
>>> or is it just because the need is not as evident as it would/could be with 
>>> non-type generic parameters?
>> 
>> Are you under the impression that Swift does not, today, instantiate generic 
>> types at runtime?
>> 
>> A lot of this entire thread seems to be premised on really weird, incorrect 
>> assumptions about the Swift compilation model.
>> 
>> John.
>> 
>>> 
>>>> Le 30 juil. 2017 à 21:10, John McCall via swift-evolution 
>>>>  a écrit :
>>>> 
>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  wrote:
>>>>> The parameters for a fixed-size array type determine the type's 
>>>>> size/stride, so how could the bounds not be needed during compile-time? 
>>>>> The compiler can't layout objects otherwise. 
>>>> 
>>>> Swift is not C; it is perfectly capable of laying out objects at run time. 
>>>>  It already has to do that for generic types and types with resilient 
>>>> members.  That does, of course, have performance consequences, and those 
>>>> performance consequences might be unacceptable to you; but the fact that 
>>>> we can handle it means that we don't ultimately require a semantic concept 
>>>> of a constant expression, except inasmuch as we want to allow users to 
>>>> explicitly request guarantees about static layout.
>>>> 
>>>> Value equality would still affect the type-checker, but I think we could 
>>>> pretty easily just say that all bound expressions are assumed to 
>>>> potentially resolve unequally unless they are literals or references to 
>>>> the same 'let' constant.
>>>> 
>>>> The only hard constraint is that types need to be consistent, but that 
>>>> just means that we need to have a model in which bound expressions are 
>>>> evaluated exactly once at runtime (and of course typically folded at 
>>>> compile time).
>>>> 
>>>> John.
>>>> 
>>>>> Or do you mean that the bounds are integer literals? (That's what I have 
>>>>> in the design document now.)
>>>>> 
>>>>> Sent from my iPhone
>>>>> 
>>>>> On Jul 30, 2017, at 8:51 PM, John McCall  wrote:
>>>>> 
>>>>>>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>>>>>>  wrote:
>>>>>>> The “constexpr” facility from C++ allows users to define constants and 
>>>>>>> functions that are determined and usable at compile-time, for 
>>>>>>> compile-time constructs but still usable at run-time. The facility is a 
>>>>>>> key step for value-based generic parameters (and fixed-size arrays if 
>>>>>>> you don’t want to be stuck with integer literals for bounds). Can 
>>>>>>> figuring out Swift’s story here be part of Swift 5?
>>>>>> 
>>>>>> Note that there's no particular reason that value-based generic 
>>>>>> parameters, including fixed-size arrays, actually need to be constant 
>>>>>> expressions in Swift.
>>>>>> 
>>>>>> John.
>>>> 
>>>> ___
>>>> 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-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 4:37 PM, Gor Gyolchanyan  
> wrote:
>> On Jul 31, 2017, at 11:23 PM, John McCall > <mailto:rjmcc...@apple.com>> wrote:
>> 
>>> 
>>> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan >> <mailto:gor.f.gyolchan...@icloud.com>> wrote:
>>> 
>>> 
>>>> On Jul 31, 2017, at 10:09 PM, John McCall >>> <mailto:rjmcc...@apple.com>> wrote:
>>>> 
>>>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan 
>>>>> mailto:gor.f.gyolchan...@icloud.com>> 
>>>>> wrote:
>>>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >>>>>> <mailto:dary...@mac.com>> wrote:
>>>>>>> The parameters for a fixed-size array type determine the type's 
>>>>>>> size/stride, so how could the bounds not be needed during compile-time? 
>>>>>>> The compiler can't layout objects otherwise. 
>>>>>> 
>>>>>> Swift is not C; it is perfectly capable of laying out objects at run 
>>>>>> time.  It already has to do that for generic types and types with 
>>>>>> resilient members.  That does, of course, have performance consequences, 
>>>>>> and those performance consequences might be unacceptable to you; but the 
>>>>>> fact that we can handle it means that we don't ultimately require a 
>>>>>> semantic concept of a constant expression, except inasmuch as we want to 
>>>>>> allow users to explicitly request guarantees about static layout.
>>>>> 
>>>>> Doesn't this defeat the purpose of generic value parameters? We might as 
>>>>> well use a regular parameter if there's no compile-time evaluation 
>>>>> involved. In that case, fixed-sized arrays will be useless, because 
>>>>> they'll be normal arrays with resizing disabled.
>>>> 
>>>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>>>> feature is to allow the array to be allocated "inline" in its context 
>>>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  
>>>> There is no reason that that representation would not be supportable just 
>>>> because the array's bound is not statically known; the only thing that 
>>>> matters is whether the bound is consistent for all instances of the 
>>>> container.
>>>> 
>>>> That is, it would not be okay to have a type like:
>>>>  struct Widget {
>>>>let length: Int
>>>>var array: [length x Int]
>>>>  }
>>>> because the value of the bound cannot be computed independently of a 
>>>> specific value.
>>>> 
>>>> But it is absolutely okay to have a type like:
>>>>  struct Widget {
>>>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>>>  }
>>>> It just means that the bound would get computed at runtime and, 
>>>> presumably, cached.  The fact that this type's size isn't known statically 
>>>> does mean that the compiler has to be more pessimistic, but its values 
>>>> would still get allocated inline into their containers and even on the 
>>>> stack, using pretty much the same techniques as C99 VLAs.
>>> 
>>> 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.
> 
> That's why I'm trying to push for compile-time execution system. All these 
> problems (among many others) could be designed out of existence and the 
> compiler would be incredibly simple in the light of all the different 
> specific features that the community is asking for. But I do feel your urge 
> to avoid inventing a bulldozer factory just for digging a hole in a sandbox. 
> It doesn't have to be rel

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-07-31 Thread John McCall via swift-evolution

> On Jul 31, 2017, at 4:00 PM, Gor Gyolchanyan  
> wrote:
> 
> 
>> On Jul 31, 2017, at 10:09 PM, John McCall > <mailto:rjmcc...@apple.com>> wrote:
>> 
>>> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan >> <mailto:gor.f.gyolchan...@icloud.com>> wrote:
>>>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker >>>> <mailto:dary...@mac.com>> wrote:
>>>>> The parameters for a fixed-size array type determine the type's 
>>>>> size/stride, so how could the bounds not be needed during compile-time? 
>>>>> The compiler can't layout objects otherwise. 
>>>> 
>>>> Swift is not C; it is perfectly capable of laying out objects at run time. 
>>>>  It already has to do that for generic types and types with resilient 
>>>> members.  That does, of course, have performance consequences, and those 
>>>> performance consequences might be unacceptable to you; but the fact that 
>>>> we can handle it means that we don't ultimately require a semantic concept 
>>>> of a constant expression, except inasmuch as we want to allow users to 
>>>> explicitly request guarantees about static layout.
>>> 
>>> Doesn't this defeat the purpose of generic value parameters? We might as 
>>> well use a regular parameter if there's no compile-time evaluation 
>>> involved. In that case, fixed-sized arrays will be useless, because they'll 
>>> be normal arrays with resizing disabled.
>> 
>> You're making huge leaps here.  The primary purpose of a fixed-size array 
>> feature is to allow the array to be allocated "inline" in its context 
>> instead of "out-of-line" using heap-allocated copy-on-write buffers.  There 
>> is no reason that that representation would not be supportable just because 
>> the array's bound is not statically known; the only thing that matters is 
>> whether the bound is consistent for all instances of the container.
>> 
>> That is, it would not be okay to have a type like:
>>  struct Widget {
>>let length: Int
>>var array: [length x Int]
>>  }
>> because the value of the bound cannot be computed independently of a 
>> specific value.
>> 
>> But it is absolutely okay to have a type like:
>>  struct Widget {
>>var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
>>  }
>> It just means that the bound would get computed at runtime and, presumably, 
>> cached.  The fact that this type's size isn't known statically does mean 
>> that the compiler has to be more pessimistic, but its values would still get 
>> allocated inline into their containers and even on the stack, using pretty 
>> much the same techniques as C99 VLAs.
> 
> 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.

>>> As far as I know, the pinnacle of uses for fixed-size arrays is having a 
>>> compile-time pre-allocated space of the necessary size (either literally at 
>>> compile-time if that's a static variable, or added to the pre-computed 
>>> offset of the stack pointer in case of a local variable).
>> 
>> The difference between having to use dynamic offsets + alloca() and static 
>> offsets + a normal stack slot is noticeable but not nearly as extreme as 
>> you're imagining.  And again, in most common cases we would absolutely be 
>> able to fold a bound statically and fall into the optimal path you're 
>> talking about.  The critical guarantee, that the array does not get 
>> heap-allocated, is still absolutely intact.
> 
> Yet again, Swift (specifically - you in this case) is teaching me to trust 
> the compiler to optimize, which is still an alien feeling to me even after 
> all these years of heavy Swift usage. Damn you, C++ for corrupting my brain 😀.

Well.  Trust but verify. :)

> In the specific case of having dynamic-sized in-place-allocated value types 
> this will absolutely work. But this raises a chicken-and-the-eg

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 3:15 AM, Gor Gyolchanyan  
> wrote:
>> On Jul 31, 2017, at 7:10 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  wrote:
>>> The parameters for a fixed-size array type determine the type's 
>>> size/stride, so how could the bounds not be needed during compile-time? The 
>>> compiler can't layout objects otherwise. 
>> 
>> Swift is not C; it is perfectly capable of laying out objects at run time.  
>> It already has to do that for generic types and types with resilient 
>> members.  That does, of course, have performance consequences, and those 
>> performance consequences might be unacceptable to you; but the fact that we 
>> can handle it means that we don't ultimately require a semantic concept of a 
>> constant expression, except inasmuch as we want to allow users to explicitly 
>> request guarantees about static layout.
> 
> Doesn't this defeat the purpose of generic value parameters? We might as well 
> use a regular parameter if there's no compile-time evaluation involved. In 
> that case, fixed-sized arrays will be useless, because they'll be normal 
> arrays with resizing disabled.

You're making huge leaps here.  The primary purpose of a fixed-size array 
feature is to allow the array to be allocated "inline" in its context instead 
of "out-of-line" using heap-allocated copy-on-write buffers.  There is no 
reason that that representation would not be supportable just because the 
array's bound is not statically known; the only thing that matters is whether 
the bound is consistent for all instances of the container.

That is, it would not be okay to have a type like:
  struct Widget {
let length: Int
var array: [length x Int]
  }
because the value of the bound cannot be computed independently of a specific 
value.

But it is absolutely okay to have a type like:
  struct Widget {
var array: [(isRunningOnIOS15() ? 20 : 10) x Int]
  }
It just means that the bound would get computed at runtime and, presumably, 
cached.  The fact that this type's size isn't known statically does mean that 
the compiler has to be more pessimistic, but its values would still get 
allocated inline into their containers and even on the stack, using pretty much 
the same techniques as C99 VLAs.

> As far as I know, the pinnacle of uses for fixed-size arrays is having a 
> compile-time pre-allocated space of the necessary size (either literally at 
> compile-time if that's a static variable, or added to the pre-computed offset 
> of the stack pointer in case of a local variable).

The difference between having to use dynamic offsets + alloca() and static 
offsets + a normal stack slot is noticeable but not nearly as extreme as you're 
imagining.  And again, in most common cases we would absolutely be able to fold 
a bound statically and fall into the optimal path you're talking about.  The 
critical guarantee, that the array does not get heap-allocated, is still 
absolutely intact.

>> Value equality would still affect the type-checker, but I think we could 
>> pretty easily just say that all bound expressions are assumed to potentially 
>> resolve unequally unless they are literals or references to the same 'let' 
>> constant.
> 
> Shouldn't the type-checker use the Equatable protocol conformance to test for 
> equality?

The Equatable protocol does guarantee reflexivity.

> Moreover, as far as I know, Equatable is not recognized by the compiler in 
> any way, so it's just a regular protocol.

That's not quite true: we synthesize Equatable instances in several places.

> What would make it special? Some types would implement operator == to compare 
> themselves to other types, that's beyond the scope of Equatable. What about 
> those? And how are custom operator implementations going to serve this 
> purpose at compile-time? Or will it just ignore the semantics of the type and 
> reduce it to a sequence of bits? Or maybe only a few hand-picked types will 
> be supported?

> 
> The seemingly simple generic value parameter concept gets vastly complicated 
> and/or poorly designed without an elaborate compile-time execution system... 
> Unless I'm missing an obvious way out.

The only thing the compiler really *needs* to know is whether two types are 
known to be the same, i.e. whether two values are known to be the same.  An 
elaborate compile-time execution system would not be sufficient here, because 
again, Swift is not C or C++: we need to be able to answer that question even 
in generic code rather than relying on the ability to fold all computations 
statically.  We do not want to add an algebraic solver to 

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-07-31 Thread John McCall via swift-evolution
> On Jul 31, 2017, at 3:58 AM, Félix Cloutier  wrote:
> It seems to me that this applies just the same to type generic parameters. 
> Are there any reason that you can't instantiate a generic type at runtime, or 
> is it just because the need is not as evident as it would/could be with 
> non-type generic parameters?

Are you under the impression that Swift does not, today, instantiate generic 
types at runtime?

A lot of this entire thread seems to be premised on really weird, incorrect 
assumptions about the Swift compilation model.

John.

> 
>> Le 30 juil. 2017 à 21:10, John McCall via swift-evolution 
>>  a écrit :
>> 
>>> On Jul 30, 2017, at 11:43 PM, Daryle Walker  wrote:
>>> The parameters for a fixed-size array type determine the type's 
>>> size/stride, so how could the bounds not be needed during compile-time? The 
>>> compiler can't layout objects otherwise. 
>> 
>> Swift is not C; it is perfectly capable of laying out objects at run time.  
>> It already has to do that for generic types and types with resilient 
>> members.  That does, of course, have performance consequences, and those 
>> performance consequences might be unacceptable to you; but the fact that we 
>> can handle it means that we don't ultimately require a semantic concept of a 
>> constant expression, except inasmuch as we want to allow users to explicitly 
>> request guarantees about static layout.
>> 
>> Value equality would still affect the type-checker, but I think we could 
>> pretty easily just say that all bound expressions are assumed to potentially 
>> resolve unequally unless they are literals or references to the same 'let' 
>> constant.
>> 
>> The only hard constraint is that types need to be consistent, but that just 
>> means that we need to have a model in which bound expressions are evaluated 
>> exactly once at runtime (and of course typically folded at compile time).
>> 
>> John.
>> 
>>> Or do you mean that the bounds are integer literals? (That's what I have in 
>>> the design document now.)
>>> 
>>> Sent from my iPhone
>>> 
>>> On Jul 30, 2017, at 8:51 PM, John McCall  wrote:
>>> 
>>>>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>>>>  wrote:
>>>>> The “constexpr” facility from C++ allows users to define constants and 
>>>>> functions that are determined and usable at compile-time, for 
>>>>> compile-time constructs but still usable at run-time. The facility is a 
>>>>> key step for value-based generic parameters (and fixed-size arrays if you 
>>>>> don’t want to be stuck with integer literals for bounds). Can figuring 
>>>>> out Swift’s story here be part of Swift 5?
>>>> 
>>>> Note that there's no particular reason that value-based generic 
>>>> parameters, including fixed-size arrays, actually need to be constant 
>>>> expressions in Swift.
>>>> 
>>>> John.
>> 
>> ___
>> 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-07-30 Thread John McCall via swift-evolution
> On Jul 30, 2017, at 11:43 PM, Daryle Walker  wrote:
> The parameters for a fixed-size array type determine the type's size/stride, 
> so how could the bounds not be needed during compile-time? The compiler can't 
> layout objects otherwise. 

Swift is not C; it is perfectly capable of laying out objects at run time.  It 
already has to do that for generic types and types with resilient members.  
That does, of course, have performance consequences, and those performance 
consequences might be unacceptable to you; but the fact that we can handle it 
means that we don't ultimately require a semantic concept of a constant 
expression, except inasmuch as we want to allow users to explicitly request 
guarantees about static layout.

Value equality would still affect the type-checker, but I think we could pretty 
easily just say that all bound expressions are assumed to potentially resolve 
unequally unless they are literals or references to the same 'let' constant.

The only hard constraint is that types need to be consistent, but that just 
means that we need to have a model in which bound expressions are evaluated 
exactly once at runtime (and of course typically folded at compile time).

John.

> Or do you mean that the bounds are integer literals? (That's what I have in 
> the design document now.)
> 
> Sent from my iPhone
> 
> On Jul 30, 2017, at 8:51 PM, John McCall  wrote:
> 
>>> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>>>  wrote:
>>> The “constexpr” facility from C++ allows users to define constants and 
>>> functions that are determined and usable at compile-time, for compile-time 
>>> constructs but still usable at run-time. The facility is a key step for 
>>> value-based generic parameters (and fixed-size arrays if you don’t want to 
>>> be stuck with integer literals for bounds). Can figuring out Swift’s story 
>>> here be part of Swift 5?
>> 
>> Note that there's no particular reason that value-based generic parameters, 
>> including fixed-size arrays, actually need to be constant expressions in 
>> Swift.
>> 
>> John.

___
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-07-30 Thread John McCall via swift-evolution
> On Jul 29, 2017, at 7:01 PM, Daryle Walker via swift-evolution 
>  wrote:
> The “constexpr” facility from C++ allows users to define constants and 
> functions that are determined and usable at compile-time, for compile-time 
> constructs but still usable at run-time. The facility is a key step for 
> value-based generic parameters (and fixed-size arrays if you don’t want to be 
> stuck with integer literals for bounds). Can figuring out Swift’s story here 
> be part of Swift 5?

Note that there's no particular reason that value-based generic parameters, 
including fixed-size arrays, actually need to be constant expressions in Swift.

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


Re: [swift-evolution] Why couldn't a class call any of its superclass' initializers?

2017-07-25 Thread John McCall via swift-evolution
> On Jul 26, 2017, at 12:36 AM, Daryle Walker via swift-evolution 
>  wrote:
> [Sorry if this's been discussed before.]
> 
> As long as the superclass sub-object gets initialized, it shouldn't matter if 
> the initializer was designated or convenience. Is there some subtle step on 
> the two-phase initialization I'm missing? Or is this a point to extend in a 
> future version of Swift?

Convenience initializers are complete-object initializers.  A sub-object 
initializer from a subclass cannot delegate to a complete-object initializer 
from its superclass because that would re-initialize all the subclass 
sub-objects.

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


Re: [swift-evolution] Pitch: Wrap calls to NSFileHandle and NSData in autorelease pools

2017-07-14 Thread John McCall via swift-evolution

> On Jul 14, 2017, at 4:43 PM, Charles Srstka  wrote:
> 
>> On Jul 14, 2017, at 3:40 PM, John McCall > > wrote:
>> 
>> Would you mind just filing a bug with a reduced test case?
>> 
>> John.
> 
> Radar or bugs.swift.org ?

Either would be fine, assuming your test case doesn't need to be confidential.

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


Re: [swift-evolution] Pitch: Wrap calls to NSFileHandle and NSData in autorelease pools

2017-07-14 Thread John McCall via swift-evolution

> On Jul 14, 2017, at 4:15 PM, Charles Srstka  wrote:
> 
>> On Jul 14, 2017, at 2:35 PM, John McCall > > wrote:
>> 
>>> On Jul 14, 2017, at 1:12 PM, Charles Srstka via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> MOTIVATION:
>>> 
>>> Meet Bob. Bob is a developer with mostly C++ and Java experience, but who 
>>> has been learning Swift. Bob needs to write an app to parse some 
>>> proprietary binary data format that his company requires. Bob’s written 
>>> this app, and it’s worked pretty well on Linux:
>>> 
>>> import Foundation
>>> 
>>> do {
>>> let url = ...
>>> 
>>> let handle = try FileHandle(forReadingFrom: url)
>>> let bufsize = 1024 * 1024 // read 1 MiB at a time
>>> 
>>> while true {
>>> let data = handle.readData(ofLength: bufsize)
>>> 
>>> if data.isEmpty {
>>> break
>>> }
>>> 
>>> data.withUnsafeBytes { (bytes: UnsafePointer) in
>>> // do something with bytes
>>> }
>>> }
>>> } catch {
>>> print("Error occurred: \(error.localizedDescription)")
>>> }
>>> 
>>> Later, Bob needs to port this same app to macOS. All seems to work well, 
>>> until Bob tries opening a large file of many gigabytes in size. Suddenly, 
>>> the simple act of running the app causes Bob’s Mac to completely lock up, 
>>> beachball, and finally pop up with the dreaded “This computer is out of 
>>> system memory” message. If Bob’s particularly unlucky, things will locked 
>>> up tight enough that he can’t even recover from there, and may have to 
>>> hard-reboot the machine.
>>> 
>>> What happened?
>>> 
>>> Experienced Objective-C developers will spot the problem right away; the 
>>> Foundation APIs that Bob used generated autoreleased objects, which would 
>>> never be released until Bob’s loop finished. However, Bob’s never 
>>> programmed in Objective-C, and to him, this behavior is completely 
>>> undecipherable.
>>> 
>>> After a copious amount of time spent Googling for answers and asking for 
>>> help on various mailing lists and message boards, Bob finally gets the 
>>> recommendation from someone to try wrapping the file handle read in an 
>>> autorelease pool. So he does:
>>> 
>>> import Foundation
>>> 
>>> do {
>>> let url = ...
>>> 
>>> let handle = try FileHandle(forReadingFrom: url)
>>> let bufsize = 1024 * 1024 // read 1 MiB at a time
>>> 
>>> while true {
>>> let data = autoreleasepool { handle.readData(ofLength: bufsize) }
>>> 
>>> if data.isEmpty {
>>> break
>>> }
>>> 
>>> data.withUnsafeBytes { (bytes: UnsafePointer) in
>>> // do something with bytes
>>> }
>>> }
>>> } catch {
>>> print("Error occurred: \(error.localizedDescription)")
>>> }
>>> 
>>> Unfortunately, Bob’s program still eats RAM like Homer Simpson in an 
>>> all-you-can-eat buffet. Turns out the data.withUnsafeBytes call *also* 
>>> causes the data to be autoreleased.
>> 
>> This seems like a bug that should be fixed.  I don't know why the other one 
>> would cause an unreclaimable autorelease.
> 
> Sticking a break at the end of my original code snippet so the loop runs only 
> once and then running it through Instruments, it seems the NSConcreteData 
> instance gets autoreleased… 32,769 times. o_O
> 
> First autorelease occurs inside -[NSConcreteFileHandle readDataOfLength:], 
> the next 32,768 occur in Data.Iterator.next(), which is called by specialized 
> RangeReplaceableCollection.init.
> 
> I can send you the trace off-list if you’d like.

We should absolutely not need to do the later autoreleases.  We have logic to 
autorelease objects when calling returns-inner-pointer objects on them, but we 
shouldn't need to do that in safe patterns like what Data does here by scoping 
the pointer to the closure.  We probably just don't actually have a way to turn 
that logic off, i.e. an equivalent of objc_precise_lifetime in ObjC ARC.

I have no idea why the first autorelease wouldn't be reclaimed.  There's a 
well-known issue with micro-reductions involving autoreleases on x86, where the 
first autorelease from the executable doesn't get reclaimed because the dynamic 
linker's lazy-binding stub interferes somehow.  Can you verify that you still 
see that initial autorelease on subsequent Data creations?

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


Re: [swift-evolution] Pitch: Wrap calls to NSFileHandle and NSData in autorelease pools

2017-07-14 Thread John McCall via swift-evolution
> On Jul 14, 2017, at 4:31 PM, Charles Srstka  wrote:
>> On Jul 14, 2017, at 3:24 PM, John McCall > > wrote:
>> 
>> We should absolutely not need to do the later autoreleases.  We have logic 
>> to autorelease objects when calling returns-inner-pointer objects on them, 
>> but we shouldn't need to do that in safe patterns like what Data does here 
>> by scoping the pointer to the closure.  We probably just don't actually have 
>> a way to turn that logic off, i.e. an equivalent of objc_precise_lifetime in 
>> ObjC ARC.
>> 
>> I have no idea why the first autorelease wouldn't be reclaimed.  There's a 
>> well-known issue with micro-reductions involving autoreleases on x86, where 
>> the first autorelease from the executable doesn't get reclaimed because the 
>> dynamic linker's lazy-binding stub interferes somehow.  Can you verify that 
>> you still see that initial autorelease on subsequent Data creations?
> 
> Changing the loop to run five times, I end up with five NSConcreteDatas in 
> Instruments. For the first one, I get the initial autorelease in 
> -[NSConcreteFileHandle readDataOfLength], as well as the subsequent 32,768 
> autoreleases (it actually seems to be one autorelease per every 32 bytes in 
> the data; if I adjust the buffer size the number of autoreleases changes 
> accordingly). 
> 
> For the other four… it looks exactly the same, actually. :-/
> 
> Instruments .trace file is available off-list by request.

Would you mind just filing a bug with a reduced test case?

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


Re: [swift-evolution] Pitch: Wrap calls to NSFileHandle and NSData in autorelease pools

2017-07-14 Thread John McCall via swift-evolution
> On Jul 14, 2017, at 1:12 PM, Charles Srstka via swift-evolution 
>  wrote:
> MOTIVATION:
> 
> Meet Bob. Bob is a developer with mostly C++ and Java experience, but who has 
> been learning Swift. Bob needs to write an app to parse some proprietary 
> binary data format that his company requires. Bob’s written this app, and 
> it’s worked pretty well on Linux:
> 
> import Foundation
> 
> do {
> let url = ...
> 
> let handle = try FileHandle(forReadingFrom: url)
> let bufsize = 1024 * 1024 // read 1 MiB at a time
> 
> while true {
> let data = handle.readData(ofLength: bufsize)
> 
> if data.isEmpty {
> break
> }
> 
> data.withUnsafeBytes { (bytes: UnsafePointer) in
> // do something with bytes
> }
> }
> } catch {
> print("Error occurred: \(error.localizedDescription)")
> }
> 
> Later, Bob needs to port this same app to macOS. All seems to work well, 
> until Bob tries opening a large file of many gigabytes in size. Suddenly, the 
> simple act of running the app causes Bob’s Mac to completely lock up, 
> beachball, and finally pop up with the dreaded “This computer is out of 
> system memory” message. If Bob’s particularly unlucky, things will locked up 
> tight enough that he can’t even recover from there, and may have to 
> hard-reboot the machine.
> 
> What happened?
> 
> Experienced Objective-C developers will spot the problem right away; the 
> Foundation APIs that Bob used generated autoreleased objects, which would 
> never be released until Bob’s loop finished. However, Bob’s never programmed 
> in Objective-C, and to him, this behavior is completely undecipherable.
> 
> After a copious amount of time spent Googling for answers and asking for help 
> on various mailing lists and message boards, Bob finally gets the 
> recommendation from someone to try wrapping the file handle read in an 
> autorelease pool. So he does:
> 
> import Foundation
> 
> do {
> let url = ...
> 
> let handle = try FileHandle(forReadingFrom: url)
> let bufsize = 1024 * 1024 // read 1 MiB at a time
> 
> while true {
> let data = autoreleasepool { handle.readData(ofLength: bufsize) }
> 
> if data.isEmpty {
> break
> }
> 
> data.withUnsafeBytes { (bytes: UnsafePointer) in
> // do something with bytes
> }
> }
> } catch {
> print("Error occurred: \(error.localizedDescription)")
> }
> 
> Unfortunately, Bob’s program still eats RAM like Homer Simpson in an 
> all-you-can-eat buffet. Turns out the data.withUnsafeBytes call *also* causes 
> the data to be autoreleased.

This seems like a bug that should be fixed.  I don't know why the other one 
would cause an unreclaimable autorelease.

John.

> What Bob really needs to do is to wrap the whole thing in an autorelease 
> pool, creating a Pyramid of Doom:
> 
> import Foundation
> 
> do {
> let url = ...
> 
> let handle = try FileHandle(forReadingFrom: url)
> let bufsize = 1024 * 1024 // read 1 MiB at a time
> 
> while true {
> autoreleasepool {
> let data = handle.readData(ofLength: bufsize)
> 
> if data.isEmpty {
> break // error: ‘break’ is allowed only inside a loop, if, 
> do, or switch
> }
> 
> data.withUnsafeBytes { (bytes: UnsafePointer) in
> // do something with bytes
> }
> }
> }
> } catch {
> print("Error occurred: \(error.localizedDescription)")
> }
> 
> However, when Bob tries to run this, he now gets a compile error on the 
> ‘break’ statement; it’s no longer possible to break out of the loop, since 
> everything inside the autorelease block is in a closure.
> 
> Bob is now regretting his decision not to become an insurance adjuster 
> instead.
> 
> Bob’s problem, of course, can be solved by using *two* autorelease pools, one 
> when getting the data, and the next when working with it. But this situation 
> is confusing to newcomers to the language, since autorelease pools are not 
> really part of Swift’s idiom, and aren’t mentioned anywhere in the usual 
> Swift documentation. Thus, without Objective-C experience, 
> autorelease-related issues are completely mysterious and baffling, 
> particularly since, as a struct, it isn’t obvious that Objective-C will be 
> involved at all when using the Data type. Even to experienced Objective-C 
> developers, autorelease pools in Swift can become awkward since, unlike with 
> Objective-C, they can’t simply be tacked onto a loop without losing flow 
> control via break and continue.
> 
> PROPOSED SOLUTION:
> 
> In the Foundation overlay, wrap calls to Objective-C NSFileHandle and NSData 
> APIs that generate autoreleased objects in an autorelease pool, so that they 
> behave the way a user new to the language would expect, and in a manner 
> consisten

Re: [swift-evolution] [Proposal] Introduces endianness specific type

2017-07-09 Thread John McCall via swift-evolution
> On Jul 9, 2017, at 6:57 PM, Robert Bennett  wrote:
> Just a question: how would/does allowing the reordering of fields affect the 
> correctness and performance of the (de)serialization API added in Swift 4?

The design of that is definitely proof against changes to the in-memory layout 
of the type.  I believe it's also proof against reordering but I'm not entirely 
certain about that.

John.

> 
> On Jul 9, 2017, at 6:21 PM, Jens Persson via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> Thanks for that clarification John McCall.
>> My code is using a lot of generic structs (in which memory layout is 
>> important) though, an example would be:
>> struct Vector4 : Vector {
>> typealias Index = VectorIndex4
>> typealias Element = E
>> var e0, e1, e2, e3: Element
>> …
>> }
>> And I guess I'm out of luck trying to represent those as C structs?
>> So AFAICS it looks like it is currently impossible to write generic low 
>> level code in Swift, unless I just keep doing what I've been doing (It does 
>> currently work after all) knowing that it will probably break in some future 
>> versions of Swift. But in that possible future version of Swift, I could 
>> probably find a way to make it work again (using some possible explicit 
>> tools for layout control present in that version of Swift).
>> Correct?
>> /Jens
>> 
>> 
>> On Sun, Jul 9, 2017 at 11:41 PM, John McCall > > wrote:
>> 
>>> On Jul 9, 2017, at 4:49 PM, Jens Persson via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Sorry for making so much off topic noise in this thread, but I made a 
>>> mistake regarding the Metal tutorial:
>>> Looking more carefully I see now that they rebuild a vertedData: [Float] 
>>> from their vertices: [Vertex] using the floatBuffer() method of the Vertex 
>>> struct, which returns an Array with the stored properties of Vertex in 
>>> correct order.
>>> 
>>> While searching the internet about this I saw Joe Groff mentioning on 
>>> Twitter that:
>>> "We plan to sort fields in padding order to minimize size, and may also 
>>> automatically pack bools and enums in bitfields."
>>> 
>>> So AFAICS my current image processing code is making the possibly invalid 
>>> assumption that eg
>>> struct S {
>>> var a, b, c, d: Float
>>> }
>>> will have a memory layout of 4*4=16 bytes (stride and size == 16) and an 
>>> alignment of 4, and most importantly that a, b, c, d will be in that order.
>> 
>> This is currently true, but may not always be.  We want to reserve the right 
>> to re-order the fields even if it doesn't improve packing — for example, if 
>> two fields are frequently accessed together, field reordering could yield 
>> substantial locality benefits.  We've also discussed reordering fields to 
>> put them in a canonical order for resilience, since it's a little 
>> counter-intuitive that reordering the fields of a struct should be 
>> ABI-breaking.  (There are arguments against doing that as well, of course — 
>> for example, the programmer may have chosen the current order for their own 
>> locality optimizations.)
>> 
>>> It looks like I should be defining my structs (the ones for which memory 
>>> layout is important) in C and import them.
>> 
>> This should always work, yes.
>> 
>>> Although I would be surprised if a Swift-struct containing only same-sized 
>>> fields (all of the same primitive type) would be reordered, and such 
>>> changes to the language would probably include some per-struct way to 
>>> express some sort of layout control (since being able to define structs to 
>>> be used for low level data manipulation is important in a systems language).
>> 
>> Exactly.  In the long term, Swift will have some explicit tools for layout 
>> control.
>> 
>> John.
>> 
>>> 
>>> /Jens
>>> 
>>> 
>>> On Sun, Jul 9, 2017 at 7:01 PM, Jens Persson via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> I should perhaps add that in my image processing code, I use code like this:
>>> 
>>> func withVImageBuffer(for table: Table, body: 
>>> (vImage_Buffer) -> R) -> R
>>> where
>>> Data.Coordinate.Index == VectorIndex2
>>> {
>>> let vib = vImage_Buffer(
>>> data: table.baseAddress,
>>> height: vImagePixelCount(table.size.e1),
>>> width: vImagePixelCount(table.size.e0),
>>> rowBytes: table.stride.e1
>>> )
>>> return withExtendedLifetime(table) { body(vib) }
>>> }
>>> 
>>> Here, Table is the raster image. Data.Coordinate == VectorIndex2 
>>> makes it a 2D table, and a Table's Data also has a type parameter 
>>> Data.Value which can be eg one of the "pixel"-struct I showed before.
>>> This works without any problems (I've tested and used the some variant of 
>>> this type of code for years) but it would surely break if the memory layout 
>>> of simple structs changed.
>>> 
>>> I can't see how this usage is much different from the one in the Metal 
>>> tutorial. It too uses po

Re: [swift-evolution] [Proposal] Introduces endianness specific type

2017-07-09 Thread John McCall via swift-evolution

> On Jul 9, 2017, at 6:14 PM, Jens Persson  wrote:
> 
> Thanks for that clarification John McCall.
> My code is using a lot of generic structs (in which memory layout is 
> important) though, an example would be:
> struct Vector4 : Vector {
> typealias Index = VectorIndex4
> typealias Element = E
> var e0, e1, e2, e3: Element
> …
> }
> And I guess I'm out of luck trying to represent those as C structs?
> So AFAICS it looks like it is currently impossible to write generic low level 
> code in Swift, unless I just keep doing what I've been doing (It does 
> currently work after all) knowing that it will probably break in some future 
> versions of Swift. But in that possible future version of Swift, I could 
> probably find a way to make it work again (using some possible explicit tools 
> for layout control present in that version of Swift).
> Correct?

Correct.

John.

> /Jens
> 
> 
> On Sun, Jul 9, 2017 at 11:41 PM, John McCall  > wrote:
> 
>> On Jul 9, 2017, at 4:49 PM, Jens Persson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Sorry for making so much off topic noise in this thread, but I made a 
>> mistake regarding the Metal tutorial:
>> Looking more carefully I see now that they rebuild a vertedData: [Float] 
>> from their vertices: [Vertex] using the floatBuffer() method of the Vertex 
>> struct, which returns an Array with the stored properties of Vertex in 
>> correct order.
>> 
>> While searching the internet about this I saw Joe Groff mentioning on 
>> Twitter that:
>> "We plan to sort fields in padding order to minimize size, and may also 
>> automatically pack bools and enums in bitfields."
>> 
>> So AFAICS my current image processing code is making the possibly invalid 
>> assumption that eg
>> struct S {
>> var a, b, c, d: Float
>> }
>> will have a memory layout of 4*4=16 bytes (stride and size == 16) and an 
>> alignment of 4, and most importantly that a, b, c, d will be in that order.
> 
> This is currently true, but may not always be.  We want to reserve the right 
> to re-order the fields even if it doesn't improve packing — for example, if 
> two fields are frequently accessed together, field reordering could yield 
> substantial locality benefits.  We've also discussed reordering fields to put 
> them in a canonical order for resilience, since it's a little 
> counter-intuitive that reordering the fields of a struct should be 
> ABI-breaking.  (There are arguments against doing that as well, of course — 
> for example, the programmer may have chosen the current order for their own 
> locality optimizations.)
> 
>> It looks like I should be defining my structs (the ones for which memory 
>> layout is important) in C and import them.
> 
> This should always work, yes.
> 
>> Although I would be surprised if a Swift-struct containing only same-sized 
>> fields (all of the same primitive type) would be reordered, and such changes 
>> to the language would probably include some per-struct way to express some 
>> sort of layout control (since being able to define structs to be used for 
>> low level data manipulation is important in a systems language).
> 
> Exactly.  In the long term, Swift will have some explicit tools for layout 
> control.
> 
> John.
> 
>> 
>> /Jens
>> 
>> 
>> On Sun, Jul 9, 2017 at 7:01 PM, Jens Persson via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> I should perhaps add that in my image processing code, I use code like this:
>> 
>> func withVImageBuffer(for table: Table, body: (vImage_Buffer) 
>> -> R) -> R
>> where
>> Data.Coordinate.Index == VectorIndex2
>> {
>> let vib = vImage_Buffer(
>> data: table.baseAddress,
>> height: vImagePixelCount(table.size.e1),
>> width: vImagePixelCount(table.size.e0),
>> rowBytes: table.stride.e1
>> )
>> return withExtendedLifetime(table) { body(vib) }
>> }
>> 
>> Here, Table is the raster image. Data.Coordinate == VectorIndex2 makes 
>> it a 2D table, and a Table's Data also has a type parameter Data.Value which 
>> can be eg one of the "pixel"-struct I showed before.
>> This works without any problems (I've tested and used the some variant of 
>> this type of code for years) but it would surely break if the memory layout 
>> of simple structs changed.
>> 
>> I can't see how this usage is much different from the one in the Metal 
>> tutorial. It too uses pointers to point into a data created using the 
>> (Swift) struct "Vertex", and the GPU hardware has its expectations on the 
>> memory layout of that data, so the code would break if the memory layout of 
>> the Vertex struct changed.
>> 
>> /Jens
>> 
>> 
>> On Sun, Jul 9, 2017 at 6:35 PM, Jens Persson > > wrote:
>> I don't think I'm misunderstanding you, but I might be, so I'll add more 
>> detail:
>> 
>> If you look at the Metal article, you'll see that the (Swift) struct 
>> "Vertex" is used to specify the dat

Re: [swift-evolution] [Proposal] Introduces endianness specific type

2017-07-09 Thread John McCall via swift-evolution

> On Jul 9, 2017, at 4:49 PM, Jens Persson via swift-evolution 
>  wrote:
> 
> Sorry for making so much off topic noise in this thread, but I made a mistake 
> regarding the Metal tutorial:
> Looking more carefully I see now that they rebuild a vertedData: [Float] from 
> their vertices: [Vertex] using the floatBuffer() method of the Vertex struct, 
> which returns an Array with the stored properties of Vertex in correct order.
> 
> While searching the internet about this I saw Joe Groff mentioning on Twitter 
> that:
> "We plan to sort fields in padding order to minimize size, and may also 
> automatically pack bools and enums in bitfields."
> 
> So AFAICS my current image processing code is making the possibly invalid 
> assumption that eg
> struct S {
> var a, b, c, d: Float
> }
> will have a memory layout of 4*4=16 bytes (stride and size == 16) and an 
> alignment of 4, and most importantly that a, b, c, d will be in that order.

This is currently true, but may not always be.  We want to reserve the right to 
re-order the fields even if it doesn't improve packing — for example, if two 
fields are frequently accessed together, field reordering could yield 
substantial locality benefits.  We've also discussed reordering fields to put 
them in a canonical order for resilience, since it's a little counter-intuitive 
that reordering the fields of a struct should be ABI-breaking.  (There are 
arguments against doing that as well, of course — for example, the programmer 
may have chosen the current order for their own locality optimizations.)

> It looks like I should be defining my structs (the ones for which memory 
> layout is important) in C and import them.

This should always work, yes.

> Although I would be surprised if a Swift-struct containing only same-sized 
> fields (all of the same primitive type) would be reordered, and such changes 
> to the language would probably include some per-struct way to express some 
> sort of layout control (since being able to define structs to be used for low 
> level data manipulation is important in a systems language).

Exactly.  In the long term, Swift will have some explicit tools for layout 
control.

John.

> 
> /Jens
> 
> 
> On Sun, Jul 9, 2017 at 7:01 PM, Jens Persson via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> I should perhaps add that in my image processing code, I use code like this:
> 
> func withVImageBuffer(for table: Table, body: (vImage_Buffer) 
> -> R) -> R
> where
> Data.Coordinate.Index == VectorIndex2
> {
> let vib = vImage_Buffer(
> data: table.baseAddress,
> height: vImagePixelCount(table.size.e1),
> width: vImagePixelCount(table.size.e0),
> rowBytes: table.stride.e1
> )
> return withExtendedLifetime(table) { body(vib) }
> }
> 
> Here, Table is the raster image. Data.Coordinate == VectorIndex2 makes 
> it a 2D table, and a Table's Data also has a type parameter Data.Value which 
> can be eg one of the "pixel"-struct I showed before.
> This works without any problems (I've tested and used the some variant of 
> this type of code for years) but it would surely break if the memory layout 
> of simple structs changed.
> 
> I can't see how this usage is much different from the one in the Metal 
> tutorial. It too uses pointers to point into a data created using the (Swift) 
> struct "Vertex", and the GPU hardware has its expectations on the memory 
> layout of that data, so the code would break if the memory layout of the 
> Vertex struct changed.
> 
> /Jens
> 
> 
> On Sun, Jul 9, 2017 at 6:35 PM, Jens Persson  > wrote:
> I don't think I'm misunderstanding you, but I might be, so I'll add more 
> detail:
> 
> If you look at the Metal article, you'll see that the (Swift) struct "Vertex" 
> is used to specify the data that is sent to Metal for creating a buffer 
> (using MTLDevice.makeBuffer). The result that the GPU will produce surely 
> depends on the fields of the Vertex struct (x, y, z, r, g, b, a) being in the 
> specified order (ie swapping the red channel with the x coordinate would 
> produce an unexpected result).
> 
> And regarding the second example, pixel structs used for manipulating raster 
> image data. Manipulating raster image data presumably includes stuff like 
> displaying to screen, loading and saving raster images.
> I currently use this way of doing this right now without any problems, but if 
> the order of the fields (eg a, r, g, b) should change in the future, then my 
> code would break (the colors of the images would at least not come out as 
> expected).
> 
> /Jens
> 
> 
> 
> 
> 
> 
> On Sun, Jul 9, 2017 at 5:53 PM, Chris Lattner  > wrote:
> 
>> On Jul 9, 2017, at 12:23 AM, Jens Persson > > wrote:
>> 
>> 
>> On Sat, Jul 8, 2017 at 6:28 PM, Chris Lattner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> Hi Susan,
>> 
>> Swift does not currently 

[swift-evolution] [Accepted] SE-0180: String Index Overhaul

2017-07-08 Thread John McCall via swift-evolution
Proposal Link: 
https://github.com/apple/swift-evolution/blob/master/proposals/0180-string-index-overhaul.md
 


The second review of “SE-0180: String Index Overhaul" ran from June 22nd – 
28th, 2017.

The proposal is accepted.  There was a lively discussion about it, but in the 
end everyone seems to agree that this is the right thing to do.

As always, I'd like to thank you for your help in making Swift a better 
language.

John McCall
Core Team___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Object aliases

2017-07-03 Thread John McCall via swift-evolution
> On Jun 30, 2017, at 4:55 AM, Daryle Walker  wrote:
>> On Jun 30, 2017, at 1:11 AM, John McCall > > wrote:
>> 
>>> 
>>> On Jun 23, 2017, at 3:28 AM, Daryle Walker via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Swift is currently an alias-adverse language. The model for the equivalent 
>>> of pointers is supposed to be for short-term use, and not persisted. Other 
>>> constructs that would use references: read-write properties, read-write 
>>> subscripts, and inout function parameters, can all be implemented by 
>>> copy-in-then-copy-out, presumably to avoid alias dynamics and its 
>>> anti-optimizations. So the scope of aliases here will be limited to 
>>> local-scale renaming of object locations that the compiler can connect 
>>> statically.
>>> Yes, the use case is currently weak, but it is a stepping stone for 
>>> stronger cases, like changing the interface of an object with (currently 
>>> not in the language) strong type-aliases without copies.
>>> 
>> 
>> We usually expect language features to stand on their own.  Certainly 
>> something as core as a new kind of declaration would be expected to.
>> 
>> Anyway, this feature is rather similar to what I called a "local ephemeral 
>> binding" in the ownership proposal, except that your alias does not access 
>> the referenced storage until it itself is accessed.  Unfortunately, this 
>> actually makes it *more* complex, rather than less, as it creates a new way 
>> to abstract over storage, including local storage.
> 
> I was thinking posing aliases would be like symbolic substitution; we could 
> replace the alias with the text defining its source expression everywhere and 
> there should be no efficiency change. But I would want any evaluation of the 
> (sub-)object’s location to be computed once; is that where complexity could 
> come in? I was hoping that object location determination could be done at 
> compile-time; that’s the reason for restricting what kinds of objects can be 
> a source object.

I'm always wary of features that require a ton of restrictions because they can 
only be implemented using a sort of preprocessing.  Among other things, it 
suggests that they cannot possibly be made resilient.

I think a better way of thinking of your feature is as sugar on top of the 
generalized accessors feature from ownership — that is, a concise way to 
declare a var/subscript with accessors that automatically forward to some other 
entity, e.g.:

  var values: [Value]
  alias var count: Int = values.count
  alias subscript(i: Int) -> Value = values[i]

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


Re: [swift-evolution] [Pitch] Object aliases

2017-06-29 Thread John McCall via swift-evolution

> On Jun 23, 2017, at 3:28 AM, Daryle Walker via swift-evolution 
>  wrote:
> 
> I started a thread earlier this week about strong type-aliases and object 
> aliases. Here’s a fuller proposal on object aliases.
> 
> Feature name
> Proposal: SE- 
> Authors: Daryle Walker , Author 2 
> 
> Review Manager: TBD
> Status: Awaiting review
> During the review process, add the following fields as needed:
> 
> Decision Notes: Rationale 
> , Additional Commentary 
> 
> Bugs: SR- , SR- 
> 
> Previous Revision: 1 
> 
> Previous Proposal: SE- 
> Introduction
> This is a proposal to define aliases to objects.
> 
> Swift-evolution thread: 1 
> 
> Motivation
> Aliasing allows a named object to actually refer to another object instead of 
> newly-allocated storage. Referring to an object with a simple name isn't very 
> useful, but referring to an object needing a complex expression to point to 
> it can help with reducing typing.
> 
> However, aliasing has a cost. Compilers have to make certain assumptions if 
> objects can have multiple names referring to them, and these assumptions 
> reduce what kinds of optimizations can be made.
> 
> Language design can make a difference in how code can be optimized. Languages 
> like C and C++ assume aliasing is allowed by default, limiting how many 
> optimizations can be done. More recent versions of C have a keyword 
> ("restrict") to ban certain objects from aliasing. Other languages go the 
> other way; you need to take extra measures to alias objects, since object 
> handling bars aliasing by default.
> 
> Swift is currently an alias-adverse language. The model for the equivalent of 
> pointers is supposed to be for short-term use, and not persisted. Other 
> constructs that would use references: read-write properties, read-write 
> subscripts, and inout function parameters, can all be implemented by 
> copy-in-then-copy-out, presumably to avoid alias dynamics and its 
> anti-optimizations. So the scope of aliases here will be limited to 
> local-scale renaming of object locations that the compiler can connect 
> statically.
> 
> Yes, the use case is currently weak, but it is a stepping stone for stronger 
> cases, like changing the interface of an object with (currently not in the 
> language) strong type-aliases without copies.
> 

We usually expect language features to stand on their own.  Certainly something 
as core as a new kind of declaration would be expected to.

Anyway, this feature is rather similar to what I called a "local ephemeral 
binding" in the ownership proposal, except that your alias does not access the 
referenced storage until it itself is accessed.  Unfortunately, this actually 
makes it *more* complex, rather than less, as it creates a new way to abstract 
over storage, including local storage.

John.
> Proposed solution
> The solution is to introduce a new kind of object declaration. It uses a new 
> keyword pose in the same place as let or var. It must be initialized with an 
> expression that specifies an object, and be typed with a layout-compatible 
> type (like the unsafeBitCast function).
> 
> struct Sample {
> var test1 = (1, 2, 3, "apple")
> //...
> func trial1() {
> pose firstTestNumber = test1.0
> print(firstTestNumber)  // prints "1"
> //...
> firstTestNumber = 4
> print(test1.0)  // prints "4"
> }
> }
> When an object is used, the compiler associates the object with some sort of 
> location ID. An alias just reuses its original's ID instead of having one of 
> its own.
> 
> Here, the substitution is simple, but longer chains are imaginable. With a 
> local-scope limitation, aliases work kind-of like macro constants in C.
> 
> Detailed design
> Add to the "Grammar of a Declaration":
> 
> declaration → alias-declaration
> Add a new section "Grammar of an Alias Declaration":
> 
> alias-declaration → attributes_opt declaration-modifiers_optpose 
> pattern-initializer-list
> An alias declaration can only be in the local scope of a function. 
> Expressions that describe source objects must be:
> 
> a named object, including function parameters
> a member of a qualifying tuple object
> a stored property of a qualifying struct (or class?) object
> A source object must have a lifetime at least as long as any aliases to it. A 
> source object cannot have willSet and/or didSetobservers. The alias poses as 
> an object of its type annotation, defaulting to the source object's type if 
> omitted. An annotation must be of the source object's type or a 
> layout-compatible typ

Re: [swift-evolution] floating point numbers implicit conversion

2017-06-19 Thread John McCall via swift-evolution
> On Jun 19, 2017, at 5:43 PM, David Sweeris  wrote:
> Sent from my iPhone
> On Jun 19, 2017, at 13:44, John McCall via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>>> On Jun 19, 2017, at 1:58 PM, Stephen Canon via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>>> On Jun 19, 2017, at 11:46 AM, Ted F.A. van Gaalen via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> var result: Float = 0.0
>>>> result = float * integer * uint8 +  double   
>>>> // here, all operands should be implicitly promoted to Double before the 
>>>> complete expression evaluation.
>>> 
>>> You would have this produce different results than:
>>> 
>>> let temp = float * integer * uint8
>>> result = temp + double
>>> 
>>> That would be extremely surprising to many unsuspecting users.
>>> 
>>> Don’t get me wrong; I *really want* implicit promotions (I proposed one 
>>> scheme for them  way back when Swift was first unveiled publicly).
>> 
>> I don't!  At least not for floating point.  It is important for both 
>> reliable behavior and performance that programmers understand and minimize 
>> the conversions they do between different floating-point types.
> 
> How expensive is it?

If memory serves, it's not usually ruinously expensive on its own, but there 
tend to not be very many functional units for it, and it doesn't get pipelined 
very well.  Essentially, micro-architects often assume that well-written FP 
code is not doing a significant number of FP conversions.  Even if it were very 
cheap, it would still be an unnecessary operation in the pipeline.

It's a well-known source of performance bugs in C to accidentally use 1.0 
instead of 1.0f in the middle of some complex expression that's heavily working 
with floats.  A bunch of intermediate computations ends up getting done in 
double, and unlike the analogous situation with integers, it's not really 
possible for the compiler to automatically figure out that it can do them in 
float instead.

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


Re: [swift-evolution] floating point numbers implicit conversion

2017-06-19 Thread John McCall via swift-evolution
> On Jun 19, 2017, at 1:58 PM, Stephen Canon via swift-evolution 
>  wrote:
>> On Jun 19, 2017, at 11:46 AM, Ted F.A. van Gaalen via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> var result: Float = 0.0
>> result = float * integer * uint8 +  double   
>> // here, all operands should be implicitly promoted to Double before the 
>> complete expression evaluation.
> 
> You would have this produce different results than:
> 
>   let temp = float * integer * uint8
>   result = temp + double
> 
> That would be extremely surprising to many unsuspecting users.
> 
> Don’t get me wrong; I *really want* implicit promotions (I proposed one 
> scheme for them  way back when Swift was first unveiled publicly).

I don't!  At least not for floating point.  It is important for both reliable 
behavior and performance that programmers understand and minimize the 
conversions they do between different floating-point types.

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


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

2017-06-15 Thread John McCall via swift-evolution
> On Jun 14, 2017, at 4:45 AM, Jérémie Girault  
> wrote:
> @john, the proposal is the fruit of my imagination and the goal was to 
> discuss about it.
> I’m vastly open to change it with the help of anyone if it can be implemented 
> in a simple way and leads to better compatibility or syntactical improvements.
> 
> xiaodi told me that he wouldn’t be available to help me but I’m open to any 
> help and change that would represent an improvement (from the developer or 
> compiler point of view)

I'm just providing feedback.

John.

> 
> —
> very short reply expected - vsre.info 
> Jérémie Girault
> 
> On 13 juin 2017 at 19:15:18, John McCall (rjmcc...@apple.com 
> ) wrote:
> 
>> 
>>> On Jun 13, 2017, at 4:41 AM, Xiaodi Wu >> > wrote:
>>> 
>>> 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?
>> 
>> If the proposal was phrased in terms of defaults, e.g. "trailing parameters 
>> do not require a matching argument if they have Void type", then yes, that 
>> would be implementable because it still admits a "local" reduction on call 
>> constraints, one which does not need to immediately reason about the actual 
>> types of arguments.  It is not clear that this rule allows function 
>> compositions of the sort that Jérémie is looking for, though.
>> 
>> Anyway, that is not the proposal; the proposal is that parameters — in any 
>> position — are simply removed from the parameter sequence if they have Void 
>> type.  In order to allow composition (i.e. f(g(x)), where g: X -> Void), you 
>> then need a matching rule that arguments are dropped from the argument 
>> sequence (for purposes of type-checking) if they have Void type.  Either of 
>> these rules is sufficient to turn the reduction of function-type matches 
>> into an extremely messy combinatoric matching problem where e.g. (τ0, Int) 
>> can be passed to a function taking (Int, τ1) if we can decide that τ0 == τ1 
>> == Void.
>> 
>>> 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 
>>> rational

Re: [swift-evolution] [swift-dev] RFC: bridging peephole for "as" casts

2017-06-14 Thread John McCall via swift-evolution
> On Jun 14, 2017, at 2:24 AM, David Hart  wrote:
> Very good description. It's always worth re-explaining terms like bridged 
> conversion to make sure every body is on the same page. But concerning the 
> rules at the end, I’m not quite sure I understood them all. Please let me 
> know if I’m correct:

Yes, all of your examples should avoid bridging conversions.

John.

> 
> No bridging conversions will be performed if:
> - a call, property reference, or subscript reference is the immediate 
> syntactic operand of an "as" cast to a type compatible with the foreign 
> return, property, or subscript element type
> 
> protocol FooBar {
> func foo() -> NSMutableArray
> var bar: NSMutableDictionary { get set }
> subscript(_ index: Int) -> NSDecimalNumber { get set }
> }
> 
> let foobar: FooBar = ...
> foobar.foo() as NSArray
> foobar.bar as NSDictionary
> foobar[0] as NSNumber
> 
> - a call argument, right operand of an assignment to a property 
> reference, or right operand of an assignment to a subscript reference is an 
> "as" cast from a type compatible with the foreign parameter, property, or 
> subscript element type.
> 
> protocol BarFoo {
> func foo(_ array: NSArray)
> var bar: NSDictionary { get set }
> subscript(_ index: Int) -> NSNumber { get set }
> }
> 
> var barfoo: BarFoo = ...
> barfoo.foo(NSMutableArray() as NSArray)
> barfoo.bar = NSMutableDictionary() as NSDictionary
> barfoo[1] = NSDecimalNumber(string: "1.2") as NSNumber
> 
> On 14 Jun 2017, at 01:11, John McCall via swift-dev  > wrote:
> 
>> So, there's a longstanding issue that we're planning to fix in Swift 4, and 
>> I want to both make sure that the plan is documented publicly and give 
>> people a chance to disagree with it.
>> 
>> A bridging conversion is a conversion between a Swift type and a foreign 
>> type (C / ObjC / whatever) which can represent the same set of values.  For 
>> example, there are bridging conversions from Swift.String to ObjC's NSString 
>> and vice-versa.  When there two-way conversions like this, we say that the 
>> Swift type is bridged to the foreign type.
>> 
>> Bridging conversions are performed for three reasons in Swift:
>> 
>> 1. You can always request a bridging conversion with an unconditional "as" 
>> cast.  For example, if myString is a String, you can convert it to NSString 
>> by writing "myString as NSString".
>> 
>> 2. Certain bridging conversions can be introduced as implicit conversions.  
>> (This is perhaps a mistake.)   For example, CFString and NSString are 
>> considered different types, but they will implicitly convert to each other.
>> 
>> 3. Bridging conversions are done "behind the scenes" when using an imported 
>> declaration that has been given a type that does not match its original 
>> type.  For example, an Objective-C method that returns an NSString will be 
>> imported as returning a String; Swift will implicitly apply a bridging 
>> conversion to the true return value in order to produce the String that the 
>> type system has promised.
>> 
>> Bridging conversions are not always desirable.  First, they do impose some 
>> performance overhead which the user may not want.  But they can also change 
>> semantics in unwanted ways.  For example, in certain rare situations, the 
>> reference identity of an NSString return value is important — maybe it's 
>> actually a persistent NSMutableString which should be modified in-place, or 
>> maybe it's a subclass which carries additional information.  A pair of 
>> bridging conversions from NSString to String and then back to NSString is 
>> likely to lose this reference identity.  In the current representation, 
>> String can store an NSString reference, and if the String is bridged to 
>> NSString that reference will be used as the result; however, the bridging 
>> conversion from NSString does not directly store the original NSString in 
>> the String, but instead stores the result of invoking +copy on it, in an 
>> effort to protect against the original NSString being somehow mutable.
>> 
>> Bridging conversions arising from reasons #1 and #2 are avoidable, but 
>> bridging conversions arising from reason #3 currently cannot be eliminated 
>> without major inconvenience, such as writing a stub in Objective-C.  This is 
>> unsatisfactory.  At the same time, it is not valid for Swift to simply 
>> eliminate pairs of bridging conversions as a matter of course, precisely 
>> because those bridging conversions can be semantically important.  We do not 
>> want optimization settings to be able to affect things as important as 
>> whether a particular NSString is mutable or not.
>> 
>> The proposal is to apply a guaranteed syntactic "peephole" to eliminate 
>> bridging conversions that arise from reason #3.  Specifically:
>> 
>>   No bridging conversions will be performed if:
>> - a call, property reference, or subscript reference is the immediate 
>> syntactic
>>   ope

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

2017-06-13 Thread John McCall via swift-evolution
> On Jun 13, 2017, at 2:02 PM, Beta  wrote:
> They may be semantically distinct and part of the type system, but they are 
> not types.

Yes.  That is already true, though.  Our internal representation is unfortunate 
but it largely doesn't actually affect the language, just the complexity of the 
type-checker.

> I don’t think they should be given the privilege of overloading, but this is 
> a separate discussion.

Yes, that would definitely require further discussion.

John.

> 
> ~Robert Widmann
> 
>> On Jun 13, 2017, at 11:00 AM, John McCall > <mailto:rjmcc...@apple.com>> wrote:
>> 
>>> On Jun 13, 2017, at 1:48 PM, Beta >> <mailto:rwidm...@apple.com>> wrote:
>>> I would like to note that overloading on inout is a code smell and 
>>> something that should be removed in a future version of the language.  
>>> inout is not a type, it’s a SIL type residency annotation.
>> 
>> Uh, no, inout arguments are semantically extremely different from by-value 
>> arguments, and this is very much part of the type system.
>> 
>> John.
>> 
>>> 
>>> ~Robert Widmann
>>> 
>>>> On Jun 13, 2017, at 10:40 AM, Xiaodi Wu via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> Note that “inout Void” is a distinct type from “Void”; it is not possible 
>>>> to specify a default value for an inout Void parameter even explicitly 
>>>> (“error: cannot pass immutable value of type ()...”), so naturally it 
>>>> cannot be done implicitly either.
>>>> On Tue, Jun 13, 2017 at 12:29 Jens Persson >>> <mailto:j...@bitcycle.com>> wrote:
>>>> The std lib swap could perhaps be an interesting example to consider:
>>>> public func swap(_ a: inout T, _ b: inout T)
>>>> 
>>>> What would happen with that?
>>>> Will inout arguments be an exception to the rule of Void getting a default 
>>>> value, and if so, what would the effects of that be?
>>>> Or would it somehow be allowed to call swap()?
>>>> Or is there a third alternative?
>>>> /Jens
>>>> 
>>>> On Tue, Jun 13, 2017 at 7:15 PM, John McCall via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> On Jun 13, 2017, at 4:41 AM, Xiaodi Wu >>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>>> 
>>>>> On Tue, Jun 13, 2017 at 3:06 AM, John McCall >>>> <mailto:rjmcc...@apple.com>> wrote:
>>>>>> On Jun 13, 2017, at 3:30 AM, Jérémie Girault >>>>> <mailto:jeremie.gira...@gmail.com>> 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

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

2017-06-13 Thread John McCall via swift-evolution
> On Jun 13, 2017, at 1:48 PM, Beta  wrote:
> I would like to note that overloading on inout is a code smell and something 
> that should be removed in a future version of the language.  inout is not a 
> type, it’s a SIL type residency annotation.

Uh, no, inout arguments are semantically extremely different from by-value 
arguments, and this is very much part of the type system.

John.

> 
> ~Robert Widmann
> 
>> On Jun 13, 2017, at 10:40 AM, Xiaodi Wu via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Note that “inout Void” is a distinct type from “Void”; it is not possible to 
>> specify a default value for an inout Void parameter even explicitly (“error: 
>> cannot pass immutable value of type ()...”), so naturally it cannot be done 
>> implicitly either.
>> On Tue, Jun 13, 2017 at 12:29 Jens Persson > <mailto:j...@bitcycle.com>> wrote:
>> The std lib swap could perhaps be an interesting example to consider:
>> public func swap(_ a: inout T, _ b: inout T)
>> 
>> What would happen with that?
>> Will inout arguments be an exception to the rule of Void getting a default 
>> value, and if so, what would the effects of that be?
>> Or would it somehow be allowed to call swap()?
>> Or is there a third alternative?
>> /Jens
>> 
>> On Tue, Jun 13, 2017 at 7:15 PM, John McCall via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jun 13, 2017, at 4:41 AM, Xiaodi Wu >> <mailto:xiaodi...@gmail.com>> wrote:
>>> 
>>> On Tue, Jun 13, 2017 at 3:06 AM, John McCall >> <mailto:rjmcc...@apple.com>> wrote:
>>>> On Jun 13, 2017, at 3:30 AM, Jérémie Girault >>> <mailto:jeremie.gira...@gmail.com>> 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 

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

2017-06-13 Thread John McCall via swift-evolution

> On Jun 13, 2017, at 4:41 AM, Xiaodi Wu  wrote:
> 
> 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?

If the proposal was phrased in terms of defaults, e.g. "trailing parameters do 
not require a matching argument if they have Void type", then yes, that would 
be implementable because it still admits a "local" reduction on call 
constraints, one which does not need to immediately reason about the actual 
types of arguments.  It is not clear that this rule allows function 
compositions of the sort that Jérémie is looking for, though.

Anyway, that is not the proposal; the proposal is that parameters — in any 
position — are simply removed from the parameter sequence if they have Void 
type.  In order to allow composition (i.e. f(g(x)), where g: X -> Void), you 
then need a matching rule that arguments are dropped from the argument sequence 
(for purposes of type-checking) if they have Void type.  Either of these rules 
is sufficient to turn the reduction of function-type matches into an extremely 
messy combinatoric matching problem where e.g. (τ0, Int) can be passed to a 
function taking (Int, τ1) if we can decide that τ0 == τ1 == Void.

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

append on a Collection is not an unconstrained generic; its parameter type is 
determined by the type of the 

  1   2   3   4   5   >