Re: [swift-evolution] Revisiting SE-0110

2017-06-16 Thread Mark Lacey via swift-evolution

> On Jun 16, 2017, at 2:09 PM, Paul Cantrell  wrote:
> 
>> 
>> On Jun 16, 2017, at 3:43 PM, Mark Lacey > > wrote:
>> 
>> 
>>> On Jun 16, 2017, at 1:21 PM, Mark Lacey >> > wrote:
>>> 
 
 On Jun 16, 2017, at 11:13 AM, Paul Cantrell via swift-evolution 
 > wrote:
 
> 
> On Jun 15, 2017, at 7:17 PM, Xiaodi Wu via swift-evolution 
> > wrote:
> 
> 
> On Thu, Jun 15, 2017 at 19:03 Víctor Pimentel  > wrote:
> On 16 Jun 2017, at 01:55, Xiaodi Wu via swift-evolution 
> > wrote:
> 
>> On Thu, Jun 15, 2017 at 17:43 David Hart > > wrote:
>> 
>> By the way, I’m not attempting to deduce that nobody uses this feature 
>> by the fact I didn’t know about it. But I think it’s one interesting 
>> datapoint when comparing it to SE-0110.
>> 
>> 
>> SE-0110, **in retrospect**, has had impacts on a lot of users; 
>> prospectively, it was thought to be a minor change, even after review 
>> and acceptance.
>> 
>> Keep in mind that this proposed change would also eliminate inline tuple 
>> shuffle. For instance, the following code will cease to compile:
>> 
>> let x = (a: 1.0, r: 0.5, g: 0.5, b: 0.5)
>> func f(color: (r: Double, g: Double, b: Double, a: Double)) {
>>   print(color)
>> }
>> f(color: x)
>> 
>> It is an open question how frequently this is used. But like implicit 
>> tuple destructuring, it currently Just Works(TM) and users may not 
>> realize they’re making use of the feature until it’s gone.
> 
> It's much much less used, by looking at open source projects I doubt that 
> a significant portion of projects would have to change code because of 
> this.
> 
> The reason that I’m urging caution is because, if I recall correctly, 
> that is also what we said about SE-0110 on this list. Then, as now, we 
> were discussing an issue with something left over from the Swift 1 model 
> of tuples. Then, as now, we believed that the feature in question was 
> rarely used. Then, as now, we believed that removing that feature would 
> improve consistency in the language, better both for the compiler and for 
> users. Then, as now, leaving it in was thought to prevent moving forward 
> with other features that could improve Swift.
 
 Data:
 
 I hacked up a regexp that will catch most uses of labeled tuples in 
 pattern matches, e.g. “let (foo: bar) = baz”. That’s what we’re talking 
 about, right?
>>> 
>>> That’s the obvious example that people find confusing.
>>> 
>>> Less obvious places that labeled tuple patterns show up are ‘case let’ and 
>>> ‘case’ (see below). 
>> 
>> Okay, I should have looked at your regex and read further. It looks like you 
>> were already trying to match these.
> 
> I did walk the grammar for all occurrences of _pattern_.
> 
> I’m only matching named tuple patterns that immediately follow one of the 
> keywords which a pattern follows (for, case, let, var, and catch). As I 
> mentioned, I’m not matching patterns that come later in comma-separated 
> lists. I’m also not matching named tuples inside nested patterns, e.g. let 
> ((a: b), (c: d)).
> 
> But again, if even the most basic form of this construct is so rare, I doubt 
> more robust matching would turn up that much more usage.
> 
>> I’m surprised you’re not seeing any uses of ‘case’ with labels.
> 
> Me too. But I just verified that my pattern does match them.

Are you sure? It doesn’t look like it’s going to match the example I gave due 
to the leading ‘.’ on the enum case.

You might want to try the patch I sent as it will definitely catch any tuple 
pattern that makes it to the verifier and does have labels.

Mark

> 
> P
> 
>> 
>> Mark
>> 
>>> Fortunately we do not appear to allow shuffling in these cases. I’m not 
>>> sure if the human disambiguation is easier here because of the context 
>>> (‘case let’ and ‘case’), but I don’t recall seeing complain about these 
>>> being confusing (having said that it’s entirely possible they are very 
>>> confusing the first time someone sees them, in particular ‘cast let’ and 
>>> the binding form of ‘case’.
>>> 
>>> enum X {
>>>   case e(i: Int, f: Float)
>>> }
>>> 
>>> let x = X.e(i: 7, f: 12)
>>> 
>>> if case let X.e(i: hi, f: bye) = x {
>>>   print("(i: \(hi), f: \(bye))")
>>> }
>>> 
>>> func test(_ x: X, _ a: Int, _ b: Float) {
>>>   switch x {
>>>   case .e(i: a, f: b):
>>> print("match values")
>>>   case .e(i: let _, f: let _):
>>> print("bind values")
>>>   

Re: [swift-evolution] Revisiting SE-0110

2017-06-16 Thread Mark Lacey via swift-evolution

> On Jun 16, 2017, at 1:21 PM, Mark Lacey  wrote:
> 
>> 
>> On Jun 16, 2017, at 11:13 AM, Paul Cantrell via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Jun 15, 2017, at 7:17 PM, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
>>> 
>>> On Thu, Jun 15, 2017 at 19:03 Víctor Pimentel >> > wrote:
>>> On 16 Jun 2017, at 01:55, Xiaodi Wu via swift-evolution 
>>> > wrote:
>>> 
 On Thu, Jun 15, 2017 at 17:43 David Hart > wrote:
 
 By the way, I’m not attempting to deduce that nobody uses this feature by 
 the fact I didn’t know about it. But I think it’s one interesting 
 datapoint when comparing it to SE-0110.
 
 
 SE-0110, **in retrospect**, has had impacts on a lot of users; 
 prospectively, it was thought to be a minor change, even after review and 
 acceptance.
 
 Keep in mind that this proposed change would also eliminate inline tuple 
 shuffle. For instance, the following code will cease to compile:
 
 let x = (a: 1.0, r: 0.5, g: 0.5, b: 0.5)
 func f(color: (r: Double, g: Double, b: Double, a: Double)) {
   print(color)
 }
 f(color: x)
 
 It is an open question how frequently this is used. But like implicit 
 tuple destructuring, it currently Just Works(TM) and users may not realize 
 they’re making use of the feature until it’s gone.
>>> 
>>> It's much much less used, by looking at open source projects I doubt that a 
>>> significant portion of projects would have to change code because of this.
>>> 
>>> The reason that I’m urging caution is because, if I recall correctly, that 
>>> is also what we said about SE-0110 on this list. Then, as now, we were 
>>> discussing an issue with something left over from the Swift 1 model of 
>>> tuples. Then, as now, we believed that the feature in question was rarely 
>>> used. Then, as now, we believed that removing that feature would improve 
>>> consistency in the language, better both for the compiler and for users. 
>>> Then, as now, leaving it in was thought to prevent moving forward with 
>>> other features that could improve Swift.
>> 
>> Data:
>> 
>> I hacked up a regexp that will catch most uses of labeled tuples in pattern 
>> matches, e.g. “let (foo: bar) = baz”. That’s what we’re talking about, right?
> 
> That’s the obvious example that people find confusing.
> 
> Less obvious places that labeled tuple patterns show up are ‘case let’ and 
> ‘case’ (see below).

Okay, I should have looked at your regex and read further. It looks like you 
were already trying to match these.

I’m surprised you’re not seeing any uses of ‘case’ with labels.

Mark

> Fortunately we do not appear to allow shuffling in these cases. I’m not sure 
> if the human disambiguation is easier here because of the context (‘case let’ 
> and ‘case’), but I don’t recall seeing complain about these being confusing 
> (having said that it’s entirely possible they are very confusing the first 
> time someone sees them, in particular ‘cast let’ and the binding form of 
> ‘case’.
> 
> enum X {
>   case e(i: Int, f: Float)
> }
> 
> let x = X.e(i: 7, f: 12)
> 
> if case let X.e(i: hi, f: bye) = x {
>   print("(i: \(hi), f: \(bye))")
> }
> 
> func test(_ x: X, _ a: Int, _ b: Float) {
>   switch x {
>   case .e(i: a, f: b):
> print("match values")
>   case .e(i: let _, f: let _):
> print("bind values")
>   default:
> break
>   }
> }
> 
> test(X.e(i: 1, f: 2), 1, 2)
> test(X.e(i: 1, f: 2), 3, 4)
> 
> 
>> 
>> I ran that against all 55 projects in swift-source-compat-suite, comprising 
>> about over 400,000 lines of Swift code, and found … drumroll … exactly one 
>> match:
>> 
>> 
>> neota (swift-source-compat-suite)$ find project_cache -name '*.swift' 
>> -print0 | xargs -0 pcregrep -M 
>> '(for|case|let|var|catch)\s+\([a-zA-Z0-9_]+\s*:'
>> project_cache/RxSwift/RxExample/RxExample-iOSTests/TestScheduler+MarbleTests.swift:
>> let (time: _, events: events) = segments.reduce((time: 0, 
>> events: [RecordedEvent]())) { state, event in
>> 
>> 
>> Caveats about this method:
>> 
>> • My regexp won’t match second and third patterns in a comma-separated let 
>> or case, e.g.:
>> 
>>let a = b, (c: d) = e
>> 
>> • It doesn’t match non-ascii identifiers.
>> 
>> • This experiment only considers labeled tuples in pattern matches, what I 
>> took Chris’s original puzzler to be about. Label-based tuple shuffling is a 
>> separate question.
>> 
>> Still, even if it’s undercounting slightly, one breakage in half a million 
>> lines of code should put to rest concerns about unexpected widespread impact.
>> 
>> (Anything else I’m missing?)
>> 
>> • • •
>> 
>> Aside for those who know the 

Re: [swift-evolution] Revisiting SE-0110

2017-06-16 Thread Mark Lacey via swift-evolution

> On Jun 16, 2017, at 11:13 AM, Paul Cantrell via swift-evolution 
>  wrote:
> 
>> 
>> On Jun 15, 2017, at 7:17 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>> 
>> On Thu, Jun 15, 2017 at 19:03 Víctor Pimentel > > wrote:
>> On 16 Jun 2017, at 01:55, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>>> On Thu, Jun 15, 2017 at 17:43 David Hart >> > wrote:
>>> 
>>> By the way, I’m not attempting to deduce that nobody uses this feature by 
>>> the fact I didn’t know about it. But I think it’s one interesting datapoint 
>>> when comparing it to SE-0110.
>>> 
>>> 
>>> SE-0110, **in retrospect**, has had impacts on a lot of users; 
>>> prospectively, it was thought to be a minor change, even after review and 
>>> acceptance.
>>> 
>>> Keep in mind that this proposed change would also eliminate inline tuple 
>>> shuffle. For instance, the following code will cease to compile:
>>> 
>>> let x = (a: 1.0, r: 0.5, g: 0.5, b: 0.5)
>>> func f(color: (r: Double, g: Double, b: Double, a: Double)) {
>>>   print(color)
>>> }
>>> f(color: x)
>>> 
>>> It is an open question how frequently this is used. But like implicit tuple 
>>> destructuring, it currently Just Works(TM) and users may not realize 
>>> they’re making use of the feature until it’s gone.
>> 
>> It's much much less used, by looking at open source projects I doubt that a 
>> significant portion of projects would have to change code because of this.
>> 
>> The reason that I’m urging caution is because, if I recall correctly, that 
>> is also what we said about SE-0110 on this list. Then, as now, we were 
>> discussing an issue with something left over from the Swift 1 model of 
>> tuples. Then, as now, we believed that the feature in question was rarely 
>> used. Then, as now, we believed that removing that feature would improve 
>> consistency in the language, better both for the compiler and for users. 
>> Then, as now, leaving it in was thought to prevent moving forward with other 
>> features that could improve Swift.
> 
> Data:
> 
> I hacked up a regexp that will catch most uses of labeled tuples in pattern 
> matches, e.g. “let (foo: bar) = baz”. That’s what we’re talking about, right?

That’s the obvious example that people find confusing.

Less obvious places that labeled tuple patterns show up are ‘case let’ and 
‘case’ (see below). Fortunately we do not appear to allow shuffling in these 
cases. I’m not sure if the human disambiguation is easier here because of the 
context (‘case let’ and ‘case’), but I don’t recall seeing complain about these 
being confusing (having said that it’s entirely possible they are very 
confusing the first time someone sees them, in particular ‘cast let’ and the 
binding form of ‘case’.

enum X {
  case e(i: Int, f: Float)
}

let x = X.e(i: 7, f: 12)

if case let X.e(i: hi, f: bye) = x {
  print("(i: \(hi), f: \(bye))")
}

func test(_ x: X, _ a: Int, _ b: Float) {
  switch x {
  case .e(i: a, f: b):
print("match values")
  case .e(i: let _, f: let _):
print("bind values")
  default:
break
  }
}

test(X.e(i: 1, f: 2), 1, 2)
test(X.e(i: 1, f: 2), 3, 4)


> 
> I ran that against all 55 projects in swift-source-compat-suite, comprising 
> about over 400,000 lines of Swift code, and found … drumroll … exactly one 
> match:
> 
> 
> neota (swift-source-compat-suite)$ find project_cache -name '*.swift' -print0 
> | xargs -0 pcregrep -M '(for|case|let|var|catch)\s+\([a-zA-Z0-9_]+\s*:'
> project_cache/RxSwift/RxExample/RxExample-iOSTests/TestScheduler+MarbleTests.swift:
> let (time: _, events: events) = segments.reduce((time: 0, 
> events: [RecordedEvent]())) { state, event in
> 
> 
> Caveats about this method:
> 
> • My regexp won’t match second and third patterns in a comma-separated let or 
> case, e.g.:
> 
>let a = b, (c: d) = e
> 
> • It doesn’t match non-ascii identifiers.
> 
> • This experiment only considers labeled tuples in pattern matches, what I 
> took Chris’s original puzzler to be about. Label-based tuple shuffling is a 
> separate question.
> 
> Still, even if it’s undercounting slightly, one breakage in half a million 
> lines of code should put to rest concerns about unexpected widespread impact.
> 
> (Anything else I’m missing?)
> 
> • • •
> 
> Aside for those who know the tools out there: what would it take to run 
> inspections like this against ASTs instead of using a regex? Could we 
> instrument the compiler as Brent suggested?

If you want to catch *all* of these cases then the patch below will do it by 
failing the AST verifier when it hits a pattern with labels. If you only want 
to find the plain let-binding versions of this and not the ‘case let’ and 
‘case’ ones, I’d suggest looking at the parser to see if there’s an easy 

Re: [swift-evolution] Revisiting SE-0110

2017-06-15 Thread Mark Lacey via swift-evolution

> On Jun 15, 2017, at 8:23 AM, Robert Bennett via swift-evolution 
>  wrote:
> 
>> One (tangential) thing that came up is that tuple element names in tuple 
>> *patterns* should probably be deprecated and removed at some point.  Without 
>> looking, what variables does this declare?:
>> 
>>  let (a : Int, b : Float) = foo()
> 
> 
> I think it would be better if the compiler raised a warning whenever you 
> tried to redefine a builtin type. `let (a : Int, b : Float) = foo()` is 
> confusing but if you were to use your own type (e.g., `struct S {}` and 
> replace Int and Float with S) you would get a compiler error.

If you replace *both* Int and Float with S you would get an error, but if you 
replace one you’ll only get an error if you do this within the same scope that 
your type is defined.

There’s nothing special happening here for the stdlib types vs. your own types. 
What you’re witnessing is shadowing. You can shadow names within deeper scopes, 
e.g. this is perfectly legal:

func MyOwnInt() {
  struct Int : ExpressibleByFloatLiteral {
typealias FloatLiteralType = Double

public init(floatLiteral value: FloatLiteralType) {
  self.value = value
}

var value: FloatLiteralType
  }
  let _: Int = 7.0
}


Mark

> If the compiler warned you that you were reassigning Int and Float, you’d 
> probably avoid that problem. Or, for a more extreme fix, we could make 
> reassigning builtin types illegal since there is pretty much no valid reason 
> to do that.
> 
> 
>> On Jun 15, 2017, at 8:10 AM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>>> On Jun 14, 2017, at 11:01 PM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Jun 12, 2017, at 10:07 PM, Paul Cantrell  wrote:
 
 What’s the status of this Chris’s double parens idea below? It garnered 
 some positive responses, but the discussion seems to have fizzled out. Is 
 there something needed to help nudge this along?
 
 What’s the likelihood of getting this fixed before Swift 4 goes live, and 
 the great wave of readability regressions hits?
>>> 
>>> We discussed this in the core team meeting today.  Consensus seems to be 
>>> that a change needs to be made to regain syntactic convenience here.  
>>> Discussion was leaning towards allowing (at least) the parenthesized form, 
>>> but more discussion is needed.
>>> 
>>> 
>>> One (tangential) thing that came up is that tuple element names in tuple 
>>> *patterns* should probably be deprecated and removed at some point.  
>>> Without looking, what variables does this declare?:
>>> 
>>>  let (a : Int, b : Float) = foo()
>> 
>> Another option would be to require let to appear next to each name binding 
>> instead of allowing a single let for the whole pattern.  I personally find 
>> that much more clear despite it being a little bit more verbose.
>> 
>>> 
>>> ?
>>> 
>>> -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

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


Re: [swift-evolution] Proposal: Always flatten the single element tuple

2017-06-09 Thread Mark Lacey via swift-evolution

> On Jun 9, 2017, at 12:55 AM, Gwendal Roué  wrote:
> 
>> 
>> Le 9 juin 2017 à 09:41, Mark Lacey > > a écrit :
>> 
>> 
>>> On Jun 9, 2017, at 12:12 AM, Gwendal Roué >> > wrote:
>>> 
> func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return 
> "notOverloaded1" }
> func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> 
> String { return "notOverloaded3" }
> 
> func overloaded(_ closure: (Int, Int) -> Int) -> String { return 
> "overloaded 1" }
> func overloaded(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { 
> return "overloaded 2" }
> 
> // not overloaded => not ambiguous
> notOverloaded1 { x, y in x + y }
> notOverloaded1 { (x, y) in x + y }
> notOverloaded1 { _ in 1 }
> notOverloaded2 { x, y in x + y }
> notOverloaded2 { (x, y) in x + y }
> notOverloaded2 { _ in 1 }
> 
> // overloaded => resolve ambiguity on closure argument, when possible
> overloaded { x, y in x + y }// "overloaded 1"
> overloaded { (x, y) in x + y }  // "overloaded 1"
> overloaded { t in t.lhs + t.rhs }   // "overloaded 2"
> overloaded { (t) in t.lhs + t.rhs } // "overloaded 2”
 
 This is exactly what happens today as a result of SE-0110 since the first 
 two calls take two arguments, and the next two take a single argument.
>>> 
>>> No, as a playground quickly reveals:
>> 
>> I was specifically referring to the last four statements but could have made 
>> that more clear.
>> 
>>> func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return 
>>> "notOverloaded1" }
>>> func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String 
>>> { return "notOverloaded3" }
>>> 
>>> // not overloaded => not ambiguous
>>> notOverloaded1 { x, y in x + y }
>>> notOverloaded1 { (x, y) in x + y }
>>> notOverloaded1 { _ in 1 }  // Swift 4 error
>> 
>> This really should be an error.
> 
> I argue this is a subjective statement, and my own subjective statement is 
> that it should not to be an error. So that { _ in ... } would always mean "I 
> don't care".
> 
>> It’s one thing to say that { x, y in } should work as it used to in the case 
>> where a closure taking a tuple is expected, but something else entirely to 
>> say that _ should work in any case, regardless of whether a closure taking N 
>> arguments or a closure taking an N-tuple is expected for any N. I can see a 
>> desire to make _ work for any tuple, and _, _ work for a two-tuple based on 
>> context if e.g. “x, y in” also works, but not for _ working where a closure 
>> requiring N independent arguments is expected.
> 
> Yes. That's why it's subjective. You argue that you don't like it, not that 
> it's impossible to do. Because you can't prove it's impossible to do.

I’m not trying to argue that it’s impossible to do. I don’t think it’s a good 
idea at all. That’s subjective. Me saying “that really should be an error” is a 
subjective statement. I don’t have to say “This is a subjective statement” to 
make a subjective statement.

> Because I have shown that it is.
> In a nice manner that is easy to developers.
> 
>> 
>>> notOverloaded2 { x, y in x + y }   // Swift 4 error
>>> notOverloaded2 { (x, y) in x + y } // Swift 4 error
>> 
>> In these cases using the tuple labels works as well (as it does in your 
>> examples where the overloaded function is involved). I’m not arguing that 
>> it’s as good as being able to do the apparent destructuring, but just want 
>> to point out that it works. I didn’t get the sense from your email that you 
>> found that objectionable in the cases involving overloads, but perhaps you 
>> do.
>> 
>>> notOverloaded2 { _ in 1 }
>>> 
>>> Those errors are the famous regressions we want to fix.
>>> 
> overloaded { _ in 1 }   // error: ambiguous use of 
> ‘overloaded'
 
 With SE-0110 in its current form, this calls the tuple version since there 
 is a single closure parameter listed.
>>> 
>>> It would be nicer if. { _ in ... } would always mean "I don't care". With 
>>> an ambiguity in the sample code we're looking at, and a compiler error.
>> 
>> How does making something that is unambiguous today actually be ambiguous 
>> improve things?
> 
> I *do* suggest a specific handling of { _ ... }. I have shown how it can be 
> implemented in a non-ambiguous fashion.

Your own comment says this should be considered ambiguous. It’s unambiguous 
now. What I am asking is how is that an improvement?

Mark

> Please don't act as if I did not.

> 
> Now the specific case of { _ ... } is interesting, but I wouldn't make it as 
> important as the other regressions.
> 
> I should make an exhaustive compilation of Swift 4 

Re: [swift-evolution] Proposal: Always flatten the single element tuple

2017-06-09 Thread Mark Lacey via swift-evolution

> On Jun 9, 2017, at 12:12 AM, Gwendal Roué  wrote:
> 
>>> func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return 
>>> "notOverloaded1" }
>>> func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String 
>>> { return "notOverloaded3" }
>>> 
>>> func overloaded(_ closure: (Int, Int) -> Int) -> String { return 
>>> "overloaded 1" }
>>> func overloaded(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { 
>>> return "overloaded 2" }
>>> 
>>> // not overloaded => not ambiguous
>>> notOverloaded1 { x, y in x + y }
>>> notOverloaded1 { (x, y) in x + y }
>>> notOverloaded1 { _ in 1 }
>>> notOverloaded2 { x, y in x + y }
>>> notOverloaded2 { (x, y) in x + y }
>>> notOverloaded2 { _ in 1 }
>>> 
>>> // overloaded => resolve ambiguity on closure argument, when possible
>>> overloaded { x, y in x + y }// "overloaded 1"
>>> overloaded { (x, y) in x + y }  // "overloaded 1"
>>> overloaded { t in t.lhs + t.rhs }   // "overloaded 2"
>>> overloaded { (t) in t.lhs + t.rhs } // "overloaded 2”
>> 
>> This is exactly what happens today as a result of SE-0110 since the first 
>> two calls take two arguments, and the next two take a single argument.
> 
> No, as a playground quickly reveals:

I was specifically referring to the last four statements but could have made 
that more clear.

> func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return 
> "notOverloaded1" }
> func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { 
> return "notOverloaded3" }
> 
> // not overloaded => not ambiguous
> notOverloaded1 { x, y in x + y }
> notOverloaded1 { (x, y) in x + y }
> notOverloaded1 { _ in 1 }  // Swift 4 error

This really should be an error. It’s one thing to say that { x, y in } should 
work as it used to in the case where a closure taking a tuple is expected, but 
something else entirely to say that _ should work in any case, regardless of 
whether a closure taking N arguments or a closure taking an N-tuple is expected 
for any N. I can see a desire to make _ work for any tuple, and _, _ work for a 
two-tuple based on context if e.g. “x, y in” also works, but not for _ working 
where a closure requiring N independent arguments is expected.

> notOverloaded2 { x, y in x + y }   // Swift 4 error
> notOverloaded2 { (x, y) in x + y } // Swift 4 error

In these cases using the tuple labels works as well (as it does in your 
examples where the overloaded function is involved). I’m not arguing that it’s 
as good as being able to do the apparent destructuring, but just want to point 
out that it works. I didn’t get the sense from your email that you found that 
objectionable in the cases involving overloads, but perhaps you do.

> notOverloaded2 { _ in 1 }
> 
> Those errors are the famous regressions we want to fix.
> 
>>> overloaded { _ in 1 }   // error: ambiguous use of 
>>> ‘overloaded'
>> 
>> With SE-0110 in its current form, this calls the tuple version since there 
>> is a single closure parameter listed.
> 
> It would be nicer if. { _ in ... } would always mean "I don't care". With an 
> ambiguity in the sample code we're looking at, and a compiler error.

How does making something that is unambiguous today actually be ambiguous 
improve things?

Mark

> The { (_, _) in ... } form is arguably cluttered, and it would be nicer it is 
> was required only for disambiguition.
> 
>>> overloaded { (_) in 1 } // "overloaded 1”
>> 
>> With SE-0110 in its current form, this calls the tuple version since there 
>> is a single closure parameter listed. I don’t understand why you would 
>> suggest this should call the two-argument version since that’s inconsistent 
>> with the other closures above that have a single argument.
>> 
>>> overloaded { (_, _) in 1 }  // "overloaded 2”
>> 
>> With SE-0110 in its current form, this calls the two-argument version since 
>> there are two listed arguments.
> 
> I was wrong, sorry. I meant what you replied.
> 
> Gwendal
> 

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


Re: [swift-evolution] Proposal: Always flatten the single element tuple

2017-06-09 Thread Mark Lacey via swift-evolution

> On Jun 8, 2017, at 11:37 PM, Gwendal Roué via swift-evolution 
>  wrote:
> 
> 
>> Le 9 juin 2017 à 07:56, Vladimir.S via swift-evolution 
>> > a écrit :
>> 
>> Yes, we are discussing the *potential* solutions for Swift 4 that can 
>> decrease the pain of migration of *some* Swift3 code, given (Int,Int)->() 
>> and ((Int,Int))->() are different types in Swift 4.
>> 
>> But, as was said by Mark Lacey in this thread later, there is an "overload" 
>> problem for such solution, when closure of kind {x, y in ..} can be sent to 
>> overloaded func like here:
>> 
>> func overloaded(_ fn: (Int, Int) -> Int) { fn(1,2) }
>> func overloaded(_ fn: ((Int, Int)) -> Int) { fn((3,4)) }
>> 
>> overloaded { x, y in x + y }
>> overloaded { (x, y) in x + y }
>> 
>> Compiler is not able to determinate which type of closure do you want in 
>> each case. For ((Int,Int))->Int you still need some 'specific' syntax which 
>> disambiguate the call. So we *still* need some good syntax to destructure 
>> tuple argument in closure to use in place of ((Int,Int))->Int closure.
>> 
>> This means that there is no sense to allow very 'magic' {x,y in ..} syntax 
>> and compiler-detected type of closure if we still need good syntax 
>> for destructuring tuple argument in ((Int,Int))->().
> 
> Yes, Mark was very right asking about overloads. But is it a problem that 
> does not have a solution which preserves ergonomics?
> 
> func notOverloaded1(_ closure: (Int, Int) -> Int) -> String { return 
> "notOverloaded1" }
> func notOverloaded2(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { 
> return "notOverloaded3" }
> 
> func overloaded(_ closure: (Int, Int) -> Int) -> String { return 
> "overloaded 1" }
> func overloaded(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { 
> return "overloaded 2" }
> 
> // not overloaded => not ambiguous
> notOverloaded1 { x, y in x + y }
> notOverloaded1 { (x, y) in x + y }
> notOverloaded1 { _ in 1 }
> notOverloaded2 { x, y in x + y }
> notOverloaded2 { (x, y) in x + y }
> notOverloaded2 { _ in 1 }
> 
> // overloaded => resolve ambiguity on closure argument, when possible
> overloaded { x, y in x + y }// "overloaded 1"
> overloaded { (x, y) in x + y }  // "overloaded 1"
> overloaded { t in t.lhs + t.rhs }   // "overloaded 2"
> overloaded { (t) in t.lhs + t.rhs } // "overloaded 2”

This is exactly what happens today as a result of SE-0110 since the first two 
calls take two arguments, and the next two take a single argument.

> overloaded { _ in 1 }   // error: ambiguous use of 
> ‘overloaded'

With SE-0110 in its current form, this calls the tuple version since there is a 
single closure parameter listed.

> overloaded { (_) in 1 } // "overloaded 1”

With SE-0110 in its current form, this calls the tuple version since there is a 
single closure parameter listed. I don’t understand why you would suggest this 
should call the two-argument version since that’s inconsistent with the other 
closures above that have a single argument.

> overloaded { (_, _) in 1 }  // "overloaded 2”

With SE-0110 in its current form, this calls the two-argument version since 
there are two listed arguments.

Mark

> See the error on `overloaded { _ in 1 }`, because _ means "I don't care". 
> Well, here you have to care because of overloading. Ambiguity is resolved 
> with parenthesis. This is a specific behavior for `_`.
> 
> Gwendal
> 
> ---
> 
> PS, I had a little look at how Swift 3 currently behave with overloading ? 
> Badly, actually:
> 
> // SWIFT 3
> 
> func f(_ closure: (Int, Int) -> Int) -> String { return "two arguments" }
> // error: invalid redeclaration of 'f'
> // func f(_ closure: ((Int, Int)) -> Int) -> String { return "one 
> anonymous tuple argument" }
> func f(_ closure: ((lhs: Int, rhs: Int)) -> Int) -> String { return "one 
> named tuple argument" }
> 
> // error: ambiguous use of 'f'
> // f { x, y in x + y }
> 
> f { t in t.rhs + t.lhs } // "one named tuple argument"
> 
> // error: ambiguous use of 'f'
> // f { t in t.0 + t.1 } // "one named tuple argument"
> 
> // error: ambiguous use of 'f'
> let c = { (a: Int, b: Int) -> Int in a + b }
> type(of: c) // ((Int, Int) -> Int).Type
> // error: ambiguous use of 'f'
> // f(c)
> 
> Swift 3 does not allow overloading ((Int, Int)) -> Int and (Int, Int) -> Int, 
> but allows overloading ((lhs: Int, rhs: Int)) -> Int and (Int, Int) -> Int.
> 
> Yet I could never call the (Int, Int) -> Int version, even when I provide 
> with a function that exactly matches its signature. And there are much too 
> many ambiguous situations the compiler can't deal with.
> 
> So yes, there is a problem with Swift 3.
> 
> How is it with Swift 4 (2017-06-02 snapshot)?
> 
> // 

Re: [swift-evolution] Proposal: Always flatten the single element tuple

2017-06-08 Thread Mark Lacey via swift-evolution

> On Jun 8, 2017, at 2:05 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 08.06.2017 21:17, Gwendal Roué via swift-evolution wrote:
>>> Le 8 juin 2017 à 19:40, Brent Royal-Gordon via swift-evolution 
>>>  
>>> >> a 
>>> écrit :
>>> 
 On Jun 7, 2017, at 3:03 AM, Adrian Zubarev via swift-evolution 
 > wrote:
 
 Well please no:
 
> |let fn2: ((Int, Int)) -> Void = { lhs, rhs in }|
 
 Instead use destructuring sugar pitched by Chris Lattner on the other 
 thread:
 
 |let fn2: ((Int, Int)) -> Void = { ((lhs, rhs)) in }|
 
>>> I think this suggestion is better than the status quo. I'm wondering, 
>>> though, if we should just drop the outer set of parentheses entirely, 
>>> unless you're also putting types on the parameters. That is, a closure of 
>>> type `(Int, Int) -> T` can look like this:
>>> 
>>> { (x: Int, y: Int) in … }
>>> 
>>> Or it can look like this:
>>> 
>>> { x, y in … }
>>> 
>>> But it *cannot* look like this:
>>> 
>>> { (x, y) in … }
>>> 
>>> The `(x, y)` form can instead be a closure of a type like `((Int, Int)) -> 
>>> T`, which immediately destructures the tuple parameter into separate 
>>> constants.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>> Hello,
>> There's a difference, in the mind of people here that try to show how bad 
>> were the recent changes, between:
>> 1: closures defined independently
>> 2: closures given as a parameter to a function.
>> I think that we all agree that the type of a closure that is defined 
>> independently should be well defined:
>> // Choose between (Int, Int) -> () or ((x: Int, y: Int)) -> ()
>> leta = { (x: Int, y: Int) -> Intin... }
>> letb = { ((x: Int, y: Int)) -> Intin... }
>> However, when a closure is given as an argument of a function that expects a 
>> closure, we ask for the maximum possible flexibility, as Swift 3 did:
>> funcwantsTwoArguments(_closure: (Int, Int) -> Int) { closure(1, 2) }
>> wantsTwoArguments{ a, b ina + b }
>> wantsTwoArguments{ (a, b) ina + b }
>> wantsTwoArguments{ t int.0+ t.1} // OK, maybe not
>> funcwantsATupleArgument(_closure: ((Int, Int)) -> Int) { closure((1, 2)) }
>> wantsATupleArgument{ a, b ina + b }
>> wantsATupleArgument{ (a, b) ina + b }
>> wantsATupleArgument{ t int.0+ t.1}
>> funcwantsANamedTupleArgument(_closure: ((lhs: Int, rhs: Int)) -> Int) { 
>> closure((lhs: 1, rhs: 2)) }
>> wantsANamedTupleArgument{ a, b ina + b }
>> wantsANamedTupleArgument{ (a, b) ina + b }
>> wantsANamedTupleArgument{ t int.lhs + t.rhs }
> 
> It's nice to see that we are agreed that func/closures declared separately 
> should have clearly defined type and (at least for now) can't be 
> interchangeable.
> 
> And personally I agree that this could be a solution to migration problem, 
> compiler can generate closure of correct(requested) type if such closure:
> 1. declared inplace of func call as parameter of that func
> 2. has no type annotations for its arguments
> 3. (probably, can discuss) has no parenthesis for its arguments, because one 
> pair of parenthesis in argument list declares closure of type (list of 
> arguments)->T in other situations.
> 
> So, we can have
> 
> wantsTwoArguments{ a, b in a + b } // (Int,Int)->() will be generated
> wantsTwoArguments{ (a, b) in a + b } // syntax of (Int,Int)->() closure
> 
> wantsATupleArgument{ a, b in a + b } // ((Int,Int))->() will be generated
> wantsATupleArgument{ t in t.0+ t.1 } // syntax of ((Int,Int))->() closure
> 
> wantsANamedTupleArgument{ a, b in a + b } // ((Int,Int))->() will be generated
> wantsANamedTupleArgument{ t in t.lhs + t.rhs } // syntax of ((Int,Int))->() 
> closure

Overloading complicates this. Ignoring for a moment that we cannot declare the 
following due to https://bugs.swift.org/browse/SR-5129: 


func overloaded(_ fn: (Int, Int) -> Int) { fn(1,2) }
func overloaded(_ fn: ((Int, Int)) -> Int) { fn((3,4)) }
  
overloaded { x, y in x + y }
overloaded { (x, y) in x + y }


Mark

> 
> So, { a,b in ...} will be a special syntax for closure which type will be 
> defined by compiler by type of func's parameter.
> 
> The question is if community and core team will support this idea, if that 
> idea is better than other ideas like {((a,b)) in ..} for tuple 
> deconstruction, and if this could be implemented before Swift 4 release.
> 
>> *This gives us the ability to deal with unfitted function signatures.* For 
>> example, most Dictionary methods. Yes, they are usually unfitted:
>> extensionDictionary{
>> funcforEach(_body: ((key: Key, value: Value)) throws-> Void) rethrows
>> }
>> Who cares about this named (key:value:) tuple? Absolutely nobody, as 
>> exemplified by this remarquable Swift 3 snippet below, where no tuple, no 
>> `key`, and no 

Re: [swift-evolution] Revisiting SE-0110

2017-06-06 Thread Mark Lacey via swift-evolution

> On Jun 6, 2017, at 1:59 PM, Stephen Celis <stephen.ce...@gmail.com> wrote:
> 
>> On Jun 6, 2017, at 1:43 PM, Mark Lacey via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> Unless I am missing something this is an example of tuple destructuring. I’m 
>> looking for examples of other issues.
> 
> The destructuring issue is the most pervasive, but as mentioned it also 
> breaks point-free style:
> 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170529/036911.html
> 
> Again, less common for most but heavily used by us and folks that use 
> functional patterns and libs like RxSwift, ReactiveCocoa, etc., where a lot 
> of streams/signals of values are composed into new structures.

Thanks for reminding me. It’s good to call out this case specifically. The 
underlying reason that this is disallowed for Swift 4 is the same as the 
underlying reason that a closure immediately passed as an argument (with with 
mismatching function type) is disallowed for Swift 4 (i.e. the “tuple 
destructuring” case). It might be possible to relax restrictions to allow one 
of these without allowing the other.

Having said that, I find it surprising that your tupleUp function works as it 
is implicitly converting the function type in a way that I would expect SE-0110 
to disallow. My expectation is that it would need to be written like this:

func tupleUp<A, B, C>(_ f: @escaping (A, B) -> C) -> ((A, B)) -> C {
  return { f($0.0, $0.1) }
}

Mark

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


Re: [swift-evolution] Why is the status of SE-0110 "implemented"?

2017-06-06 Thread Mark Lacey via swift-evolution

> On Jun 6, 2017, at 3:16 PM, Jens Persson <j...@bitcycle.com> wrote:
> 
> Here are the four you asked me to report:
> 
> https://bugs.swift.org/browse/SR-5127 <https://bugs.swift.org/browse/SR-5127>
> Single-tuple and multiple-argument function types should not be considered 
> equal
>  
> https://bugs.swift.org/browse/SR-5128 <https://bugs.swift.org/browse/SR-5128>
> Don't allow swapping a single-tuple function with a multiple-argument function
> 
> https://bugs.swift.org/browse/SR-5129 <https://bugs.swift.org/browse/SR-5129>
> Don't treat func signatures as being the same when they are in fact different
> 
> https://bugs.swift.org/browse/SR-5130 <https://bugs.swift.org/browse/SR-5130>
> Single-tuple and multiple-argument function types should be treated as 
> different types

Thanks!

Mark

> 
> /Jens
> 
> 
> On Tue, Jun 6, 2017 at 8:17 PM, Mark Lacey via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
> > On Jun 6, 2017, at 11:09 AM, Vladimir.S <sva...@gmail.com 
> > <mailto:sva...@gmail.com>> wrote:
> >
> > On 06.06.2017 19:41, Mark Lacey wrote:
> >>> On Jun 6, 2017, at 4:00 AM, Vladimir.S <sva...@gmail.com 
> >>> <mailto:sva...@gmail.com> <mailto:sva...@gmail.com 
> >>> <mailto:sva...@gmail.com>>> wrote:
> >>>
> >>> Mark, could you please also comment this inconsistencies / bugs :
> >>> (swift-4.0-DEVELOPMENT-SNAPSHOT-2017-06-01-a-osx)
> >>>
> >>> func fooParam(_ x: Int, _ y: Int){}
> >>> func fooTuple(_ x: (Int, Int)) {}
> >>>
> >>> print("type of fooParam is", type(of:fooParam))
> >>> // result: type of fooParam is (Int, Int) -> ()
> >>>
> >>> print("type of fooTuple is", type(of:fooTuple))
> >>> // result: type of fooTuple is (Int, Int) -> ()
> >>>
> >>> print("type of fooTuple as (_:(Int,Int))->Void is", type(of: fooTuple as 
> >>> (_:(Int,Int))->()))
> >>> // result: type of fooTuple as (_:(Int,Int))->() is (Int, Int) -> ()
> >>>
> >>>
> >>> print("type of fooParam == type of fooTuple ?", type(of: fooParam) == 
> >>> type(of: fooTuple))
> >>> // result: true
> >>>
> >>> if fooParam is (_: (Int,Int))->() { print("fooParam is (_: 
> >>> (Int,Int))->()") }
> >>> // result: fooParam is (_: (Int,Int))->()
> >>>
> >>> if fooTuple is (Int,Int)->() { print("fooTuple is (Int,Int)->()") }
> >>> // result: fooTuple is (Int,Int)->()
> >>>
> >>> var closureParam = { (x: Int, y: Int) in  }
> >>> var closureTuple = { (x: (Int, Int)) in  }
> >>>
> >>> print("type of closureParam is", type(of:closureParam))
> >>> // result: type of closureParam is (Int, Int) -> ()
> >>>
> >>> print("type of closureTuple is", type(of:closureTuple))
> >>> // result: type of closureTuple is (Int, Int) -> ()
> >>>
> >>> if closureParam is (_: (Int,Int))->() { print("closureParam is (_: 
> >>> (Int,Int))->()") }
> >>> // result: closureParam is (_: (Int,Int))->()
> >>>
> >>> if closureTuple is (Int,Int)->() { print("closureTuple is (Int,Int)->()") 
> >>> }
> >>> // result: closureTuple is (Int,Int)->()
> >> Can you open two reports at bugs.swift.org <http://bugs.swift.org/> 
> >> <http://bugs.swift.org <http://bugs.swift.org/>>, one for the ‘is’ issue, 
> >> and one for type(of:)?
> >> These (along with the issue with function declarations that Jens 
> >> mentioned) are all similar issues, but each is in a different part of the 
> >> compiler.
> >
> > Here they are:
> > https://bugs.swift.org/browse/SR-5114 
> > <https://bugs.swift.org/browse/SR-5114>  (typeof)
> > https://bugs.swift.org/browse/SR-5112 
> > <https://bugs.swift.org/browse/SR-5112>  (is)
> 
> Thanks!
> 
> Mark
> 
> >
> >> Mark
> >>>
> >>> Thank you.
> >>> Vladimir.
> >>>
> >>> On 06.06.2017 11:43, Mark Lacey via swift-evolution wrote:
> >>>>> On Jun 6, 2017, at 12:08 AM, Jens Persson via swift-evolution 
> >>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org> 
&g

Re: [swift-evolution] Revisiting SE-0110

2017-06-06 Thread Mark Lacey via swift-evolution

> On Jun 6, 2017, at 10:33 AM, John Holdsworth <m...@johnholdsworth.com> wrote:
> 
> Hi Mark,
> 
> one example of what was possible in Swift 3 but not convenient in Swift4 as 
> it stands is the following:
> 
>let bookTuples = [(1, "john", "book", "novel", 9.99, []),
>  (2, "john", "book", "novel", 9.99, ["chapt1", 
> "chapt2"])]
> 
>print("""
> 
> 
> \(bookTuples.map {
> (id, author, title, genre, price, chapters) in """
> 
> \(author)
> \(title)
> \(genre)
> \(price)
> 
> \(chapters.map {
> (heading) in """
> \(heading)
> 
> """}.joined(separator:"")
> )
> 
> 
> """}.joined(separator:"")
> )
> """)
> 
> It would be great if this functionality could be preserved somehow. ((double 
> brackets)) perhaps
> but it would help library maintainers if this could also be back ported into 
> Swift 3.2.

Unless I am missing something this is an example of tuple destructuring. I’m 
looking for examples of other issues.

Mark

> 
> -John
> 
>> On 6 Jun 2017, at 18:10, Mark Lacey via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Jun 6, 2017, at 8:42 AM, Ray Fix via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>> FWIW, after doing a project migration last night and this morning, I am 
>>> reluctantly +1 for reverting SE-0110 and seeing a new proposal that can be 
>>> properly evaluated.  The split-the-difference compromise mentioned seems 
>>> like just that, a compromise that will need to be revisited anyway.
>>> 
>>> While I agreed with the spirit of the original proposal, the assertion that 
>>> "Minor changes to user code may be required if this proposal is accepted.” 
>>> seems like it underestimated the magnitude of the impact. In almost every 
>>> case, my code lost clarity.
>> 
>> Did you run into issues other than the “tuple destructuring” issue that 
>> began this thread?
>> 
>> If so, can you provide some examples to illustrate what other issues people 
>> are hitting in practice?
>> 
>> I put “tuple destructuring” in quotes here because although it looks very 
>> much like what is happening in Swift 3 and earlier, there was no real tuple 
>> destructuring support in parameters (as evidenced by the fact that things 
>> like (x, (y, z)) never worked).
>> 
>> The behavior of allowing:
>>   [“key” : 1].map { key, value in … }
>> is the result of allowing the two-argument closure to be passed to a 
>> function (map) that expects a one-argument function parameter where the 
>> argument is a two element tuple.
>> 
>> I don’t think anyone disagrees that removing this functionality without 
>> simultaneously providing a real destructuring feature regresses the 
>> usability of the language where closures are concerned.
>> 
>> Understanding other fallout from SE-0110 will be helpful in guiding the 
>> decision of how to move forward from here.
>> 
>> Mark
>> 
>>> 
>>> Other aspects of the migration went quite smoothly.
>>> 
>>> BTW, if I were at WWDC this year I would be in the Swift lab pestering them 
>>> about this.  Hopefully that feedback is happening. :)
>>> 
>>> Ray
>>> 
>>> 
>>>> On Jun 6, 2017, at 8:22 AM, Shawn Erickson via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> 
>>>> On Tue, Jun 6, 2017 at 7:18 AM Gwendal Roué via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> Le 6 juin 2017 à 15:30, Vladimir.S <sva...@gmail.com 
>>>>> <mailto:sva...@gmail.com>> a écrit :
>>>>> 
>>>>> I'm just trying to understand your opinion.
>>>>> Let me know, what result do you *expect* for this Swift4 code given what 
>>>>> 

Re: [swift-evolution] Revisiting SE-0110

2017-06-06 Thread Mark Lacey via swift-evolution

> On Jun 6, 2017, at 8:42 AM, Ray Fix via swift-evolution 
>  wrote:
> 
> 
> FWIW, after doing a project migration last night and this morning, I am 
> reluctantly +1 for reverting SE-0110 and seeing a new proposal that can be 
> properly evaluated.  The split-the-difference compromise mentioned seems like 
> just that, a compromise that will need to be revisited anyway.
> 
> While I agreed with the spirit of the original proposal, the assertion that 
> "Minor changes to user code may be required if this proposal is accepted.” 
> seems like it underestimated the magnitude of the impact. In almost every 
> case, my code lost clarity.

Did you run into issues other than the “tuple destructuring” issue that began 
this thread?

If so, can you provide some examples to illustrate what other issues people are 
hitting in practice?

I put “tuple destructuring” in quotes here because although it looks very much 
like what is happening in Swift 3 and earlier, there was no real tuple 
destructuring support in parameters (as evidenced by the fact that things like 
(x, (y, z)) never worked).

The behavior of allowing:
  [“key” : 1].map { key, value in … }
is the result of allowing the two-argument closure to be passed to a function 
(map) that expects a one-argument function parameter where the argument is a 
two element tuple.

I don’t think anyone disagrees that removing this functionality without 
simultaneously providing a real destructuring feature regresses the usability 
of the language where closures are concerned.

Understanding other fallout from SE-0110 will be helpful in guiding the 
decision of how to move forward from here.

Mark

> 
> Other aspects of the migration went quite smoothly.
> 
> BTW, if I were at WWDC this year I would be in the Swift lab pestering them 
> about this.  Hopefully that feedback is happening. :)
> 
> Ray
> 
> 
>> On Jun 6, 2017, at 8:22 AM, Shawn Erickson via swift-evolution 
>> > wrote:
>> 
>> 
>> On Tue, Jun 6, 2017 at 7:18 AM Gwendal Roué via swift-evolution 
>> > wrote:
>> 
>>> Le 6 juin 2017 à 15:30, Vladimir.S >> > a écrit :
>>> 
>>> I'm just trying to understand your opinion.
>>> Let me know, what result do you *expect* for this Swift4 code given what 
>>> SE-0066 requires for function types:
>>> 
>>> func foo(x : (Int, Int))->() {}
>>> 
>>> print(type(of: foo))  // ??
>>> print(foo is (_: Int, _: Int)->())  // ??
>> 
>> I couldn't care less.
>> 
>> What I care about: the code regressions introduced by SE-0110 (look at 
>> previous messages in this long thread, and the ridiculous state of closures 
>> that eat tuples), and the migration bugs (look at Xcode 9 release notes).
>> 
>> Note that many of Apple's swift team are likely swamped with WWDC at the 
>> moment. They are also dealing with merging out their private changes 
>> announced so far at WWDC. Xcode 9 is prerelease still so expect things to 
>> get revised to some degree before the final release.
>> 
>> Not say to not voice concerns but at this time some patience will be needed.
>> 
>> -Shawn
>> ___
>> 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] Why is the status of SE-0110 "implemented"?

2017-06-06 Thread Mark Lacey via swift-evolution

> On Jun 6, 2017, at 4:00 AM, Vladimir.S <sva...@gmail.com> wrote:
> 
> Mark, could you please also comment this inconsistencies / bugs :
> (swift-4.0-DEVELOPMENT-SNAPSHOT-2017-06-01-a-osx)
> 
> func fooParam(_ x: Int, _ y: Int){}
> func fooTuple(_ x: (Int, Int)) {}
> 
> print("type of fooParam is", type(of:fooParam))
> // result: type of fooParam is (Int, Int) -> ()
> 
> print("type of fooTuple is", type(of:fooTuple))
> // result: type of fooTuple is (Int, Int) -> ()
> 
> print("type of fooTuple as (_:(Int,Int))->Void is", type(of: fooTuple as 
> (_:(Int,Int))->()))
> // result: type of fooTuple as (_:(Int,Int))->() is (Int, Int) -> ()
> 
> 
> print("type of fooParam == type of fooTuple ?", type(of: fooParam) == 
> type(of: fooTuple))
> // result: true
> 
> if fooParam is (_: (Int,Int))->() { print("fooParam is (_: (Int,Int))->()") }
> // result: fooParam is (_: (Int,Int))->()
> 
> if fooTuple is (Int,Int)->() { print("fooTuple is (Int,Int)->()") }
> // result: fooTuple is (Int,Int)->()
> 
> var closureParam = { (x: Int, y: Int) in  }
> var closureTuple = { (x: (Int, Int)) in  }
> 
> print("type of closureParam is", type(of:closureParam))
> // result: type of closureParam is (Int, Int) -> ()
> 
> print("type of closureTuple is", type(of:closureTuple))
> // result: type of closureTuple is (Int, Int) -> ()
> 
> if closureParam is (_: (Int,Int))->() { print("closureParam is (_: 
> (Int,Int))->()") }
> // result: closureParam is (_: (Int,Int))->()
> 
> if closureTuple is (Int,Int)->() { print("closureTuple is (Int,Int)->()") }
> // result: closureTuple is (Int,Int)->()

Can you open two reports at bugs.swift.org <http://bugs.swift.org/>, one for 
the ‘is’ issue, and one for type(of:)?

These (along with the issue with function declarations that Jens mentioned) are 
all similar issues, but each is in a different part of the compiler.

Mark


> 
> Thank you.
> Vladimir.
> 
> On 06.06.2017 11:43, Mark Lacey via swift-evolution wrote:
>>> On Jun 6, 2017, at 12:08 AM, Jens Persson via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> IMHO There seems to be a lot of bugs and inconsistencies left in more than 
>>> just the reflective type system, for example the following won't compile 
>>> although the two foo funcs clearly take different types as argument:
>>> 
>>> func foo(fun: (Int, Int) -> ()) { print("was given a function of type: 
>>> (Int, Int) -> ()") }
>>> func foo(fun: ((Int, Int)) -> ()) { print("was given a function of type: 
>>> ((Int, Int)) -> ()") }
>> I took a look at this. When determining if we have conflicting declarations, 
>> we compute an interface type and this computation is stripping the parens 
>> around the tuple in the second example, resulting in these two signatures 
>> appearing to be the same, despite the fact that the types of the arguments 
>> to the two functions are different.
>>> // This will result in error: invalid redeclaration of 'foo(fun:)'
>>> 
>>> I would expect this to compile, and I can't understand how this has 
>>> anything to do with the reflective type system.
>>> 
>>> 
>>> Here is another example:
>>> 
>>> func add(_ a: Int, _ b: Int) -> Int { return a + b }
>>> let a: (Int, Int) -> Int = add
>>> let b: ((Int, Int)) -> Int = add // This is OK, unexpectedly
>> I didn’t have a chance to look at this yet. I suspect this is related to the 
>> swap example that you gave previously.
>>> I would not expect it to compile since the add func does not have the type 
>>> ((Int, Int)) -> Int.
>>> I don't think that is a dynamic cast, is it?
>> Would you mind opening bugs for all four issues - the two mentioned above 
>> and the two from the previous e-mail (with type(of:) and swap examples)? 
>> Despite the fact that some of these might have different underlying causes 
>> it would be useful to have separate bugs and if they turn out to be the same 
>> issue we can dup as appropriate.
>> Mark
>>> 
>>> /Jens
>>> 
>>> 
>>> 
>>> 
>>> On Tue, Jun 6, 2017 at 2:45 AM, John McCall <rjmcc...@apple.com 
>>> <mailto:rjmcc...@apple.com>> wrote:
>>> 
>>>>On Jun 5, 2017, at 12:08 AM, Jens Persson via swift-evolution
>>>><swift-evolution@swift.o

Re: [swift-evolution] Why is the status of SE-0110 "implemented"?

2017-06-06 Thread Mark Lacey via swift-evolution

> On Jun 6, 2017, at 12:08 AM, Jens Persson via swift-evolution 
>  wrote:
> 
> IMHO There seems to be a lot of bugs and inconsistencies left in more than 
> just the reflective type system, for example the following won't compile 
> although the two foo funcs clearly take different types as argument:
> 
> func foo(fun: (Int, Int) -> ()) { print("was given a function of type: (Int, 
> Int) -> ()") }
> func foo(fun: ((Int, Int)) -> ()) { print("was given a function of type: 
> ((Int, Int)) -> ()") }

I took a look at this. When determining if we have conflicting declarations, we 
compute an interface type and this computation is stripping the parens around 
the tuple in the second example, resulting in these two signatures appearing to 
be the same, despite the fact that the types of the arguments to the two 
functions are different.

> // This will result in error: invalid redeclaration of 'foo(fun:)'
> 
> I would expect this to compile, and I can't understand how this has anything 
> to do with the reflective type system.
> 
> 
> Here is another example:
> 
> func add(_ a: Int, _ b: Int) -> Int { return a + b }
> let a: (Int, Int) -> Int = add
> let b: ((Int, Int)) -> Int = add // This is OK, unexpectedly

I didn’t have a chance to look at this yet. I suspect this is related to the 
swap example that you gave previously.

> I would not expect it to compile since the add func does not have the type 
> ((Int, Int)) -> Int.
> I don't think that is a dynamic cast, is it?

Would you mind opening bugs for all four issues - the two mentioned above and 
the two from the previous e-mail (with type(of:) and swap examples)? Despite 
the fact that some of these might have different underlying causes it would be 
useful to have separate bugs and if they turn out to be the same issue we can 
dup as appropriate.

Mark

> 
> /Jens
> 
> 
> 
> 
> On Tue, Jun 6, 2017 at 2:45 AM, John McCall  > wrote:
>> On Jun 5, 2017, at 12:08 AM, Jens Persson via swift-evolution 
>> > wrote:
>> So the bug in the reflective type system needs to be fixed before SE-0110 
>> can actually be implemented (so that the statements in its title and text 
>> are true when compared to the actual behavior of the current Swift 4 
>> compiler), 
> 
> Gaps in the reflective type system are bugs, but they are not showstopper 
> bugs.  We do not even expose any way to query the reflective system today; it 
> basically only affects type equality and dynamic casts that programmers are 
> very unlikely to use.  The changes in call type-checking are vastly more 
> important, are implemented (modulo bugs, of course), and by themselves 
> warrant calling SE-0110 implemented.
> 
> John.
> 
>> 
>> And yet:
>> 
>> 1. The status of SE-0110 is "Implemented"
>> 
>> 2. These statuses of the following issues are "resolved":
>> SR-2008: Distinguish between single-tuple and multiple-argument function 
>> types
>> SR-2216: Confusing behavior related to closure types and tuples
>> SR-296: Fix inconsistencies related to tuples, arg/param lists, type 
>> params, typealiases
>> 
>> Why?
>> 
>> /Jens
>> 
>> 
>> On Sun, Jun 4, 2017 at 5:49 PM, Ben Rimmington > > wrote:
>> I assumed that Swift 3 mode would be the default, so that existing 
>> `#!/usr/bin/swift` scripts continue to work.
>> 
>> -- Ben
>> 
>> > On 3 Jun 2017, at 23:47, Jens Persson > > > wrote:
>> >
>> > Yes of course, try my demonstration code yourself.
>> > (In the current dev snapshots, -swift-version 4 is the default and 
>> > -swift-version 3 is what you need to set if you want 3 compability)
>> >
>> >> On Sun, Jun 4, 2017 at 12:37 AM, Ben Rimmington > >> > wrote:
>> >>
>> >> Are you using the Swift 4 language mode?
>> >>
>> >> > >> >
>> >>
>> >> -- Ben
>> 
>> ___
>> 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] Revisiting SE-0110

2017-05-25 Thread Mark Lacey via swift-evolution

> On May 25, 2017, at 11:27 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On May 25, 2017, at 2:23 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>  wrote:
>> One possibility is to make parentheses consistently meaningful in closure 
>> argument lists, so that “(a, b)” would exclusively mean “there is one 
>> parameter of tuple-type, which is being destructured”, while “a, b” without 
>> parentheses would exclusively mean “there are two parameters”.
>> 
>> That way you can destructure a tuple parameter if you wish (by using 
>> parentheses) or you can leave the tuple intact (by listing a single 
>> identifier without parentheses).
> 
> The problem with this is that we also need some way to be explicit about the 
> return type, and it would be strange to allow (and require!)
>  { a, b -> Int in }
> when that's not at all a valid way to write a function type

This is allowed today, but I agree it would be very strange to require it. 

We also allow:
  { (a, b: Int) -> Int in } // infer ‘a' from context
and
  { (a, b: () -> Int) -> Int in } // infer ‘a' from context
but these become completely ambiguous if you remove the parens.

> .  Also it would be an enormous source break, even worse than this problem.

Yes.

> That said, I'm quite sympathetic to the idea that directly destructuring 
> tuples in closure parameter lists is too useful to lose, even if it's 
> ambiguous.

I think the right thing to do here is add uniform tuple destructuring in 
functions, but that is clearly out of scope for 4.0.

Reverting SE-0110 is not as simple as reverting a single change. So far I have 
found 19 commits that addressed different aspects moving from the old behavior 
by searching for SE-110 and SE-0110 in commit logs. It is possible there were 
others that did not specifically call out the proposal.

Having said that, we are supposed to support the old behavior for 
"-swift-verison 3", so it may be possible to find the handful of places where 
the version check can be removed and old behavior restored under "-swift-verson 
4" if we choose to do that as mitigation until the destructuring feature is 
properly designed and implemented.

Another option is attempting to do some targeted fix specifically for closure 
arguments but that does not seem straightforward, and does seem relatively 
risky.

Mark


> 
> 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] [Pitch] inout with capture variable

2016-10-05 Thread Mark Lacey via swift-evolution

> On Oct 5, 2016, at 10:07 PM, Cao Jiannan  wrote:
> 
> so if developer want to capture an variable inference, must declare a new 
> variable.

I don’t follow what you mean here.

> 
> class A {
> var value = 1
> 
> func test() -> () -> Int {
> var capturedValue = self.value
> let editInfo = { () -> Int in 
> capturedValue += 1
> return capturedValue
> }
> return editInfo
> }
> }
> 
> let a = A()
> 
> let editInfo = a.test()
> print(editInfo()) // 2
> print(a.value) // 1
> print(editInfo()) // 3
> print(a.value) // 1
> 
> what about:
> 
> class A {
> var value = 1
> 
> func test() -> () -> Int {
> let editInfo = { [inout value] () -> Int in 
> capturedValue += 1
> return capturedValue
> }
> return editInfo
> }
> }
> 
> let a = A()
> 
> let editInfo = a.test()
> print(editInfo()) // 2
> print(a.value) // 2
> print(editInfo()) // 3
> print(a.value) // 3

I’m not quite sure what you’re getting at, but this prints what you’re 
expecting in the output you have in the comments:

class A {
var value = 1

func test() -> () -> Int {
let editInfo = { () -> Int in 
self.value += 1
return self.value
}
return editInfo
}
}

let a = A()

let editInfo = a.test()
print(editInfo()) // 2
print(a.value) // 2
print(editInfo()) // 3
print(a.value) // 3


Mark

> 
> > > On Oct 5, 2016, at 9:06 PM, Cao Jiannan via 
> > > swift-evolution > > >wrote:
> > > 
> > > for example:
> > > 
> > > var a = 1
> > > 
> > > let block = { [inout a] in
> > > a += 1
> > > }
> > > 
> > > block()
> > > block()
> > > 
> > > print(a) // 3
> > This is already how captures work by default in closures and nested 
> > functions in Swift:
> > 
> > var a = 1
> > 
> > let block = { a += 1 }
> > 
> > block()
> > block()
> > 
> > print(a) // prints 3
> > 
> > 
> > If you want to capture something immutably you can put it in the capture 
> > list:
> > 
> > var a = 1
> > let block = { [a] in a += 1 } // error: left side of mutating operator 
> > isn't mutable: 'a' is a 'let' constant
> > 
> > Mark
> > 
> > > 
> > > 
> > > ___
> > > swift-evolution mailing list
> > > swift-evolution@swift.org 
> > > https://lists.swift.org/mailman/listinfo/swift-evolution 
> > > 
> > 
> > 
> > 

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


Re: [swift-evolution] [Pitch] inout with capture variable

2016-10-05 Thread Mark Lacey via swift-evolution

> On Oct 5, 2016, at 9:06 PM, Cao Jiannan via swift-evolution 
>  wrote:
> 
> for example:
> 
> var a = 1
> 
> let block = { [inout a] in
>   a += 1
> }
> 
> block()
> block()
> 
> print(a) // 3

This is already how captures work by default in closures and nested functions 
in Swift:

var a = 1

let block = { a += 1 }

block()
block()

print(a) // prints 3


If you want to capture something immutably you can put it in the capture list:

var a = 1
let block = { [a] in a += 1 } // error: left side of mutating operator isn't 
mutable: 'a' is a 'let' constant

Mark

> 
> 
> ___
> 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 draft] Disallow Optionals in String Interpolation Segments

2016-10-04 Thread Mark Lacey via swift-evolution

> On Oct 4, 2016, at 10:29 AM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> On Tue, Oct 4, 2016, at 10:28 AM, Nate Cook wrote:
>>> On Oct 3, 2016, at 5:49 PM, Kevin Ballard via swift-evolution 
>>> > wrote:
>>> 
>>> On Mon, Oct 3, 2016, at 03:18 PM, Jordan Rose wrote:
> 
> ...
> 
 We had this at one point, but we took it out because people would forget 
 to test the nil case. I think `?? ""` or `?? nil` really is the best 
 answer here.
>>> 
>>> But you can't write that, unless you're dealing specifically with an 
>>> Optional.  If you try you'll get an error:
>>> 
>>> unnamed.swift:2:19: error: binary operator '??' cannot be applied to 
>>> operands of type 'Int?' and 'String'
>>> print("x: \(x ?? "nil")")
>>> ~ ^  ~
>>> unnamed.swift:2:19: note: overloads for '??' exist with these partially 
>>> matching parameter lists: (T?, @autoclosure () throws -> T), (T?, 
>>> @autoclosure () thro
>>> ws -> T?)
>>> print("x: \(x ?? "nil")")
>>>   ^
>>> This leads to writing code like "… \(x.map(String.init(describing:)) ?? 
>>> "nil")" which is pretty gross.
>> 
>> I think that if we're going to add this warning we should make it possible 
>> to provide a string as an alternative. It seems like it should be possible 
>> to build a ?? operator with a (T?, String) -> _StringInterpolationSomething 
>> signature that works only in a string interpolation context.
>> 
>> There are some types that aren't trivially constructible, or don't have 
>> clear alternatives for the nil case. Other times it might just not make 
>> sense to build a new instance simply to turn it into a string. If we're 
>> going to make people provide an alternative for optionals in this otherwise 
>> simple-to-use construct, let's make it simple to do so.
>> 
>> This is undoubtedly a more complex approach that could be considered 
>> separately, but I think it would be a valuable part of how developers could 
>> transition their code.

That’s definitely more complex, and seems like a completely orthogonal feature 
request.

> I like this idea. This combined with the warning for naively interpolating an 
> Optional would be a good solution, because now when I see the warning I can 
> trivially solve it with `?? "nil”`.

If you can suppress the warning with `as T?` (where T? is the type of the thing 
being warned on), you wouldn’t need a form that specifically printed “nil”, 
correct?

Mark

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


Re: [swift-evolution] [Proposal draft] Disallow Optionals in String Interpolation Segments

2016-10-03 Thread Mark Lacey via swift-evolution

> On Oct 3, 2016, at 2:12 PM, Harlan Haskins <har...@harlanhaskins.com> wrote:
> 
> If you don't think this needs a proposal

Well, that’s not up to me, so let’s wait until someone else chimes in. :)

Mark

> , then Robert has an implementation almost done. We could submit a PR later 
> today.
> 
> - Harlan
> 
> On Oct 3, 2016, at 4:06 PM, Mark Lacey via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> On Oct 3, 2016, at 11:26 AM, Joe Groff via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>>> On Oct 3, 2016, at 11:02 AM, Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>> wrote:
>>>> 
>>>> Because the initializer here doesn’t take Any, it takes .
>>> 
>>> I think there's a case to be made to generalize the 'Any' warning to 
>>> Optional implicitly being deduced as a type variable binding in any 
>>> unconstrained context. What exactly constitutes 'implicit' and 
>>> 'unconstrained' is up for debate, though, and probably needs some 
>>> experimentation to figure out what feels good. For instance, explicitly 
>>> constructing an optional is a signal the optionality intentional. 
>>> Potentially, having multiple Optional parameters binding the same type 
>>> variable also increases the likelihood it's intended, for example:
>>> 
>>> func foo(x: T, y: T) {}
>>> 
>>> var x: Int? = 1
>>> var y: Int = 2
>>> foo(x, y) // One Optional isn't unwrapped, forcing the other to promote. 
>>> Maybe a mistake?
>>> var z: Int? = 3
>>> foo(x, z) // Two T parameters are Optional. Probably intentional?
>>> 
>>> Regardless of whether there's a more general principle we can base a 
>>> warning on, string interpolation and String(describing:) are common enough 
>>> pitfalls that they may just deserve special case treatment.
>> 
>> I think string interpolation could be handled pretty easily with a warning 
>> by extending the existing warning for Any. We just need to look at 
>> interpolation expressions and if any of the segments are optional-typed emit 
>> a warning unless they are explicitly casted to the optional type. The fixit 
>> can suggest explicit casting or using the debugDescription.
>> 
>> I’m not sure we really need an evolution proposal for that.
>> 
>> As for the more general topic of trickiness around optional injection into 
>> unconstrained generics: Yes, we should review that at some point as well. I 
>> recall seeing at least one concrete complaint about surprising behavior 
>> resulting from doing this in generic functions, but I cannot find the bug at 
>> the moment.
>> 
>> Mark
>> 
>> 
>>> 
>>> -Joe
>>> 
>>>> ~Robert Widmann
>>>> 
>>>>> On Oct 3, 2016, at 2:00 PM, Harlan Haskins via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> Unfortunately, Optional-to-Any does not currently hit this case because 
>>>>> IIRC it doesn't promote to Any in an interpolation segment. I tested this 
>>>>> with a ToT build yesterday.
>>>>> 
>>>>> - Harlan
>>>>> 
>>>>> On Oct 3, 2016, at 1:57 PM, Joe Groff <jgr...@apple.com 
>>>>> <mailto:jgr...@apple.com>> wrote:
>>>>> 
>>>>>> We now emit a warning whenever an optional is used as an Any. I disagree 
>>>>>> that this should be an error, but it seems reasonable to warn (if we 
>>>>>> don't already thanks to the 'Any' warning).
>>>>>> 
>>>>>> -Joe
>>>>>> 
>>>>>>> On Oct 3, 2016, at 10:52 AM, Harlan Haskins via swift-evolution 
>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>> Hey all,
>>>>>>> 
>>>>>>> Julio Carrettoni, Robert Widmann, and I have been working on a proposal 
>>>>>>> to mitigate something that's burned us all since Swift 1. We'd love 
>>>>>>> some feedback!
>>>>>>> 
>>>>>>> It's available here: 
>>>>>>> https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c

Re: [swift-evolution] [Proposal draft] Disallow Optionals in String Interpolation Segments

2016-10-03 Thread Mark Lacey via swift-evolution

> On Oct 3, 2016, at 11:26 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Oct 3, 2016, at 11:02 AM, Robert Widmann > > wrote:
>> 
>> Because the initializer here doesn’t take Any, it takes .
> 
> I think there's a case to be made to generalize the 'Any' warning to Optional 
> implicitly being deduced as a type variable binding in any unconstrained 
> context. What exactly constitutes 'implicit' and 'unconstrained' is up for 
> debate, though, and probably needs some experimentation to figure out what 
> feels good. For instance, explicitly constructing an optional is a signal the 
> optionality intentional. Potentially, having multiple Optional parameters 
> binding the same type variable also increases the likelihood it's intended, 
> for example:
> 
> func foo(x: T, y: T) {}
> 
> var x: Int? = 1
> var y: Int = 2
> foo(x, y) // One Optional isn't unwrapped, forcing the other to promote. 
> Maybe a mistake?
> var z: Int? = 3
> foo(x, z) // Two T parameters are Optional. Probably intentional?
> 
> Regardless of whether there's a more general principle we can base a warning 
> on, string interpolation and String(describing:) are common enough pitfalls 
> that they may just deserve special case treatment.

I think string interpolation could be handled pretty easily with a warning by 
extending the existing warning for Any. We just need to look at interpolation 
expressions and if any of the segments are optional-typed emit a warning unless 
they are explicitly casted to the optional type. The fixit can suggest explicit 
casting or using the debugDescription.

I’m not sure we really need an evolution proposal for that.

As for the more general topic of trickiness around optional injection into 
unconstrained generics: Yes, we should review that at some point as well. I 
recall seeing at least one concrete complaint about surprising behavior 
resulting from doing this in generic functions, but I cannot find the bug at 
the moment.

Mark


> 
> -Joe
> 
>> ~Robert Widmann
>> 
>>> On Oct 3, 2016, at 2:00 PM, Harlan Haskins via swift-evolution 
>>> > wrote:
>>> 
>>> Unfortunately, Optional-to-Any does not currently hit this case because 
>>> IIRC it doesn't promote to Any in an interpolation segment. I tested this 
>>> with a ToT build yesterday.
>>> 
>>> - Harlan
>>> 
>>> On Oct 3, 2016, at 1:57 PM, Joe Groff >> > wrote:
>>> 
 We now emit a warning whenever an optional is used as an Any. I disagree 
 that this should be an error, but it seems reasonable to warn (if we don't 
 already thanks to the 'Any' warning).
 
 -Joe
 
> On Oct 3, 2016, at 10:52 AM, Harlan Haskins via swift-evolution 
> > wrote:
> 
> Hey all,
> 
> Julio Carrettoni, Robert Widmann, and I have been working on a proposal 
> to mitigate something that's burned us all since Swift 1. We'd love some 
> feedback!
> 
> It's available here: 
> https://gist.github.com/harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd 
> 
> 
> I've posted the current draft below.
> 
> Thanks,
> Harlan Haskins
> 
> Disallow Optionals in String Interpolation Segments
> 
> Proposal: SE- 
> Authors: Harlan Haskins , Julio 
> Carrettoni , Robert Widmann 
> 
> Review Manager: TBD
> Status: Awaiting revie
>  
> Introduction
> 
> Swift developers frequently use string interpolation as a convenient, 
> concise syntax for interweaving variable values with strings. The 
> interpolation machinery, however, has surprising behavior in one specific 
> case: Optional. If a user puts an optional value into a string 
> interpolation segment, it will insert either "Optional("value")" or "nil" 
> in the resulting string. Neither of these is particularly desirable, so 
> we propose a warning and fix-it to surface solutions to these potential 
> mistakes.
> 
> Swift-evolution thread: Discussion thread topic for that proposal 
> 
>  
> Motivation
> 
> The Swift Programming Language defines string interpolation segments as 
> "a way to construct a new String value from a mix of constants, 
> variables, literals, and expressions". There is one type that runs 
> counter to this definition: 

Re: [swift-evolution] pattern matching on variable-sized data type

2016-09-06 Thread Mark Lacey via swift-evolution

> On Sep 6, 2016, at 7:47 AM, Jean-Denis Muys via swift-evolution 
>  wrote:
> 
> Hello,
> 
> I would like to suggest an additive evolution to Swift that might be in scope 
> of phase 1 of Swift 4 (because it might have an impact on the ABI).

How would you expect this to have an impact on ABI?

Mark

> 
> The idea is to extend the pattern matching abilities of Swift to enable a 
> recursive programming style that’s very common in languages such as Lisp, ML, 
> or Prolog on a collection that is processed as a list. By analogy to ML, 
> Swift could do that on tuples, or on arrays, or on any similar, perhaps new, 
> data type. This would allow the following for example:
> 
> func listOfDifferenceOfListElements (list: List) -> Int {
> 
> switch list {
> case 〘〙: {
> return 〘〙
> }
> case 〘 let a 〙: {
> return 〘 a 〙
> }
> case 〘 let a, let b ⫸ let tail 〙: {
> return 〘 a-b 〙 ⋙ sumDifferenceOfListElements(tail)
> }
> }
> }
> 
> 
> Where I deliberately used unusual Unicode characters to denote syntax that 
> would need to be invented:
> 
> - 〘〙 to denote the list-like data structure. It would be old style 
> parenthesis if we wanted that to be Swift’s tuple, or the usual bracket if it 
> was arrays
> - ⫸ to pattern-match the tail of the list, i.e. the list composed of any and 
> all elements following whatever has been pattern-matched so far
> - ⋙ to denote a list append operator.
> 
> If we wanted the list data-type to be tuples, this would require the ability 
> to build longer tuples from existing ones, i.e. build (a, b, c) from a and 
> (b, c), or from (a) and (b, c) (appending tuples). Array seems more suitable, 
> however.
> 
> So this post is to assess the interest in such a feature. Also note that 
> while I have tried to have an occasional look at this mailing list in the 
> past, due to its overwhelming volume, I may very well have missed a similar 
> discussion in the past. In that case, I would appreciate a pointer.
> 
> As someone who developed Lisp and Prolog software professionally in a rather 
> distant past, with an ever renewed sense of wonder, I would very much love to 
> be able to use that programming style again when it makes sense.
> 
> If there is interest, I would be willing to write up an evolution proposal.
> 
> Jean-Denis Muys
> 
> ___
> 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] [Swift4][Pitch] Control struct layout with @layout, @offset, @order

2016-08-17 Thread Mark Lacey via swift-evolution

> On Aug 17, 2016, at 11:28 AM, Russ Bishop via swift-evolution 
>  wrote:
> 
> I wanted to gauge the interest in supporting explicit struct layout and 
> alignment.
> 
> The general idea would be to support attributes to create packed structs and 
> set alignment. It will be critical for certain kinds of interop and systems 
> programming in pure Swift. I don’t know about you but I want to write a 
> kernel module in Swift someday :) I’m bringing it up because it probably 
> affects ABI stability and resilience and so meets the requirements for Swift 
> 4 phase 1.

Explicit layout matters for the ABI once the feature exists, but it seems 
purely additive, i.e. out of scope for Swift 4 phase 1. You can ship without 
any explicit layout support and add it later without impacting code that ships 
before the feature exists.

Mark

> 
> Hopefully this could be a jumping-off point for further discussion. If the 
> core team doesn’t think this affects ABI stability then we can postpone 
> discussing it until Swift 4 phase 1 wraps up.
> 
> 
> @layout(style: auto, alignment: natural)
> 
> enum LayoutStyle {
> /// Compiler is free to order the fields as it likes
> case automatic
> /// Places a struct's members in source order
> case sequential
> /// Requires each member to have an @order attribute
> case ordered
> /// Requires each member to have an @offset attribute
> case explicit
> }
> 
> Only structs with certain @layout attributes would be exportable to non-Swift 
> languages (assuming such support is added at some point). A struct defined 
> with ordered or explicit layout and as resilient could possibly avoid 
> indirect access to members since the ABI contract guarantees the location of 
> each member.
> 
> 
> enum Alignment {
> /// Compiler decides
> case natural
> /// Align as if the natural alignment were specified bytes
> case bytes(Int)
> }
> 
> 
> 
> @order()
> 
> Specifies the order of the member in memory. Order must start at zero and 
> increase monotonically without gaps. This makes accidental changes to the 
> ordering errors.
> 
> 
> 
> @offset()
> 
> Specifies the offset from the start of the struct where this member should be 
> placed. The size of the struct becomes the highest offset plus the size of 
> the member with that offset.
> 
> It is an open question whether overlapping alignment should be allowed. If it 
> is allowed I’d propose that for any set of members overlapping all of the 
> members must be entirely contained within the largest overlapping member (I’m 
> thinking of C-style unions when the struct format is imposed by something 
> outside your control).
> 
> 
> 
> Thoughts?
> 
> Russ
> 
> 
> 
> 
> 
> ___
> 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] [Meta] What does the backlog mean to the process?

2016-07-29 Thread Mark Lacey via swift-evolution


> On Jul 29, 2016, at 09:30, Karl via swift-evolution 
>  wrote:
> 
> 
>> On 29 Jul 2016, at 18:01, Brandon Knope via swift-evolution 
>>  wrote:
>> 
>> I think this just shows how familiar many of us are with this process.
>> 
>> It’s fun and challenging coming up with the great ideas…but someone has to 
>> implement it. It may not be fun…and it may be very time consuming.
>> 
>> I think a lot of us just expected the core team to implement these all…but 
>> they really need help from the community to save them time and sanity with 
>> trying to get all of this done.
>> 
>> 
>> To me this means I need to familiarize myself with the swift code base even 
>> more. I need to understand all the GitHub processes to get a change 
>> implemented and submitted.
>> 
>> I really hope at some point someone can make a primer of the process they 
>> went through to implement one of these proposals from start to finish. I 
>> think this could be illuminating for many on this list.
>> 
>> ALSO: I think this is where a forum can help greatly: some of us need a way 
>> to discuss our implementations and ask for help while we are working on one 
>> of these proposals. Mailing lists make it very hard to have a general 
>> discussion where we talk code and ask for help in get detail. It is also 
>> much easier for others to browse to learn from that conversation.
>> 
>> In short: the swift-evolution process works…but some of us in the community 
>> need to step up and help a little more other than just proposing things. I 
>> think the swift team could make this easier with some detailed guides and 
>> documentation and a forum for better discussions when trying to implement 
>> these things…but I know they are insanely busy. I do think some time 
>> investment in this area will pay off in the future…and quickly.
>> 
>> Brandon
>> 
>>> On Jul 29, 2016, at 11:15 AM, Félix Cloutier via swift-evolution 
>>>  wrote:
>>> 
>>> Hello all,
>>> 
>>> With the Swift 3 deadline passed, according to the Swift Evolution progress 
>>> page, about 20% of the proposals that the community voted in won't make it 
>>> for Swift 3. Beyond the implications for the language itself, what does 
>>> that mean for the swift-evolution process?
>>> 
>>> Félix
>>> 
>>> ___
>>> 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
> 
> The thing that’s stopping me contributing to the compiler itself is that it 
> uses LLVM types and functions, and I don’t know them. The Swift compiler 
> itself looks very clean and approachable.
> 
> And then, when you try to look up any of those LLVM functions, you get 
> Doxygen, which isn’t really great. It just puts me off really getting to 
> grips with LLVM’s conventions. Maybe one day when I have more time.
> 
> Unless somebody knows of some better documentation?

This is a good reference if you want to start getting to know things like 
DenseMap, SmallVector, etc.: 
http://llvm.org/docs/ProgrammersManual.html#picking-the-right-data-structure-for-a-task

The other thing I would suggest is just taking a look at the headers and when 
needed the source. Most of the ADTs closely resemble STL counterparts in API 
and are easy to get up-to-speed with. 

I have never taken a serious look at the Doxygen documentation as I personally 
don't find it useful with the source available. 

Mark

> 
> Karl
> ___
> 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] [Draft][Proposal] Formalized Ordering

2016-07-22 Thread Mark Lacey via swift-evolution

> On Jul 21, 2016, at 10:37 PM, Dmitri Gribenko via swift-evolution 
>  wrote:
> 
> On Thu, Jul 21, 2016 at 10:17 PM, Xiaodi Wu  wrote:
>> Robert, the gist is notably vague on this point, so I'm hoping you will
>> clarify. Are you proposing that FloatingPoint will break with IEEE754
>> semantics? What will be the result of `Float.nan == Float.nan`?
>> 
>> (My guess at the sanest outcome is that areSame/Equivalent() and <=> will be
>> totally ordered but FloatingPoint types will override == and the standard
>> comparison operators to maintain IEEE754 semantics, yes?)
> 
> Right, == (and !=, <, >, <=, >=) can be customized with
> domain-specific semantics, and floating point does this.  In addition,
> floating point protocols will list == as a requirement, so generic
> code generic over floating point types will get IEEE 754 semantics
> when using == syntax, but code that only has an Equatable requirement
> will use the total ordering semantics.

I think this needs to be spelled out clearly in the final proposal. 
Floating-point compares involving NaN are mentioned in the motivation section, 
but there is no clear connection made to that issue in the proposal or detailed 
design.

Mark

> 
> Dmitri
> 
> -- 
> main(i,j){for(i=2;;i++){for(j=2;j (j){printf("%d\n",i);}}} /*Dmitri Gribenko */
> ___
> 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] [Meta] Proposal status page

2016-07-18 Thread Mark Lacey via swift-evolution

> On Jul 18, 2016, at 4:44 PM, Jacob Bandes-Storch via swift-evolution 
>  wrote:
> 
> This is now live:  http://apple.github.io/swift-evolution/ 
> 
Very very nice!

I wonder if we should do something to avoid the 404 here though: 
http://apple.github.io 

Perhaps a redirect to https://github.com/apple/swift 
 or maybe directly to 
https://github.com/apple/swift/blob/master/README.md? 


Mark

> 
> On Fri, Jul 15, 2016 at 8:08 AM, Thorsten Seitz  > wrote:
> Cool! Looks great!
> 
> -Thorsten 
> 
> Am 14.07.2016 um 10:30 schrieb Jacob Bandes-Storch via swift-evolution 
> >:
> 
>> I got sidetracked today and mocked up a proposal "status page":
>> 
>> http://jtbandes.github.io/swift-evolution/ 
>> 
>> 
>> This moves the proposal status info (currently in README.md) into a separate 
>> "source of truth":
>> 
>> https://github.com/jtbandes/swift-evolution/blob/master/proposals.xml 
>> 
>> 
>> The status page is then generated from the source of truth using XSLT. 
>> Unfortunately, in order to get this working on GitHub Pages, I had to load 
>> the files using JavaScript (otherwise the browser blocks the cross-origin 
>> requests): 
>> https://github.com/jtbandes/swift-evolution/blob/gh-pages/index.html 
>> .
>> 
>> 
>> If we wanted to adopt this for the official swift-evolution repo, the steps 
>> would be:
>> 
>> 1. push the XML and XSL files to master
>> 
>> 2. push a gh-pages branch with the status page
>> 
>> 3. update README.md on master to point to the status page, rather than 
>> duplicating all the information.
>> 
>> 
>> Thoughts? Tweaks? Insults?
>> 
>> Jacob
>> ___
>> 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] Optional comparison operators

2016-07-12 Thread Mark Lacey via swift-evolution

> On Jul 12, 2016, at 12:58 AM, Charlie Monroe <char...@charliemonroe.net> 
> wrote:
> 
> An example to keep in mind:
> 
> let dict: [String : String] = ...
> if dict["key"] == "value" { // String? == String
>   // Do something
> }
> 
> If I understand correctly, when the proposal is accepted, you'd need to do 
> something like:
> 
> if let value = dict["key"], value == "value" { } 
> -- OR --
> if dict["key"] == Optional("value") { }
> 
> It's not an end of the world, but makes life a bit more difficult and such 
> usecase should be kept in mind.

Yes, Jacob also pointed this out.

Sometime later today I will push out an updated proposal that calls this out, 
and also discusses the overloads for equality and identity comparisons where 
one side is optional. I want to take another quick look at some of the changes 
I had to make to projects I looked at before I do so.

Mark

> 
> 
>> On Jul 12, 2016, at 9:09 AM, Mark Lacey via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Jul 11, 2016, at 11:55 PM, Jacob Bandes-Storch <jtban...@gmail.com 
>>> <mailto:jtban...@gmail.com>> wrote:
>>> 
>>> Mark,
>>> Thanks for writing this up. Just to clarify, will these still work if your 
>>> proposal is implemented?
>>> 
>>> let x: Int?
>>> let y: Int
>>> struct NotEquatable {}
>>> let z: NotEquatable?
>>> 
>>> x == y; x != y
>>> x == nil; x != nil
>>> z == nil; z != nil
>>> 
>>> I would hope that these continue to work. If any changes need to be made to 
>>> ensure that, please make sure they're included in the proposal too.
>> 
>> The last four would work, but the first two (x == y and x != y) would not 
>> because they still involve coercing y to an optional.
>> 
>> Similarly, === and !== on reference types where one is an optional would 
>> require coercing one side, and would not be accepted without an explicit 
>> cast using Optional().
>> 
>> I’m curious what the motivation is for further special casing these 
>> operators. They do occur more in practice than <, <=, >, >= (in fact most of 
>> the source updates I had to make were due to === and !==, with == and != a 
>> close second), but overall these are still quite uncommon from what I’ve 
>> seen.
>> 
>> If you’d like I can certainly update the “alternatives considered” to 
>> include the suggestion that we add overloads for (T, T?) and (T?, T) for 
>> those four operators.
>> 
>> Mark
>> 
>>> 
>>> Jacob
>>> 
>>> On Mon, Jul 11, 2016 at 9:35 PM, Mark Lacey <mark.la...@apple.com 
>>> <mailto:mark.la...@apple.com>> wrote:
>>> 
>>>> On Jul 11, 2016, at 9:12 PM, Chris Lattner via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> 
>>>>> On Jul 11, 2016, at 8:14 PM, Jacob Bandes-Storch via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> You'd have to unwrap it, or use the ??/==/!= operators: 
>>>>> https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38 
>>>>> <https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38>
>>>>> 
>>>>> I'd be okay with />= returning Bool?, as I suggested in an older 
>>>>> email (which somehow didn't make it to gmane's archive, but it's quoted 
>>>>> in some other messages 
>>>>> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/10095>). I think 
>>>>> it would be more convenient in some cases than unwrapping the individual 
>>>>> values before comparing them.
>>>> 
>>>> I’d be strongly opposed to those operator returning “Bool?”.  Doing so 
>>>> would prevent conforming to Comparable and would be extremely surprising.
>>>> 
>>>> -Chris
>>> 
>>> I just pushed the current draft of the proposal: 
>>> https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/-disallow-value-to-optional-coercion-in-operator-arguments.md
>>>  
>>> <https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/-disallow-value-to-optional-coercion-in-operator-argum

Re: [swift-evolution] Optional comparison operators

2016-07-12 Thread Mark Lacey via swift-evolution

> On Jul 12, 2016, at 12:16 AM, Jacob Bandes-Storch  wrote:
> 
> Okay, I guess it's fair that (T, T?) and (T?, T) overloads should have to be 
> a separate proposal.
> 
> My personal motivation is mostly anecdotal; I've found them quite useful, and 
> I wouldn't say they're uncommon.

Sure, I mean uncommon in the sense that in the projects I’ve looked at I’m 
seeing them perhaps once every 1,000-2,000 lines of commented code, not 
uncommon in the sense that you will almost never see them in practice. I’m sure 
for some projects it’s going to be much more often than others.

Mark

> Some use cases off the top of my head:
> - checking whether a dictionary contains a particular value for a key
> - checking whether an optional ivar (such as "selectedIndex: Int?") contains 
> a particular value ("if tappedIndex == selectedIndex”)
> 
> Jacob
> 
> On Tue, Jul 12, 2016 at 12:09 AM, Mark Lacey  > wrote:
> 
>> On Jul 11, 2016, at 11:55 PM, Jacob Bandes-Storch > > wrote:
>> 
>> Mark,
>> Thanks for writing this up. Just to clarify, will these still work if your 
>> proposal is implemented?
>> 
>> let x: Int?
>> let y: Int
>> struct NotEquatable {}
>> let z: NotEquatable?
>> 
>> x == y; x != y
>> x == nil; x != nil
>> z == nil; z != nil
>> 
>> I would hope that these continue to work. If any changes need to be made to 
>> ensure that, please make sure they're included in the proposal too.
> 
> The last four would work, but the first two (x == y and x != y) would not 
> because they still involve coercing y to an optional.
> 
> Similarly, === and !== on reference types where one is an optional would 
> require coercing one side, and would not be accepted without an explicit cast 
> using Optional().
> 
> I’m curious what the motivation is for further special casing these 
> operators. They do occur more in practice than <, <=, >, >= (in fact most of 
> the source updates I had to make were due to === and !==, with == and != a 
> close second), but overall these are still quite uncommon from what I’ve seen.
> 
> If you’d like I can certainly update the “alternatives considered” to include 
> the suggestion that we add overloads for (T, T?) and (T?, T) for those four 
> operators.
> 
> Mark
> 
>> 
>> Jacob
>> 
>> On Mon, Jul 11, 2016 at 9:35 PM, Mark Lacey > > wrote:
>> 
>>> On Jul 11, 2016, at 9:12 PM, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
>>> 
 On Jul 11, 2016, at 8:14 PM, Jacob Bandes-Storch via swift-evolution 
 > wrote:
 
 You'd have to unwrap it, or use the ??/==/!= operators: 
 https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38 
 
 
 I'd be okay with />= returning Bool?, as I suggested in an older 
 email (which somehow didn't make it to gmane's archive, but it's quoted in 
 some other messages 
 ). I think 
 it would be more convenient in some cases than unwrapping the individual 
 values before comparing them.
>>> 
>>> I’d be strongly opposed to those operator returning “Bool?”.  Doing so 
>>> would prevent conforming to Comparable and would be extremely surprising.
>>> 
>>> -Chris
>> 
>> I just pushed the current draft of the proposal: 
>> https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/-disallow-value-to-optional-coercion-in-operator-arguments.md
>>  
>> 
>> 
>> I haven’t addressed removal of the ordered comparison operators. I suspect 
>> this should be a separate proposal, but I can roll that into this one if 
>> it’s desired.
>> 
>> I’ll update the proposal as the discussion continues until it’s selected for 
>> review.
>> 
>> Mark
>> 
>>> 
>>> ___
>>> 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] Optional comparison operators

2016-07-12 Thread Mark Lacey via swift-evolution

> On Jul 11, 2016, at 11:55 PM, Jacob Bandes-Storch  wrote:
> 
> Mark,
> Thanks for writing this up. Just to clarify, will these still work if your 
> proposal is implemented?
> 
> let x: Int?
> let y: Int
> struct NotEquatable {}
> let z: NotEquatable?
> 
> x == y; x != y
> x == nil; x != nil
> z == nil; z != nil
> 
> I would hope that these continue to work. If any changes need to be made to 
> ensure that, please make sure they're included in the proposal too.

The last four would work, but the first two (x == y and x != y) would not 
because they still involve coercing y to an optional.

Similarly, === and !== on reference types where one is an optional would 
require coercing one side, and would not be accepted without an explicit cast 
using Optional().

I’m curious what the motivation is for further special casing these operators. 
They do occur more in practice than <, <=, >, >= (in fact most of the source 
updates I had to make were due to === and !==, with == and != a close second), 
but overall these are still quite uncommon from what I’ve seen.

If you’d like I can certainly update the “alternatives considered” to include 
the suggestion that we add overloads for (T, T?) and (T?, T) for those four 
operators.

Mark

> 
> Jacob
> 
> On Mon, Jul 11, 2016 at 9:35 PM, Mark Lacey  > wrote:
> 
>> On Jul 11, 2016, at 9:12 PM, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Jul 11, 2016, at 8:14 PM, Jacob Bandes-Storch via swift-evolution 
>>> > wrote:
>>> 
>>> You'd have to unwrap it, or use the ??/==/!= operators: 
>>> https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38 
>>> 
>>> 
>>> I'd be okay with />= returning Bool?, as I suggested in an older 
>>> email (which somehow didn't make it to gmane's archive, but it's quoted in 
>>> some other messages 
>>> ). I think 
>>> it would be more convenient in some cases than unwrapping the individual 
>>> values before comparing them.
>> 
>> I’d be strongly opposed to those operator returning “Bool?”.  Doing so would 
>> prevent conforming to Comparable and would be extremely surprising.
>> 
>> -Chris
> 
> I just pushed the current draft of the proposal: 
> https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/-disallow-value-to-optional-coercion-in-operator-arguments.md
>  
> 
> 
> I haven’t addressed removal of the ordered comparison operators. I suspect 
> this should be a separate proposal, but I can roll that into this one if it’s 
> desired.
> 
> I’ll update the proposal as the discussion continues until it’s selected for 
> review.
> 
> Mark
> 
>> 
>> ___
>> 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] Optional comparison operators

2016-07-12 Thread Mark Lacey via swift-evolution

> On Jul 11, 2016, at 9:54 PM, Chris Lattner  wrote:
> 
>> 
>> On Jul 11, 2016, at 9:35 PM, Mark Lacey > > wrote:
>> 
>> 
>>> On Jul 11, 2016, at 9:12 PM, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
>>> 
 On Jul 11, 2016, at 8:14 PM, Jacob Bandes-Storch via swift-evolution 
 > wrote:
 
 You'd have to unwrap it, or use the ??/==/!= operators: 
 https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38 
 
 
 I'd be okay with />= returning Bool?, as I suggested in an older 
 email (which somehow didn't make it to gmane's archive, but it's quoted in 
 some other messages 
 ). I think 
 it would be more convenient in some cases than unwrapping the individual 
 values before comparing them.
>>> 
>>> I’d be strongly opposed to those operator returning “Bool?”.  Doing so 
>>> would prevent conforming to Comparable and would be extremely surprising.
>>> 
>>> -Chris
>> 
>> I just pushed the current draft of the proposal: 
>> https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/-disallow-value-to-optional-coercion-in-operator-arguments.md
>>  
>> 
>> 
>> I haven’t addressed removal of the ordered comparison operators. I suspect 
>> this should be a separate proposal, but I can roll that into this one if 
>> it’s desired.
>> 
>> I’ll update the proposal as the discussion continues until it’s selected for 
>> review.
> 
> I think it makes sense to keep removal of the non-equality comparisons a 
> separate proposal.
> 
> Here are some nit-picky comments:
> 
> I’d suggest adding quotes:
> 
> … by making the notion of “having" or "not having" a value explicit. 
> 
> Missing a let/var before the first x in:
> 
> func returnsOptional() -> Int? {
>   x: Int = ...
>   return x
> }
> 
> 
> I would move “Proposed Solution” before “Motivation” and just call it 
> “Proposal”.  Otherwise the motivation section doesn’t make sense to read in 
> order.
> 
> 
> I’d add to this:
> "Both of these examples represent cases where the silent behavior could 
> potentially hide bugs or confuse readers of the code.”  
> 
> … “, it would be better to reject the code as a type error."
> 
> 
> If this is relating to implementation details of the standard library, then 
> it should be omitted from the proposal.  The following paragraph also makes 
> sense to revise if you drop this:
> "Additionally the standard library has approximately a half a dozen locations 
> where optionals are compared to non-optional values which will need to be 
> updated to explicitly cast one operand to an optional.”
> 

Thanks for the great feedback. I have most of it addressed, but I’m not sure 
what you’re referring to with “If this is relating to implementation details of 
the standard library…”? Do you mean the functions I called out that need to be 
added?

I can remove that, but I thought it was worth calling out despite the fact that 
they are just overloads. If it’s not necessary to do so, I’ll delete that 
section (although there aren’t many details left in the “Detailed design” at 
that point).

Mark

> 
> In this paragraph, I’d recommend changing the wording to be specific and 
> opinionated (saying that “Optional” is the right answer).  If you want to 
> raise specific alternatives for consideration, please add it to “alternatives 
> considered” at the end:
> "This conversion can currently be accomplished by using Optional() 
> (preferable) or alternately .some(). We could also consider adding a new 
> top-level function for this purpose, but unless it provides additional 
> clarity, it seems like Optional() is reasonable and quite prominent."
> 
> Keeping the body of the proposal opinionated makes the review periods more 
> useful because people know what is specifically being proposed.
> 
> 
> 
> "In a survey of six projects” -> Can you explicitly share the name of any of 
> the projects?
> 
> Otherwise, LGTM.  When you’re happy with it, please submit a PR for 
> swift-evolution repo, I’ll review managerize it,
> 
> -Chris

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


Re: [swift-evolution] Optional comparison operators

2016-07-11 Thread Mark Lacey via swift-evolution

> On Jul 11, 2016, at 9:12 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
>> On Jul 11, 2016, at 8:14 PM, Jacob Bandes-Storch via swift-evolution 
>> > wrote:
>> 
>> You'd have to unwrap it, or use the ??/==/!= operators: 
>> https://gist.github.com/jtbandes/9d88cc83ceceb6c62f38 
>> 
>> 
>> I'd be okay with />= returning Bool?, as I suggested in an older email 
>> (which somehow didn't make it to gmane's archive, but it's quoted in some 
>> other messages 
>> ). I think it 
>> would be more convenient in some cases than unwrapping the individual values 
>> before comparing them.
> 
> I’d be strongly opposed to those operator returning “Bool?”.  Doing so would 
> prevent conforming to Comparable and would be extremely surprising.
> 
> -Chris

I just pushed the current draft of the proposal: 
https://github.com/rudkx/swift-evolution/blob/eliminate-value-to-optional-coercion/proposals/-disallow-value-to-optional-coercion-in-operator-arguments.md
 


I haven’t addressed removal of the ordered comparison operators. I suspect this 
should be a separate proposal, but I can roll that into this one if it’s 
desired.

I’ll update the proposal as the discussion continues until it’s selected for 
review.

Mark

> 
> ___
> 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] Optional comparison operators

2016-07-11 Thread Mark Lacey via swift-evolution

> On Jul 11, 2016, at 6:02 PM, Jacob Bandes-Storch  wrote:
> 
> On Mon, Jul 11, 2016 at 5:58 PM, Chris Lattner  > wrote:
> On Jul 11, 2016, at 4:56 PM, Jacob Bandes-Storch via swift-evolution 
> > wrote:
> > Personally I think we should just remove these optional-taking variants of 
> > the comparison operators. Does anyone agree/disagree?
> >
> > It does make sense to keep ==(T?, T?) and !=(T?, T?), and if coercion were 
> > removed, we might want to add (T, T?) and (T?, T) versions. Are there any 
> > other operators that would be affected by your proposal? If not, removing 
> > the optional />= would obviate the need to remove coercion.
> 
> My opinion:
>  - We need to remove T -> T? promotion from operators for a whole lot of 
> reasons.  People are frequently surprised by the behavior of the ?? operator 
> promoting the LHS to optional, for example.  There are a ton of “bugs” that 
> people file that are related to issues like that.
> 
> Thinking about this a bit more, couldn't the same class of "gotcha" happen 
> with regular functions, too? Why should this be changed for operators 
> specifically?

This occurred to me when I was considering this over the weekend, but operators 
are already quite special. You can specify whether they are infix, prefix, or 
postfix, and assign a precedence. They are used without any special syntax to 
“apply” them, unlike normal functions which are applied with (…). I would go as 
far as saying that most (non-PL, non-compiler implementor) people wouldn’t 
consider operators and normal functions to be very closely related at all.

We clearly wouldn’t want to remove the coercion for the regular functions 
because it’s extremely convenient. I know you’re not suggesting doing so, I’m 
just pointing out that if we made things uniform we’d clearly have to keep the 
coercion by default.

> Maybe it makes more sense to have some kind of "@noncoercing" parameter, so 
> that coercion can still take place, but operator could be defined as `func 
> ??(lhs: @noncoercing T?, rhs: T?)`

I’m not sure it’s really worth adding another attribute just for this purpose.

Mark


>  
>  - We don’t have conditional conformances, so Optional cannot conditionally 
> conform to Equatable and Comparable in Swift 3.  In a later release, we can 
> consider whether adding them is a good idea.
>  - We currently support equatable comparing an arbitrary optional to nil (one 
> in which T is not necessarily Equatable), which I think is useful to keep 
> around.
>  - If we allow that, then it makes sense to allow == and != operators for 
> optionals where T is Equatable, even though the optional itself cannot 
> conditionally conform to Equatable.  The “surprising” aspect of equatable 
> comparison doing promotions will have been removed.
> 
> The questionable piece is what to do with />=.  I would lean towards 
> removing them in Swift 3 simply because it is easier to "remove now, but add 
> them back later" if they really are important.  The argument for keeping them 
> is that the surprising aspect will be solved by removing the first promotion 
> - "42 > nil” will cease to type-check, so they may not actually be harmful 
> anymore.
> 
> -Chris
> 

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


Re: [swift-evolution] Optional comparison operators

2016-07-11 Thread Mark Lacey via swift-evolution

> On Jul 11, 2016, at 4:59 PM, Xiaodi Wu  wrote:
> 
> Yup, I too would prefer removing the functions over removing coercion.

Hi Xiaodi,

Is there a reason you think the coercion is important to keep?

I see these as somewhat orthogonal issues (allowing or disallowing coercion vs. 
keeping or removing certain operators that take optionals or for that matter 
changing the defined behavior in the case of nil operands mixed with non-nil 
operands).

Mark

> 
> On Mon, Jul 11, 2016 at 18:57 Jacob Bandes-Storch via swift-evolution 
> > wrote:
> Personally I think we should just remove these optional-taking variants of 
> the comparison operators. Does anyone agree/disagree?
> 
> It does make sense to keep ==(T?, T?) and !=(T?, T?), and if coercion were 
> removed, we might want to add (T, T?) and (T?, T) versions. Are there any 
> other operators that would be affected by your proposal? If not, removing the 
> optional />= would obviate the need to remove coercion.
> 
> Jacob
> 
> On Mon, Jul 11, 2016 at 4:45 PM, Mark Lacey  > wrote:
> 
>> On Jul 11, 2016, at 4:32 PM, Jacob Bandes-Storch > > wrote:
>> 
>> Great, thanks Mark! I look forward to it.
> 
> To be clear, I’m specifically looking at making the change to remove the 
> coercion from T to T? for operator arguments.
> 
> I agree there might be other things worth looking at regarding operators that 
> take optionals, but I’m not currently looking at those issues.
> 
> Mark
> 
>> 
>> On Mon, Jul 11, 2016 at 4:31 PM, Mark Lacey > > wrote:
>> Hi Jacob,
>> 
>>> On Jul 11, 2016, at 4:23 PM, Jacob Bandes-Storch via swift-evolution 
>>> > wrote:
>>> 
>>> Bump for Swift 3.
>>> 
>>> On Thu, Jul 7, 2016 at 2:37 PM, Jacob Bandes-Storch >> > wrote:
>>> These operators cause some potential for confusion:
>>> 
>>> public func <(lhs: T?, rhs: T?) -> Bool
>>> public func >(lhs: T?, rhs: T?) -> Bool
>>> public func <=(lhs: T?, rhs: T?) -> Bool
>>> public func >=(lhs: T?, rhs: T?) -> Bool
>>> 
>>> 1. The meaning of T? < T? is not immediately obvious (Why is nil < .some(x) 
>>> for any x? Personally, my intuition says that Optional should only provide 
>>> a partial order, with .none not being ordered w.r.t. .some(x).)
>>> 
>>> 2. Even if the meaning is understood, it can be surprising when the (T?, 
>>> T?) -> Bool version is used instead of (T, T) -> Bool.
>>> 
>>> Prior discussion:
>>> - http://thread.gmane.org/gmane.comp.lang.swift.devel/2089 
>>> 
>>> - http://thread.gmane.org/gmane.comp.lang.swift.evolution/10095 
>>> 
>>> - rdar:// <>16966712&22833869
>>> - Replies to https://twitter.com/jtbandes/status/646914031433871364 
>>> 
>>> 
>>> In the swift-dev thread from May, Chris said:
>>> 
>>> One of the ideas that Joe Pamer has been discussing is whether the implicit 
>>> promotion from T to T? should be disabled when in an operator context.  
>>> Doing so would fix problems like this, but making the code invalid.
>>> 
>>> 
>>> A change like this would be source-breaking, so if the core team has 
>>> recommendations for how to handle these issues, now is probably the time to 
>>> get it done.
>> 
>> I overlooked your previous message on this.
>> 
>> I’m actually writing up a proposal for this now, and have an implementation 
>> that I’ve done a bit of testing with.
>> 
>> I’m hoping to get the proposal out in the next couple days.
>> 
>> Mark
>> 
>> 
> 
> 
> ___
> 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] Optional comparison operators

2016-07-11 Thread Mark Lacey via swift-evolution

> On Jul 11, 2016, at 4:32 PM, Jacob Bandes-Storch  wrote:
> 
> Great, thanks Mark! I look forward to it.

To be clear, I’m specifically looking at making the change to remove the 
coercion from T to T? for operator arguments.

I agree there might be other things worth looking at regarding operators that 
take optionals, but I’m not currently looking at those issues.

Mark

> 
> On Mon, Jul 11, 2016 at 4:31 PM, Mark Lacey  > wrote:
> Hi Jacob,
> 
>> On Jul 11, 2016, at 4:23 PM, Jacob Bandes-Storch via swift-evolution 
>> > wrote:
>> 
>> Bump for Swift 3.
>> 
>> On Thu, Jul 7, 2016 at 2:37 PM, Jacob Bandes-Storch > > wrote:
>> These operators cause some potential for confusion:
>> 
>> public func <(lhs: T?, rhs: T?) -> Bool
>> public func >(lhs: T?, rhs: T?) -> Bool
>> public func <=(lhs: T?, rhs: T?) -> Bool
>> public func >=(lhs: T?, rhs: T?) -> Bool
>> 
>> 1. The meaning of T? < T? is not immediately obvious (Why is nil < .some(x) 
>> for any x? Personally, my intuition says that Optional should only provide a 
>> partial order, with .none not being ordered w.r.t. .some(x).)
>> 
>> 2. Even if the meaning is understood, it can be surprising when the (T?, T?) 
>> -> Bool version is used instead of (T, T) -> Bool.
>> 
>> Prior discussion:
>> - http://thread.gmane.org/gmane.comp.lang.swift.devel/2089 
>> 
>> - http://thread.gmane.org/gmane.comp.lang.swift.evolution/10095 
>> 
>> - rdar:// <>16966712&22833869
>> - Replies to https://twitter.com/jtbandes/status/646914031433871364 
>> 
>> 
>> In the swift-dev thread from May, Chris said:
>> 
>> One of the ideas that Joe Pamer has been discussing is whether the implicit 
>> promotion from T to T? should be disabled when in an operator context.  
>> Doing so would fix problems like this, but making the code invalid.
>> 
>> 
>> A change like this would be source-breaking, so if the core team has 
>> recommendations for how to handle these issues, now is probably the time to 
>> get it done.
> 
> I overlooked your previous message on this.
> 
> I’m actually writing up a proposal for this now, and have an implementation 
> that I’ve done a bit of testing with.
> 
> I’m hoping to get the proposal out in the next couple days.
> 
> Mark
> 
> 

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


Re: [swift-evolution] Optional comparison operators

2016-07-11 Thread Mark Lacey via swift-evolution
Hi Jacob,

> On Jul 11, 2016, at 4:23 PM, Jacob Bandes-Storch via swift-evolution 
>  wrote:
> 
> Bump for Swift 3.
> 
> On Thu, Jul 7, 2016 at 2:37 PM, Jacob Bandes-Storch  > wrote:
> These operators cause some potential for confusion:
> 
> public func <(lhs: T?, rhs: T?) -> Bool
> public func >(lhs: T?, rhs: T?) -> Bool
> public func <=(lhs: T?, rhs: T?) -> Bool
> public func >=(lhs: T?, rhs: T?) -> Bool
> 
> 1. The meaning of T? < T? is not immediately obvious (Why is nil < .some(x) 
> for any x? Personally, my intuition says that Optional should only provide a 
> partial order, with .none not being ordered w.r.t. .some(x).)
> 
> 2. Even if the meaning is understood, it can be surprising when the (T?, T?) 
> -> Bool version is used instead of (T, T) -> Bool.
> 
> Prior discussion:
> - http://thread.gmane.org/gmane.comp.lang.swift.devel/2089 
> 
> - http://thread.gmane.org/gmane.comp.lang.swift.evolution/10095 
> 
> - rdar://16966712&22833869
> - Replies to https://twitter.com/jtbandes/status/646914031433871364 
> 
> 
> In the swift-dev thread from May, Chris said:
> 
> One of the ideas that Joe Pamer has been discussing is whether the implicit 
> promotion from T to T? should be disabled when in an operator context.  Doing 
> so would fix problems like this, but making the code invalid.
> 
> 
> A change like this would be source-breaking, so if the core team has 
> recommendations for how to handle these issues, now is probably the time to 
> get it done.

I overlooked your previous message on this.

I’m actually writing up a proposal for this now, and have an implementation 
that I’ve done a bit of testing with.

I’m hoping to get the proposal out in the next couple days.

Mark

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


Re: [swift-evolution] [Accepted] SE-0111: Remove type system significance of function argument labels

2016-07-11 Thread Mark Lacey via swift-evolution

> On Jul 10, 2016, at 10:53 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> 
>> On Jul 10, 2016, at 10:30 PM, David Owens II > > wrote:
 
 I wish the core team or the author of the proposal came to this thread and 
 engaged again with the community. 
>>> 
>>> I'm not inclined to spend time engaging with people who couldn't be 
>>> bothered to give feedback during the week-long official review period.
>> 
>> Not all people "couldn’t be bothered” but had life events, such as moving 
>> across states with four kids, that prevented them from being able to engage 
>> during the official review period. 
> 
> I hope your move went smoothly. More generally, there will always be people 
> with good reasons for not being able to participate in the review process, 
> but the procedure is set: one week of formal discussion, followed by a 
> decision by the core team. If a proposal should be re-reviewed or amended, 
> someone should submit (or at least draft) a follow-up proposal; none of the 
> other proposals that have been accepted have been taken up for re-review by 
> the core team based merely on reviews that were submitted after the review 
> period ended (and there have been at least a few whose acceptance was very 
> controversial).
> 
>> 
>> I’ve read through all of the posts that I see in my mailbox regarding this 
>> topic and I’ve yet to see any real answer to the concerns of tooling, 
>> typealias usage, closures, and code readability and maintainability concerns 
>> under this new proposal. This is the closest I’ve seen (from Douglas Gregor 
>> a few days ago):
>> 
>>> The core team’s intent is that one can add cosmetic labels to function 
>>> types, but that those labels are not (cannot be) used at the call site, 
>>> e.g.,
>> 
>> Do you have specific post in mind that addresses the these concerns? Maybe 
>> I’m just missing them, but I really don’t see those addressed and they are 
>> not mentioned in the proposal at all.
>> 
>> Let’s say I want to model a problem regarding some library functions that 
>> work with resizing some image type. Today, if I did that, the tooling would 
>> give me auto-completion for all of the parameter labels and the code is very 
>> legible. 
>> 
>> Note that both `original` and `resized` get auto-completed for us here. This 
>> provides great code clarity and insights. This is also self-documenting code.
>> 
>> However, under this proposal as accepted (as I understand it), we are left 
>> with this:
>> 
>> func doResizeC(image: Image, completed: (Image, Image) -> Void) {
>> let newData = image.data
>> let newSize = image.size
> 
> You can still have labels in the type: `completed: (original: Image, resized: 
> Image)`.
> 
>> 
>> // do some work that's really slow...
>> 
>> completed(image, Image(data: newData, size: newSize))
> 
> This is definitely a problem. I am considering writing a follow-up proposal 
> that would allow for compound naming of values of function type, which would 
> alleviate this problem: `let foo(x:y:) : (Int, Int) -> Void`, which was 
> brought up a couple of times during the review thread. (This was going to be 
> part of the original proposal, but was removed for various reasons.)

In the meantime one option here would be to define a nested function that 
invokes the callback. It results in boilerplate, which is unfortunate, but 
would work:

func doResize
(
  image: Image,
  completed completedParam: (original: Image, resized: Image) -> Void
) {
  func completed(original: Image, resized: Image) {
completedParam(original, resized)
  }

  // do lots of work

  completed(original: image, resized: Image(data: newData, size: newSize))
}

Mark


> 
>> }
>> 
>> -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] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-09 Thread Mark Lacey via swift-evolution

> On Jul 9, 2016, at 10:47 AM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPhone
>> On Jul 9, 2016, at 11:29, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>>> On Jul 9, 2016, at 11:04 AM, Tino Heth <2...@gmx.de> wrote:
>>> 
>>> Second:
>>> Do you really believe there will be positive impact on open-source 
>>> libraries?
>>> My forecast is that closed by default will dramatically increase trivial 
>>> pull request where developers ask for unsealing so that they can do as they 
>>> like…
>> 
>> I think this is a good thing.  It will force a considered answer and a 
>> discussion about whether or not subclassing should be supported by the 
>> library.
> 
> So, let's say I ask you to support subclassing in your library, and you say 
> no. What's to stop from just writing something like this:
>  class YesICan {
>var foo: YouCantInheritThis
>// Duplicate `YouCantInheritThis`'s public API by just passing everything 
> through to `foo`
>  }
> 
> And overloading/extending anything else I need for `YesICan` to, functionally 
> speaking, inherit from `YouCantInheritThis`.

You can certainly do this, but it isn’t equivalent to subclassing for at least 
two reasons.

First, calls within the methods of YouCantInheritThis will not call into the 
methods in YesICan. In other words if YouCantInheritThis has both doWork() and 
okIWill() methods and doWork() calls okIWill(), it will only ever call the 
implementation of okIWill() in YouCantInheritThis, not the implementation in 
YesICan. This actually gets to the heart of what one hopes to achieve through 
final or sealed, specifically avoiding a subclass from inadvertently changing 
the behavior of a superclass and assumptions the superclass is making about 
behavior of calls *within that superclass*.

Second, you cannot pass a YesICan where you can pass a YouCantInheritThis, so 
if you have another library that traffics in YouCantInheritThises, your 
“subclass” cannot be used with it.

Mark

> 
> Yes, I know it'd all be the epitome of annoying boilerplate code, but my 
> point is that if someone wants to subclass something of yours, there's really 
> not much you can do to stop them.
> 
> (Before anyone mentions it, yes, the same trick can be used to get around 
> `final` and `sealed`, but IIRC the motivations there were to enable certain 
> compiler optimizations, not to prohibit "unauthorized" inheritance.)
> 
> - Dave Sweeris
> ___
> 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] Sealed classes by default

2016-06-29 Thread Mark Lacey via swift-evolution

> On Jun 29, 2016, at 3:45 PM, Rod Brown via swift-evolution 
>  wrote:
> 
> From my understanding, "Sealed" or whatever we will call it technically 
> provides no actual optimisations. We cannot assume the class is final because 
> something inside the module may have vended a subclass.

It can enable optimization when compiling with -whole-module-optimization since 
we know all the subclasses defined within the module. For any call site where 
the static type and all subclasses are sealed, we can limit the set of 
potential callees to only the functions defined in those types. Further, if the 
static type at the callsite has no subclasses, we can treat it like final and 
devirtualize the call.

Mark

> 
> The issue that "sealed" as a concept fills is that you stop people from 
> subclassing types that were never specifically designed for subclassing, but 
> allows the module to do some subclassing for its own needs because the 
> developer understands how the class works.
> 
> It also means a developer of the framework can retroactively apply "Final" to 
> the class if they've worked out it actually should be final and will never be 
> subclass. If the concept of Sealed did not exist, then a framework could 
> never finalise a class down the track - users of the framework may have 
> subclassed the type, and now the framework is hamstrung by its previous 
> "openness".
> 
> Should this be the default? In my opinion, yes.  Allowing subclassing to 
> other clients should be explicit. It will tie you down and limit you from 
> developing into the future. Allowing subclasses from other clients is a 
> promise for the life of your product, and cannot be reneged. On classes that 
> are not designed for subclassing, this is ill advised, and on classes you 
> wish to optimise, it's a permanent limitation.
> 
> While I fear the abuse framework vendors will exercise, by allowing clever 
> private hacks, and disallowing obj-c style workarounds, I think the safety 
> and longevity of this approach is far more important.
> 
> +1 to the concept. I agree "sealed" is not foot wording and can be improved.
> 
> - Rod Brown
> 
>> On 30 Jun. 2016, at 5:05 am, Michael Peternell via swift-evolution 
>>  wrote:
>> 
>> I'm still unhappy about this "sealed by default" proposal. That really looks 
>> like premature optimization to me. Instead there should be some `sealed` 
>> keyword. Maybe it should be called `applepublic` :-p Everyone will 
>> understand!
>> 
>> `sealed` classes should be a special optimization used by optimizing 
>> developers who ask for it. Don't make it an unwanted and un-asked-for 
>> default optimization. The people who care for optimization much will learn 
>> about `sealed` and be able to apply the concept in both cases. The people 
>> who don't care about performance will just be disappointed by the 
>> "implicitly sealed" behavior. And with this proposal, when I read `unsealed` 
>> I can never know: "did this developer intend me to be able to subclass this 
>> class? or did he just not want to restrict me unnecessarily?" The 
>> documenting aspect of `unsealed` is so small.
>> 
>> And `sealed` is just an optimization; IMHO the magic of static dispatch lies 
>> in final classes or final methods. Sealing everything by default just marks 
>> many classes and methods as implicitly final (because it can be proven that 
>> they are not subclassed). I just don't think that all these theoretical 
>> performance improvements are really worth the trouble in practice.
>> 
>> -Michael
>> 
>>> Am 29.06.2016 um 20:39 schrieb Vladimir.S via swift-evolution 
>>> :
>>> 
>>> How about `public(extensible)` ?
>>> 
>>> On 29.06.2016 21:32, John McCall via swift-evolution wrote:
> On Jun 29, 2016, at 11:16 AM, Michael Peternell via swift-evolution 
>  wrote:
> Do you mean `public(unsealed)`? Because `internal(unsealed)` doesn't 
> really make sense. `internal` declarations are always sealed.
 
 Right.
 
 If "sealed" is the default behavior for public classes and methods — and I 
 don't think the modifier is worth adding unless it's the default — then we 
 need a way of "unsealing" classes and methods that's fairly pithy.  I 
 don't think a parenthesized spelling is good enough for that.  And we 
 should try to make the positive form ("can be overridden") shorter than 
 the negative ("cannot be overridden"), because the latter will not usually 
 be written.
 
 To me, the ideal spelling would be usable in place of "public".  If it 
 does have to be stacked with "public", then I think it ought to be pretty 
 short.
 
 "communal"? :)
 
 "open" doesn't carry quite the right meaning, and it would need to be 
 paired with "public", I think.
 
 John.
 
 
> 
> -Michael
> 
>> Am 29.06.2016 um 20:11 

Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Mark Lacey via swift-evolution

> On Jun 28, 2016, at 4:01 PM, Michael Peternell via swift-evolution 
>  wrote:
> 
> 
>> Am 29.06.2016 um 00:32 schrieb John McCall :
>> 
>> The decision to make class methods polymorphic by default was always 
>> premised on being able to undo that in obvious cases where methods are never 
>> overridden.  Making a class public so that clients can use it shouldn't 
>> cause significant performance degradations just because you forgot to also 
>> write "final".
>> 
>> John.
> 
> I do care about performance. For this reason I don't want a fully dynamic 
> language. I disagree about the "significant performance degradations just 
> because you forgot to also write `final`". I mentioned "performance" in my 
> original post only because it would be the only convincing argument - if 
> there were indeed superior performance when using `final`.

There is, and it can be very substantial. Knowing a method is final enables the 
optimizer to devirtualize, and devirtualization enables type-based 
specialization for generic functions, as well as inlining (each of which enable 
further devirtualization, etc., etc.). Devirtualization also makes it possible 
to do specialization of function signatures, which can remove ARC overhead. 
When that kicks in it can be a substantial win by itself. It can also improve 
the results of interprocedural analysis, which can provide further benefit (and 
which we’ll likely rely on more for performance improvement in the future). For 
example we are currently able to stack-allocate some data that was heap 
allocated in Swift 2.x because we do escape analysis, which is only possible 
when you know all the potential callees at a call site.

I recall seeing performance differences of 40x (yes, 40x, not 40%) on 
small-to-moderately sized benchmarks that use generics due to whole module 
optimization being able to infer final for internal classes. Part of that 
performance difference can be accounted for by known issues with the 
performance of generic code, but even if we substantially improve that I 
believe we would still have cases where lack of devirtualizing, inlining, and 
specialization would result in substantially slower code. 

Mark

> 
> Of course, dynamic dispatch is much slower than static dispatch. But 
> optimized code does not spend much time dispatching. If a method takes 3 
> seconds to complete, and from that 2 seconds are used for dynamically 
> dispatching method calls, then I would say that it has not been optimized for 
> performance yet. How would such a function look like? The function being 
> dynamically dispatched should probably not be statically dispatched but 
> inlined completely. And for the rare case that the dispatch type really makes 
> all the difference, it's always possible to `final`ize (or `private`ize) some 
> of the used methods.
> 
> -Michael
> 
> ___
> 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] Sealed classes by default

2016-06-28 Thread Mark Lacey via swift-evolution

> On Jun 28, 2016, at 7:55 AM, Sean Heber <s...@fifthace.com> wrote:
> 
>> On Jun 28, 2016, at 9:52 AM, Mark Lacey via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>>> 
>>> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> -1 for the fact that if all devs can write working code, fewer can do it in 
>>> a clear structured fashion that is well designed for extensibility.
>> 
>> This sounds more like an argument for having sealed classes than not. As the 
>> proposal points out in the motivation, if the base class is not designed 
>> with subclassing in mind then overriding methods can result in unintended 
>> behavior (e.g. crashing, or other bugs).
> 
> But I think the counter argument is, what if you need to fix or workaround 
> unintended behavior of the class you’re trying to use?

Sure, I understand that, and I don’t mean to trivialize that concern. I’m just 
pointing out that “code…that is [not] well designed for extensibility”, might 
not  work very well if you start using extension points that weren’t well 
thought through.

If you are designing for extensibility you’ll be carefully thinking about what 
should and should not be final both within and outside of your module. Not 
doing so can result in bugs. This proposal introduces the ability to allow 
extension within the module but restrict it outside the module, and defaults to 
not allowing extension beyond the module.

You can argue both ways which default would be better, and I suspect people who 
mostly write libraries might opt for sealed-by-default, and people who mostly 
consume libraries might opt for open-by-default. My point is that 
open-by-default isn’t “better” because it allows you to potentially work around 
a problem in a base class, because by working around that problem by overriding 
a method that wasn’t designed to be overridden you don’t know how many other 
new problems you might be introducing (now or in the future if the 
implementation of the base class changes).

Mark

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


Re: [swift-evolution] [Proposal] Sealed classes by default

2016-06-28 Thread Mark Lacey via swift-evolution

> On Jun 27, 2016, at 9:10 PM, L. Mihalkovic via swift-evolution 
>  wrote:
> 
> -1 for the fact that if all devs can write working code, fewer can do it in a 
> clear structured fashion that is well designed for extensibility.

This sounds more like an argument for having sealed classes than not. As the 
proposal points out in the motivation, if the base class is not designed with 
subclassing in mind then overriding methods can result in unintended behavior 
(e.g. crashing, or other bugs).

Mark

> A couple months ago I even ran into difficulties when trying to extend 
> AlamoFire because some things had not been designed as cleanly as they could 
> have been to make extending it easy. So if the default is now that everything 
> becomes non-extensible but default, it is going to complicate (and partially 
> defeat the purpose of) reusing libraries.
> Regards
> (From mobile)
> 
> On Jun 28, 2016, at 2:11 AM, Michael Ilseman via swift-evolution 
> > wrote:
> 
>> I was also referring to how we present Objective-C classes in Swift. That 
>> is, if a Swift user tries to subclass an Objective-C-imported class, then 
>> we’d take into account sealed-ness in order to issue an error/warning, etc. 
>> If you are also proposing a Clang attribute for this, e.g. ‘swift_sealed’, 
>> to import as sealed (meaning issue an error if Swift users try to subclass 
>> it), then that should be spelled out as well. I don’t have an opinion on 
>> whether this is a good idea yet, just pointing out some more directions to 
>> explore. In general it feels like your proposal could use more fleshing out.
>> 
>> 
>>> On Jun 27, 2016, at 5:08 PM, Javier Soto >> > wrote:
>>> 
>>> That is a very good point, it should be explicitly mentioned in the 
>>> proposal. My thought would be that since in the Obj-C runtime it's not 
>>> possible to guarantee a class won't have subclasses, or that a method is 
>>> not overriden, Obj-C classes would be imported as open. 
>>> 
>>> On the Swift side, I think today it's possible to declare a "public final 
>>> @objc class", but you can still inherit from it from Obj-C, right? My hunch 
>>> would be that that should be disallowed, but perhaps there's a reason why 
>>> it's allowed today. 
>>> On Mon, Jun 27, 2016 at 4:25 PM Michael Ilseman >> > wrote:
>>> Could you elaborate on how we should treat classes imported from 
>>> Objective-C or CF-style C? That is, do we always annotate them as being 
>>> “open” because those paradigms permit subclassing anywhere, or do you 
>>> propose some kind of recommended “sealed” audit, or what?
>>> 
>>> 
 On Jun 27, 2016, at 3:40 PM, Javier Soto via swift-evolution 
 > wrote:
 
>>> 
 Hello!
 
 I sent this as a PR  on 
 the swift-evolution repo, but we never had any discussion about it 
 on-list, besides a long time ago 
 . 
 Here's the first draft of the proposal:
 
 
 Sealed classes by default
 
  
 Introduction
 
 Introduce a new sealed class modifier that makes classes and methods final 
 outside of the module they're declared in, but non-final within the module.
 
  
 Motivation
 
 It is not uncommon to have a need for a reference type without needing 
 inheritance. Classes must be intentionally designed to be subclassable, 
 carefully deciding which methods are the override entry-points such that 
 the the behavior remains correct and subclasses respect the Liskov 
 substitution principle 
 .
 Defaulting to non-final allows the author of a class to accidentally leave 
 the visible methods open for overrides, even if they didn't carefully 
 consider this possibility.
 Requiring that the author of a class mark a class as open is akin to 
 requiring symbols to be explicitly public: it ensures that a conscious 
 decision is made regarding whether the ability to subclass a class is part 
 of the API.
  
 Proposed
  solution
 
 New sealed (actual name pending bike-shedding) class modifier for classes 
 and methods which marks them as only overridable within 

Re: [swift-evolution] [Pitch] "unavailable" members shouldn't need an impl

2016-06-10 Thread Mark Lacey via swift-evolution

> On Jun 10, 2016, at 2:32 PM, Leonardo Pessoa via swift-evolution 
>  wrote:
> 
> I've seen around the Swift source code some uses of a function named
> something like NSUnimplemented(). I'm not sure this is available only
> inside the Swift source or if we could call it as well (I'm not in
> front of a Swift compiler right now so I cannot test).

You might be thinking of Builtin.unreachable(). I recently replaced the bodies 
of all the stdlib functions that are completely unavailable with calls to 
Builtin.unreachable(), which generates a trap instruction (as opposed to having 
bodies with calls to fatalError that take static strings, which generate more 
code/data).

> The idea of being able to drop the body of the function is interesting
> but I keep thinking of the overhead of the compiler to check for every
> function if it can drop the requirement for a body. Perhaps keeping
> the body is well suited here.

Personally I think it would be nice if you could omit the body of any function 
(through some special syntax) with the intent that you’d get a warning for 
these when compiling and that they would trap if ever called. It can be handy 
to be able to do that while prototyping, e.g. as you’re trying to figure out 
the design of the types you want to implement, etc. I don’t consider this 
critical though, as it’s usually not too hard to write a placeholder body that 
constructs and returns some kind of dummy return value.

Mark

> 
> On 10 June 2016 at 18:26, Erica Sadun via swift-evolution
>  wrote:
>> On Jun 10, 2016, at 3:22 PM, Austin Zheng via swift-evolution
>>  wrote:
>> 
>> So, instead of:
>> 
>> @available(*, unavailable, renamed:"someNewAPI()")
>> public func someOldAPI() -> Int { fatalError() }
>> 
>> You can just have:
>> 
>> @available(*, unavailable, renamed:"someNewAPI()")
>> public func someOldAPI() -> Int
>> 
>> The intent is, in my opinion, clearer for the latter and it feels less
>> kludgy.
>> 
>> 
>> You ask, we answer. I'd much prefer spelling out { fatalError("unavailable
>> API") }.
>> It makes the code clearer to read, to maintain, it produces debug and
>> runtime errors. etc. I think
>> this is an example where concision is overrated.
>> 
>> -- E
>> 
>> 
>> 
>> ___
>> 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] [Pitch] Allow explicit specialization of generic functions

2016-05-26 Thread Mark Lacey via swift-evolution

> On May 25, 2016, at 11:37 PM, David Hart  wrote:
> 
> The former. This proposal is simply to make certain scenarios which require 
> to be explicit to be more elegant and more in line with generic types.
> 
> Moreover, what you suggest might be dangerous. Imagine this code:
> 
> func foo() -> (T, U) { ... }
> let a = foo()
> 
> I just did a typo on Foobarr and Foobarr does not exist. So the compiler has 
> to guess that I meant an inferred generic type, which might not be what I 
> want. And I don't think that the compiler should require us to remember the 
> actual name of the generic types.

I probably wasn’t clear enough here, but what I meant was something like:
  func foo(x: U) -> (T, U) { … }

  let a = foo(v)   // the second type was unspecified, but can be 
inferred by the argument ‘v'

Ignore the specific syntax for the unspecified type here. Would your 
expectation be that something like this work as well, or does one need to 
specify all-or-none when it comes to the type parameters?

If the former, what is the proposed syntax for what goes in the positions of 
the types that are unspecified?

Mark

> 
> On 26 May 2016, at 03:38, Mark Lacey  > wrote:
> 
>> 
>>> On May 25, 2016, at 4:17 PM, David Hart via swift-evolution 
>>> > wrote:
>>> 
>>> Hello,
>>> 
>>> This is a new pitch to allow explicitly specializing generic functions. 
>>> Notice that potential ambiguity with initialisers and how I’m currently 
>>> trying to avoid it. Please let me know what you think!
>> 
>> Hi David,
>> 
>> I’m wondering if the only motivation here is to be more explicit about the 
>> types involved so you can avoid having to rely on type inference and the 
>> code is more clear, or if you also have the expectation that we’ll generate 
>> a type-specialized version of the body of the function in question which you 
>> would expect to be more efficient than the fully generic version?
>> 
>> Do you imagine this supporting a scenario where only some of the type 
>> parameters are given explicitly and others are inferred, or would this only 
>> be supported in the case where all type parameters were given explicitly?
>> 
>> What if some of those type parameters were themselves generics? For example:
>>   func callee(x: T, y: U) { … }
>>   func caller(x: T) {
>> let f = bar // supported
>> f(3, x)
>>   }
>> 
>> Mark
>> 
>>> 
>>> David
>>> 
>>> Allow explicit specialization of generic functions
>>> 
>>> Proposal: SE- 
>>> 
>>> Author: David Hart , Douglas Gregor 
>>> 
>>> Status: TBD
>>> Review manager: TBD
>>>  
>>> Introduction
>>> 
>>> This proposal allows bypassing the type inference engine and explicitly 
>>> specializing type arguments of generic functions. 
>>> 
>>>  
>>> Motivation
>>> 
>>> In Swift, generic type parameters are inferred by the argument or return 
>>> value types as follows:
>>> 
>>> func foo(t: T) { ... }
>>> 
>>> foo(5) // infers T = Int
>>> There exists certain scenarios when a programmer wants to explicitly 
>>> specialize a generic function. Swift does not allow it, so we resort to 
>>> giving hints to the inference engine:
>>> 
>>> let f1 = foo as ((Int) -> Void)
>>> let f2: (Int) -> Void = foo
>>> let f3 = foo // error: Cannot explicitly specialize a generic function
>>> 
>>> func bar() -> T { ... }
>>> 
>>> let b1 = bar() as Int
>>> let b2: Int = bar()
>>> let b3 = bar() // error: Cannot explicitly specialize a generic 
>>> function
>>> This behaviour is not very consistent with generic types which allow 
>>> specialization:
>>> 
>>> let array: Array = Array(arrayLiteral: 1, 2, 3)
>>> Therefore, this proposal seeks to make the above errors valid 
>>> specializations:
>>> 
>>> let f3 = foo // explicitly specialized to (Int) -> Void 
>>> let b3 = bar() // explicitly specialized to () -> Int 
>>> An ambiguous scenario arrises when we wish to specialize initializer 
>>> functions:
>>> 
>>> struct Foo {
>>> let storage: T
>>> 
>>> init(_ value: U) {
>>> storage = T(rawValue: value.description)!
>>> }
>>> }
>>> 
>>> enum Bar: String, CustomStringConvertible {
>>> case foobar = "foo"
>>> 
>>> var description: String {
>>> return self.rawValue
>>> }
>>> }
>>> 
>>> let a = Foo(Bar.foobar)
>>> Does this specialization specialize the struct's or the initializer's 
>>> generic type? The proposal solves this ambiguity by requiring initializer 
>>> generic type specialization to use the init syntax:
>>> 

Re: [swift-evolution] [Pitch] Allow explicit specialization of generic functions

2016-05-25 Thread Mark Lacey via swift-evolution

> On May 25, 2016, at 4:17 PM, David Hart via swift-evolution 
>  wrote:
> 
> Hello,
> 
> This is a new pitch to allow explicitly specializing generic functions. 
> Notice that potential ambiguity with initialisers and how I’m currently 
> trying to avoid it. Please let me know what you think!

Hi David,

I’m wondering if the only motivation here is to be more explicit about the 
types involved so you can avoid having to rely on type inference and the code 
is more clear, or if you also have the expectation that we’ll generate a 
type-specialized version of the body of the function in question which you 
would expect to be more efficient than the fully generic version?

Do you imagine this supporting a scenario where only some of the type 
parameters are given explicitly and others are inferred, or would this only be 
supported in the case where all type parameters were given explicitly?

What if some of those type parameters were themselves generics? For example:
  func callee(x: T, y: U) { … }
  func caller(x: T) {
let f = bar // supported
f(3, x)
  }

Mark

> 
> David
> 
> Allow explicit specialization of generic functions
> 
> Proposal: SE- 
> 
> Author: David Hart , Douglas Gregor 
> 
> Status: TBD
> Review manager: TBD
>  
> Introduction
> 
> This proposal allows bypassing the type inference engine and explicitly 
> specializing type arguments of generic functions. 
> 
>  
> Motivation
> 
> In Swift, generic type parameters are inferred by the argument or return 
> value types as follows:
> 
> func foo(t: T) { ... }
> 
> foo(5) // infers T = Int
> There exists certain scenarios when a programmer wants to explicitly 
> specialize a generic function. Swift does not allow it, so we resort to 
> giving hints to the inference engine:
> 
> let f1 = foo as ((Int) -> Void)
> let f2: (Int) -> Void = foo
> let f3 = foo // error: Cannot explicitly specialize a generic function
> 
> func bar() -> T { ... }
> 
> let b1 = bar() as Int
> let b2: Int = bar()
> let b3 = bar() // error: Cannot explicitly specialize a generic function
> This behaviour is not very consistent with generic types which allow 
> specialization:
> 
> let array: Array = Array(arrayLiteral: 1, 2, 3)
> Therefore, this proposal seeks to make the above errors valid specializations:
> 
> let f3 = foo // explicitly specialized to (Int) -> Void 
> let b3 = bar() // explicitly specialized to () -> Int 
> An ambiguous scenario arrises when we wish to specialize initializer 
> functions:
> 
> struct Foo {
> let storage: T
> 
> init(_ value: U) {
> storage = T(rawValue: value.description)!
> }
> }
> 
> enum Bar: String, CustomStringConvertible {
> case foobar = "foo"
> 
> var description: String {
> return self.rawValue
> }
> }
> 
> let a = Foo(Bar.foobar)
> Does this specialization specialize the struct's or the initializer's generic 
> type? The proposal solves this ambiguity by requiring initializer generic 
> type specialization to use the init syntax:
> 
> let a = Foo.init(Bar.foobar)
>  
> Detailed
>  Design
> 
> Function calls are fairly straight forward and have their grammar modified as 
> follows:
> 
> function-call-expression → postfix-expression­ generic-argument-clause­opt 
> parenthesized-expression
> 
> function-call-expression → postfix-expression generic-argument-clause­opt 
> ­parenthesized-expression­opt ­trailing-closure­
> 
> To allow initializers to be called with explicit specialization, we need to 
> use the Initializer Expression. Its grammar is modified to:
> 
> initializer-expression → postfix-expression­ . ­init­ 
> generic-argument-clause­opt
> 
> initializer-expression → postfix-expression­ . ­init­ 
> generic-argument-clause­opt ( ­argument-names­ )
> 
>  
> Impact
>  on Existing Code
> 
> This proposal is purely additive and will have no impact on existing code.
> 
>  
> Alternatives
>  Considered
> 
> Not adopting this proposal for Swift.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0045: Add scan, prefix(while:), drop(while:), and iterate to the stdlib

2016-04-28 Thread Mark Lacey via swift-evolution
I haven’t read through the complete proposal in detail, but regarding the 
‘scan’ operation I would like to point out that the definition given in the 
example matches the semantics of what is usually called ‘prescan' or 'exclusive 
scan', whereas ‘scan’ (aka ‘inclusive scan’ or ‘prefix sum’) would not include 
the identity element, and each position of the result would include applying 
the operator to the elements up to and including the element in the same 
position of the source array, e.g.:

  (1..<6).scan(combine: +) // [1, 3, 6, 10, 15, 21]

Sources:
  https://www.cs.cmu.edu/~guyb/papers/Ble93.pdf
  https://en.wikipedia.org/wiki/Prefix_sum

Mark


> On Apr 28, 2016, at 11:11 AM, Chris Lattner  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0045: Add scan, prefix(while:), drop(while:), and iterate 
> to the stdlib" begins now and runs through May 3. The proposal is available 
> here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0045-scan-takewhile-dropwhile.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 the review 
> manager.
> 
> 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 you used other languages or libraries with a similar 
> feature, how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution-announce mailing list
> swift-evolution-annou...@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution-announce

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