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

2017-06-07 Thread Jonathan Hull via swift-evolution
Also, I want to repeat what I said on the other thread.  We should revert to 
Swift 3 behavior for this, and then take the time to design the behavior we 
really want (either for 4.1 or 5).  Anything else will cause us to break 
people’s code twice…

Thanks,
Jon

> On Jun 7, 2017, at 11:50 AM, Gwendal Roué via swift-evolution 
>  wrote:
> 
> 
>> Le 7 juin 2017 à 20:33, Gwendal Roué > > a écrit :
>> 
>> For example, take those three functions:
>> 
>>  func f(_ closure:(Int, Int) -> ())
>>  func g(_ closure:((Int, Int)) -> ())
>>  func h(_ closure:((a: Int, b: Int)) -> ())
>> 
>> If one can always write (as in Swift 3):
>> 
>>  f { (a, b) in ... }
>>  g { (a, b) in ... }
>>  c { (a, b) in ... }
>> 
>> Then one can easily deal with a badly fit closure signature.
>> 
>> This is most examplified by dictionaries. They always expose (key: Key, 
>> value: Value) tuples (their Element type). Problem is that 'key' and 'value' 
>> are identifiers that only matter for dictionaries, not for dictionary users. 
>> It's very important for dictionary users to forget about tuples, and the 
>> `key` and `value` words:
>> 
>>  // No pollution
>>  dictionary.map { (name, score) in ... }
> 
> It looks like some people in this mailing list are horrified by this 
> "request" (not a feature request, but a request that Swift 3 behavior is 
> restored, actually).
> 
> What could be the reasons for such a bad reaction?
> 
> 1: measurable runtime overhead (slower programs in some cases, without any 
> obvious way for the developper to notice where is the extra cost)
> 2: measurable compiler overhead (slower compilation)
> 3: implementation complexity (slower swift progress, technical debt, etc.)
> 4: other?
> 
> I understand 1. We are all fascinated by C++ and Rust "zero-overhead". If 
> this is the main concern of the community, then we may focus the discussion 
> of that very precise topic.
> 
> I can live with 2 (just a personal subjective preference)
> 
> About 3: I can not tell because I lack the necessary skills.
> 
> 4: enlighten us!
> 
> Gwendal
> 
> ___
> 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-07 Thread Jonathan Hull via swift-evolution

> On Jun 7, 2017, at 11:33 AM, Gwendal Roué via swift-evolution 
>  wrote:
> 
> So far, the answer to the ergonomics regression reports have been much too 
> often negative. I wish ergonomics had better support in the community. Very 
> few regular developers talk here, unfortunately.

Yes, I unfortunately agree.  The best term I have heard to describe this list 
is “Combative”.

I wish actual user experience / human factors was a greater consideration here, 
and that often requires little touches that are immediately dismissed from this 
list as being not-significant/important enough.  But those little touches add 
up to make the overall experience… and our experience has been suffering as a 
result.

I don’t mean to offend, and I feel like I am learning a lot from everyone here 
(I am an experienced mac/iOS developer, but I mainly work as a designer and 
teacher).  I just really wish the list was more open to a range of voices. 

Thanks,
Jon

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


Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Stephen Celis via swift-evolution
:D

Great example for what I was trying to say. We can compose such a thing with 
existing code and not require an overload per.

> On Jun 8, 2017, at 12:34 AM, Susan Cheng  wrote:
> 
> this work,
> 
> prefix operator *
> 
> prefix func *(keyPath: KeyPath) -> (Root) -> Value {
> return { $0[keyPath: keyPath] }
> }
> 
> ["Hello, World"].map(*\String.count)// [12]
> 
> 
> 2017-06-08 12:19 GMT+08:00 Paul Cantrell via swift-evolution 
> :
> It should be possible to achieve Ruby-like generality in Swift with a 
> protocol for “thing that can converted to a transform function.” That 
> wouldn’t need a special & operator.
> 
> Here’s a sketch. This sketch doesn’t compile — maybe not enough of Swift 4 is 
> there yet for it to work, or maybe I am missing something obvious and need to 
> go to sleep now — but it’s close enough to suggest the approach:
> 
> public protocol TransformConvertible {  // or whatever you want to call it
>   associatedtype From
>   associatedtype To
>   
>   var transform: (From) -> To { get }
> }
> 
> extension KeyPath: TransformConvertible {
>   public typealias From = Root
>   public typealias To = Value
>   
>   public var transform: (Root) -> Value {
> return { $0[keypath: self] }
>   }
> }
> 
> extension Sequence {
>   public func map(_ transformSource: U) -> [T]
>where U: TransformConvertible,
>  U.From == Element,
>  U.To == T {
> return map(transformSource.transform)
>   }
> }
> 
> This seems a bit more ambitious, perhaps not suitable for this round of Swift 
> evolution work. But I throw it out there at least to show that supporting 
> people.map(\.firstName) today would not preclude a generic keypath → function 
> mechanism in the future:
> 
>   • A flavor of map that accepts a keypath today could be generalized to 
> accept TransformConvertible in the future without breaking existing code.
>   • When calling a function that doesn’t know how to work with 
> TransformConvertible, you could use (Foo.bar).transform, no special operator 
> needed.
> 
> Cheers,
> 
> Paul
> 
> P.S. Largely irrelevant Ruby aside: Ruby’s & is not a free-floating operator, 
> but part of the method invocation syntax indicating that the following arg 
> should be treated as a block. Ruby calls a to_proc method on whatever is in 
> that position. Symbol implements to_proc by returning a lambda that calls the 
> method named by the symbol on the lambda’s first arg. Very much the 
> duck-typed version of TransformConvertible above.
> 
> 
>> On Jun 7, 2017, at 10:21 PM, Stephen Celis via swift-evolution 
>>  wrote:
>> 
>> -1
>> 
>> A -1 from me may be surprising. I'm excited about key path composition and 
>> generic solutions, e.g. this experiment with lenses: 
>> https://twitter.com/stephencelis/status/863916921577758721
>> 
>> But I'd prefer a reusable solution for converting key paths into functions.
>> 
>> Heaven help me for this Rubyism, but a prefix "&" operator (or, maybe better 
>> yet, some implicit mechanism) could convert a key-path to a function that 
>> passes a root value to a key path...
>> 
>>   people.map(&\.firstName)
>> 
>> This way any function that takes a transformation from "whole" to "part" 
>> could take a key path. Requiring an overload per instance is less flexible.
>> 
>> Stephen
>> 
>>> On Jun 7, 2017, at 10:58 PM, Tony Allevato via swift-evolution 
>>>  wrote:
>>> 
>>> +1, I really like this. It would also align nicely with the method type 
>>> flattening in SE-0042 (once it gets implemented), because passing keypaths 
>>> (i.e., unbound property references) and unbound parameterless method 
>>> references to map/flatMap would look nearly the same:
>>> 
>>> ```
>>> struct Person {
>>>  let firstName: String
>>>  let lastName: String
>>>  func fullName() -> String { return "\(firstName) \(lastName)" }
>>> }
>>> 
>>> let people: [Person]
>>> let firstNames = people.map(\.firstName)
>>> let fullNames = people.map(Person.fullName)  // because after SE-0042, this 
>>> will be (Person) -> String, not (Person) -> () -> String
>>> ```
>>> 
>>> Especially if there's a move in the future to also use \. to denote unbound 
>>> methods references, which was discussed during the keypath reviews. (Even 
>>> with that, I believe it would be more work though to get rid of the 
>>> explicit type name in the function case.)
>>> 
>>> 
>>> On Wed, Jun 7, 2017 at 6:11 PM Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> +1. Would think that all variants should exist on Optional too unless it 
>>> would be harmful.
>>> On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution 
>>>  wrote:
>>> This is a great idea, and ought to be easy enough to bring forward!  +1 
>>> from me!
>>> 
>>> -Michael
>>> 
 On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution 
  wrote:
 
 💯
 
> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swif

Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Susan Cheng via swift-evolution
this work,


prefix operator *


prefix func *(keyPath: KeyPath) -> (Root) -> Value
{

return { $0[keyPath: keyPath] }

}


["Hello, World"].map(*\String.count)// [12]


2017-06-08 12:19 GMT+08:00 Paul Cantrell via swift-evolution <
swift-evolution@swift.org>:

> It should be possible to achieve Ruby-like generality in Swift with a
> protocol for “thing that can converted to a transform function.” That
> wouldn’t need a special & operator.
>
> Here’s a sketch. This sketch doesn’t compile — maybe not enough of Swift 4
> is there yet for it to work, or maybe I am missing something obvious and
> need to go to sleep now — but it’s close enough to suggest the approach:
>
> public protocol TransformConvertible {  // or whatever you want to
> call it
>   associatedtype From
>   associatedtype To
>
>
>   var transform: (From) -> To { get }
> }
>
> extension KeyPath: TransformConvertible {
>   public typealias From = Root
>   public typealias To = Value
>
>
>   public var transform: (Root) -> Value {
> return { $0[keypath: self] }
>   }
> }
>
> extension Sequence {
>   public func map(_ transformSource: U) -> [T]
>where U: TransformConvertible,
>  U.From == Element,
>  U.To == T {
> return map(transformSource.transform)
>   }
> }
>
> This seems a bit more ambitious, perhaps not suitable for this round of
> Swift evolution work. But I throw it out there at least to show that
> supporting people.map(\.firstName) today *would not preclude* a generic
> keypath → function mechanism in the future:
>
>
>- A flavor of map that accepts a keypath today could be generalized to
>accept TransformConvertible in the future without breaking existing code.
>- When calling a function that doesn’t know how to work
>with TransformConvertible, you could use (Foo.bar).transform, no special
>operator needed.
>
>
> Cheers,
>
> Paul
>
> P.S. Largely irrelevant Ruby aside: Ruby’s & is not a free-floating
> operator, but part of the method invocation syntax indicating that the
> following arg should be treated as a block. Ruby calls a to_proc method on
> whatever is in that position. Symbol implements to_proc by returning a
> lambda that calls the method named by the symbol on the lambda’s first arg.
> Very much the duck-typed version of TransformConvertible above.
>
>
> On Jun 7, 2017, at 10:21 PM, Stephen Celis via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> -1
>
> A -1 from me may be surprising. I'm excited about key path composition and
> generic solutions, e.g. this experiment with lenses: https://twitter.com/
> stephencelis/status/863916921577758721
>
> But I'd prefer a reusable solution for converting key paths into functions.
>
> Heaven help me for this Rubyism, but a prefix "&" operator (or, maybe
> better yet, some implicit mechanism) could convert a key-path to a function
> that passes a root value to a key path...
>
>   people.map(&\.firstName)
>
> This way any function that takes a transformation from "whole" to "part"
> could take a key path. Requiring an overload per instance is less flexible.
>
> Stephen
>
> On Jun 7, 2017, at 10:58 PM, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> +1, I really like this. It would also align nicely with the method type
> flattening in SE-0042 (once it gets implemented), because passing keypaths
> (i.e., unbound property references) and unbound parameterless method
> references to map/flatMap would look nearly the same:
>
> ```
> struct Person {
>  let firstName: String
>  let lastName: String
>  func fullName() -> String { return "\(firstName) \(lastName)" }
> }
>
> let people: [Person]
> let firstNames = people.map(\.firstName)
> let fullNames = people.map(Person.fullName)  // because after SE-0042,
> this will be (Person) -> String, not (Person) -> () -> String
> ```
>
> Especially if there's a move in the future to also use \. to denote
> unbound methods references, which was discussed during the keypath reviews.
> (Even with that, I believe it would be more work though to get rid of the
> explicit type name in the function case.)
>
>
> On Wed, Jun 7, 2017 at 6:11 PM Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
> +1. Would think that all variants should exist on Optional too unless it
> would be harmful.
> On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution <
> swift-evolution@swift.org> wrote:
> This is a great idea, and ought to be easy enough to bring forward!  +1
> from me!
>
> -Michael
>
> On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> 💯
>
> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> The new smart key path feature is really lovely, and feels like a great
> addition to Swift.
>
> It seems like it might be straightforward to add overloads of `m

Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Paul Cantrell via swift-evolution
It should be possible to achieve Ruby-like generality in Swift with a protocol 
for “thing that can converted to a transform function.” That wouldn’t need a 
special & operator.

Here’s a sketch. This sketch doesn’t compile — maybe not enough of Swift 4 is 
there yet for it to work, or maybe I am missing something obvious and need to 
go to sleep now — but it’s close enough to suggest the approach:

public protocol TransformConvertible {  // or whatever you want to call it
  associatedtype From
  associatedtype To
  
  var transform: (From) -> To { get }
}

extension KeyPath: TransformConvertible {
  public typealias From = Root
  public typealias To = Value
  
  public var transform: (Root) -> Value {
return { $0[keypath: self] }
  }
}

extension Sequence {
  public func map(_ transformSource: U) -> [T]
   where U: TransformConvertible,
 U.From == Element,
 U.To == T {
return map(transformSource.transform)
  }
}

This seems a bit more ambitious, perhaps not suitable for this round of Swift 
evolution work. But I throw it out there at least to show that supporting 
people.map(\.firstName) today would not preclude a generic keypath → function 
mechanism in the future:

A flavor of map that accepts a keypath today could be generalized to accept 
TransformConvertible in the future without breaking existing code.
When calling a function that doesn’t know how to work with 
TransformConvertible, you could use (Foo.bar).transform, no special operator 
needed.

Cheers,

Paul

P.S. Largely irrelevant Ruby aside: Ruby’s & is not a free-floating operator, 
but part of the method invocation syntax indicating that the following arg 
should be treated as a block. Ruby calls a to_proc method on whatever is in 
that position. Symbol implements to_proc by returning a lambda that calls the 
method named by the symbol on the lambda’s first arg. Very much the duck-typed 
version of TransformConvertible above.


> On Jun 7, 2017, at 10:21 PM, Stephen Celis via swift-evolution 
>  wrote:
> 
> -1
> 
> A -1 from me may be surprising. I'm excited about key path composition and 
> generic solutions, e.g. this experiment with lenses: 
> https://twitter.com/stephencelis/status/863916921577758721
> 
> But I'd prefer a reusable solution for converting key paths into functions.
> 
> Heaven help me for this Rubyism, but a prefix "&" operator (or, maybe better 
> yet, some implicit mechanism) could convert a key-path to a function that 
> passes a root value to a key path...
> 
>   people.map(&\.firstName)
> 
> This way any function that takes a transformation from "whole" to "part" 
> could take a key path. Requiring an overload per instance is less flexible.
> 
> Stephen
> 
>> On Jun 7, 2017, at 10:58 PM, Tony Allevato via swift-evolution 
>>  wrote:
>> 
>> +1, I really like this. It would also align nicely with the method type 
>> flattening in SE-0042 (once it gets implemented), because passing keypaths 
>> (i.e., unbound property references) and unbound parameterless method 
>> references to map/flatMap would look nearly the same:
>> 
>> ```
>> struct Person {
>>  let firstName: String
>>  let lastName: String
>>  func fullName() -> String { return "\(firstName) \(lastName)" }
>> }
>> 
>> let people: [Person]
>> let firstNames = people.map(\.firstName)
>> let fullNames = people.map(Person.fullName)  // because after SE-0042, this 
>> will be (Person) -> String, not (Person) -> () -> String
>> ```
>> 
>> Especially if there's a move in the future to also use \. to denote unbound 
>> methods references, which was discussed during the keypath reviews. (Even 
>> with that, I believe it would be more work though to get rid of the explicit 
>> type name in the function case.)
>> 
>> 
>> On Wed, Jun 7, 2017 at 6:11 PM Xiaodi Wu via swift-evolution 
>>  wrote:
>> +1. Would think that all variants should exist on Optional too unless it 
>> would be harmful.
>> On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution 
>>  wrote:
>> This is a great idea, and ought to be easy enough to bring forward!  +1 from 
>> me!
>> 
>> -Michael
>> 
>>> On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution 
>>>  wrote:
>>> 
>>> 💯
>>> 
 On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution 
  wrote:
 
 The new smart key path feature is really lovely, and feels like a great 
 addition to Swift.
 
 It seems like it might be straightforward to add overloads of `map` and 
 `flatMap` to the standard library to make use of the new functionality:
 
 let managers = flatOrganisation.managers
 let allEmployees = Set(managers.flatMap(\.directReports))
 let employeeNames = Set(allEmployees.map(\.name))
 
 This feels like a really natural way of working with key paths in a 
 functional style. It makes a lot of sense for collections, and possibly 
 f

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

2017-06-07 Thread Susan Cheng via swift-evolution
that makes sense to me ;P

2017-06-08 12:07 GMT+08:00 Gwendal Roué :

> Le 8 juin 2017 à 05:15, Susan Cheng via swift-evolution <
> swift-evolution@swift.org> a écrit :
>
> Just a thought
>
> if parentheses is important, why the tuples are not?
>
> var tuple1: (Int, Int) = (0, 0)
> var tuple2: Int, Int = (0, 0)
>
> type(of: tuple1) == type(of: tuple2)// true
>
> var void: ((())) = ()
>
> type(of: void) == type(of: Void())  // true
>
>
> I think is is because Swift doesn't have tuples with a single value: those
> parenthesis are just parenthesis around an expression:
>
> let a = 1 + 2
> let b = (1 + 2)
> let c = (1 + 2) * 3
> let d = ((1 + 2)) * 3
>
> Many languages behave like that, Swift is no exception.
>
> It also allows some fancy/legacy/foreign programming styles :-)
>
> // C-style if
> if (a && b) {
> ...
> }
> // "return function"
> return(a && b)
>
> Languages that have single-valued tuples need a special syntax so that
> they are distinguished from parenthesised expressions. In Python, this is a
> trailing comma:
>
> 1# 1
> (1)  # 1
> (1,) # (1,)
>
> Swift currently disallows trailing commas inside parenthesis.
>
> 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-07 Thread Gwendal Roué via swift-evolution
> Le 8 juin 2017 à 05:15, Susan Cheng via swift-evolution 
>  a écrit :
> 
> Just a thought
> 
> if parentheses is important, why the tuples are not?
> 
> var tuple1: (Int, Int) = (0, 0)
> var tuple2: Int, Int = (0, 0)
> 
> type(of: tuple1) == type(of: tuple2)// true
> 
> var void: ((())) = ()
> 
> type(of: void) == type(of: Void())  // true

I think is is because Swift doesn't have tuples with a single value: those 
parenthesis are just parenthesis around an expression:

let a = 1 + 2
let b = (1 + 2)
let c = (1 + 2) * 3
let d = ((1 + 2)) * 3

Many languages behave like that, Swift is no exception.

It also allows some fancy/legacy/foreign programming styles :-)

// C-style if
if (a && b) {
...
}
// "return function"
return(a && b)

Languages that have single-valued tuples need a special syntax so that they are 
distinguished from parenthesised expressions. In Python, this is a trailing 
comma:

1# 1
(1)  # 1
(1,) # (1,)

Swift currently disallows trailing commas inside parenthesis.

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-07 Thread Susan Cheng via swift-evolution
if it's necessary to distinct argument list and tuple, what about the enum?


enum Foo {

case tuple(a: Int, b: Int)

}


let tuple = Foo.tuple((1, 2))


if case let .tuple(a, b) = tuple {



(a, b)//  (1, 2)

}


if case let .tuple(tuple) = tuple {



tuple//  (1, 2)

}




2017-06-08 11:36 GMT+08:00 Xiaodi Wu :

> On Wed, Jun 7, 2017 at 10:15 PM, Susan Cheng via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Just a thought
>>
>> if parentheses is important, why the tuples are not?
>>
>
> It is not parentheses that are important; it is the distinction between an
> argument list and a tuple. They both happen to be written with parentheses.
>
> var tuple1: (Int, Int) = (0, 0)
>>
>> var tuple2: Int, Int = (0, 0)
>>
>>
>> type(of: tuple1) == type(of: tuple2)// true
>>
>>
>> var void: ((())) = ()
>>
>>
>> type(of: void) == type(of: Void())  // true
>>
>>
>> 2017-06-07 10:15 GMT+08:00 Susan Cheng :
>>
>>> Introduction
>>>
>>> Because the painful of SE-0110, here is a proposal to clarify the tuple
>>> syntax.
>>>
>>> Proposed solution
>>> 1. single element tuple always be flattened
>>>
>>> let tuple1: (((Int))) = 0  // TypeOf(tuple1) == Int
>>>
>>>
>>> let tuple2: Int))), Int) = (0, 0)  // TypeOf(tuple2) == (Int, Int)
>>>
>>> 2. function arguments list also consider as a tuple, which means the
>>> function that accept a single tuple should always be flattened.
>>>
>>> let fn1: (Int, Int) -> Void = { _, _ in }
>>>
>>>
>>> let fn2: ((Int, Int)) -> Void = { _, _ in }  // always flattened
>>>
>>> let fn3: (Int, Int) -> Void = { _ in }  // not allowed, here are two
>>> arguments
>>>
>>> let fn4: ((Int, Int)) -> Void = { _ in }  // not allowed, here are two
>>> arguments
>>>
>>>
>>
>> ___
>> 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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 10:15 PM, Susan Cheng via swift-evolution <
swift-evolution@swift.org> wrote:

> Just a thought
>
> if parentheses is important, why the tuples are not?
>

It is not parentheses that are important; it is the distinction between an
argument list and a tuple. They both happen to be written with parentheses.

var tuple1: (Int, Int) = (0, 0)
>
> var tuple2: Int, Int = (0, 0)
>
>
> type(of: tuple1) == type(of: tuple2)// true
>
>
> var void: ((())) = ()
>
>
> type(of: void) == type(of: Void())  // true
>
>
> 2017-06-07 10:15 GMT+08:00 Susan Cheng :
>
>> Introduction
>>
>> Because the painful of SE-0110, here is a proposal to clarify the tuple
>> syntax.
>>
>> Proposed solution
>> 1. single element tuple always be flattened
>>
>> let tuple1: (((Int))) = 0  // TypeOf(tuple1) == Int
>>
>>
>> let tuple2: Int))), Int) = (0, 0)  // TypeOf(tuple2) == (Int, Int)
>>
>> 2. function arguments list also consider as a tuple, which means the
>> function that accept a single tuple should always be flattened.
>>
>> let fn1: (Int, Int) -> Void = { _, _ in }
>>
>>
>> let fn2: ((Int, Int)) -> Void = { _, _ in }  // always flattened
>>
>> let fn3: (Int, Int) -> Void = { _ in }  // not allowed, here are two
>> arguments
>>
>> let fn4: ((Int, Int)) -> Void = { _ in }  // not allowed, here are two
>> arguments
>>
>>
>
> ___
> 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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 10:12 PM, Stephen Celis 
wrote:

> > On Jun 7, 2017, at 10:33 PM, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > However, what I don’t get is why you’d have a mismatch here. Your method
> `first` accepts a closure, and surely the type it expects should be
> `((String, Conversation)) -> Bool` instead, since that is the type that the
> `filter` method expects in the body of your implementation?
>
> I must continue to ask for more justification as to why it's _so_ valuable
> to consider "(Int,Int)->()" and "((Int,Int))->()" to be different in _most_
> cases. Even in the contrived-described example above, the function may be
> reusable and the engineer may pass "String" and "Conversation" objects
> directly in some cases, and this distinction only makes things more
> difficult and requires cumbersome workarounds.
>
> I know you feel that the ship has sailed, and I understand the ambiguities
> these proposals intended to clarify, but for the most common cases,
> treating a function that takes a single tuple the same way we treat a
> function that takes the same number of values that same tuple contains
> is...really nice, so maybe there's a better way to disambiguate.
>

Again, an argument list was once a tuple: this solution was investigated
and "completely abandoned" early in the development of Swift "for a large
number of reasons (including inout, default arguments, variadic arguments,
labels, etc)". Removal of implicit tuple splatting was outlined in SE-0029.
Namely, for a function `foo(_:b:)` called using a tuple `x`:

>A call to foo(x) looks like a call to an overloaded version of foo, both
to the compiler and to the human who maintains the code. This is extremely
confusing if you don't know the feature exists.
>There are real ambiguities in the syntax, e.g. involving Any arguments and
situations where you want to pass a tuple value as a single parameter.
>The current implementation has a ton of implementation bugs - it doesn't
work reliably.
>The current implementation adds complexity to the type checker, slowing it
down and adding maintenance burden.
>The current implementation doesn't work the way we would want a tuple
splat operation to work.

...

>The root problem here is that we use exactly the same syntax for both
forms of function application. If the two forms were differentiated (an
option considered in “alternatives considered” below) then some of these
problems would be defined away.

However,

>[A]ctually designing this feature would be a non-trivial effort...
>We don't have an obvious sigil to use. "prefix-star" should be left unused
for now in case we want to use it to refer to memory-related operations in
the future.
>Making the tuple splat operation great requires more than just fixing the
syntactic ambiguities we have, it would require re-evaluating the semantics
of the operation (e.g. in light of parameter labels, varargs and other
features).

The removal of tuple splatting was approved during Swift *2* Evolution; it
so happens that one particular segment of the feature was not excised until
SE-0110, but the writing was on the wall, so to speak, for 18 months.

I'll work with whatever final solution the Swift team comes up with, but in
> the meantime I'm not going to shy away from reacting to regressions.
>
> I've referred to these regressions as "ergonomic" in the past, but it's
> more about expressiveness. Swift 3 (and earlier) syntax allowed for
> functional, point-free expression that could amount to very succinct,
> readable code. The code Swift 4 requires is harder to read and harder to
> maintain.
>
> Stephen
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Stephen Celis via swift-evolution
-1

A -1 from me may be surprising. I'm excited about key path composition and 
generic solutions, e.g. this experiment with lenses: 
https://twitter.com/stephencelis/status/863916921577758721

But I'd prefer a reusable solution for converting key paths into functions.

Heaven help me for this Rubyism, but a prefix "&" operator (or, maybe better 
yet, some implicit mechanism) could convert a key-path to a function that 
passes a root value to a key path...

   people.map(&\.firstName)

This way any function that takes a transformation from "whole" to "part" could 
take a key path. Requiring an overload per instance is less flexible.

Stephen

> On Jun 7, 2017, at 10:58 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> +1, I really like this. It would also align nicely with the method type 
> flattening in SE-0042 (once it gets implemented), because passing keypaths 
> (i.e., unbound property references) and unbound parameterless method 
> references to map/flatMap would look nearly the same:
> 
> ```
> struct Person {
>   let firstName: String
>   let lastName: String
>   func fullName() -> String { return "\(firstName) \(lastName)" }
> }
> 
> let people: [Person]
> let firstNames = people.map(\.firstName)
> let fullNames = people.map(Person.fullName)  // because after SE-0042, this 
> will be (Person) -> String, not (Person) -> () -> String
> ```
> 
> Especially if there's a move in the future to also use \. to denote unbound 
> methods references, which was discussed during the keypath reviews. (Even 
> with that, I believe it would be more work though to get rid of the explicit 
> type name in the function case.)
> 
> 
> On Wed, Jun 7, 2017 at 6:11 PM Xiaodi Wu via swift-evolution 
>  wrote:
> +1. Would think that all variants should exist on Optional too unless it 
> would be harmful.
> On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution 
>  wrote:
> This is a great idea, and ought to be easy enough to bring forward!  +1 from 
> me!
> 
> -Michael
> 
> > On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution 
> >  wrote:
> >
> > 💯
> >
> >> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution 
> >>  wrote:
> >>
> >> The new smart key path feature is really lovely, and feels like a great 
> >> addition to Swift.
> >>
> >> It seems like it might be straightforward to add overloads of `map` and 
> >> `flatMap` to the standard library to make use of the new functionality:
> >>
> >>  let managers = flatOrganisation.managers
> >>  let allEmployees = Set(managers.flatMap(\.directReports))
> >>  let employeeNames = Set(allEmployees.map(\.name))
> >>
> >> This feels like a really natural way of working with key paths in a 
> >> functional style. It makes a lot of sense for collections, and possibly 
> >> for Optional too (although as far as I can see optional chaining is more 
> >> or less equivalent, and with more compact syntax).
> >>
> >> I’m hoping that this might be low-hanging fruit that could be considered 
> >> for the Swift 4 release. I’d be happy to have a go at writing a proposal 
> >> if there’s interest!
> >>
> >> –Adam
> >>
> >> ___
> >> 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
> ___
> 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-07 Thread Susan Cheng via swift-evolution
Just a thought

if parentheses is important, why the tuples are not?


var tuple1: (Int, Int) = (0, 0)

var tuple2: Int, Int = (0, 0)


type(of: tuple1) == type(of: tuple2)// true


var void: ((())) = ()


type(of: void) == type(of: Void())  // true


2017-06-07 10:15 GMT+08:00 Susan Cheng :

> Introduction
>
> Because the painful of SE-0110, here is a proposal to clarify the tuple
> syntax.
>
> Proposed solution
> 1. single element tuple always be flattened
>
> let tuple1: (((Int))) = 0  // TypeOf(tuple1) == Int
>
>
> let tuple2: Int))), Int) = (0, 0)  // TypeOf(tuple2) == (Int, Int)
>
> 2. function arguments list also consider as a tuple, which means the
> function that accept a single tuple should always be flattened.
>
> let fn1: (Int, Int) -> Void = { _, _ in }
>
>
> let fn2: ((Int, Int)) -> Void = { _, _ in }  // always flattened
>
> let fn3: (Int, Int) -> Void = { _ in }  // not allowed, here are two
> arguments
>
> let fn4: ((Int, Int)) -> Void = { _ in }  // not allowed, here are two
> arguments
>
>
___
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-07 Thread Stephen Celis via swift-evolution
> On Jun 7, 2017, at 10:33 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> However, what I don’t get is why you’d have a mismatch here. Your method 
> `first` accepts a closure, and surely the type it expects should be 
> `((String, Conversation)) -> Bool` instead, since that is the type that the 
> `filter` method expects in the body of your implementation?

I must continue to ask for more justification as to why it's _so_ valuable to 
consider "(Int,Int)->()" and "((Int,Int))->()" to be different in _most_ cases. 
Even in the contrived-described example above, the function may be reusable and 
the engineer may pass "String" and "Conversation" objects directly in some 
cases, and this distinction only makes things more difficult and requires 
cumbersome workarounds.

I know you feel that the ship has sailed, and I understand the ambiguities 
these proposals intended to clarify, but for the most common cases, treating a 
function that takes a single tuple the same way we treat a function that takes 
the same number of values that same tuple contains is...really nice, so maybe 
there's a better way to disambiguate.

I'll work with whatever final solution the Swift team comes up with, but in the 
meantime I'm not going to shy away from reacting to regressions.

I've referred to these regressions as "ergonomic" in the past, but it's more 
about expressiveness. Swift 3 (and earlier) syntax allowed for functional, 
point-free expression that could amount to very succinct, readable code. The 
code Swift 4 requires is harder to read and harder to maintain.

Stephen

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


Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Tony Allevato via swift-evolution
+1, I really like this. It would also align nicely with the method type
flattening in SE-0042

(once it gets implemented), because passing keypaths (i.e., unbound
property references) and unbound parameterless method references to
map/flatMap would look nearly the same:

```
struct Person {
  let firstName: String
  let lastName: String
  func fullName() -> String { return "\(firstName) \(lastName)" }
}

let people: [Person]
let firstNames = people.map(\.firstName)
let fullNames = people.map(Person.fullName)  // because after SE-0042, this
will be (Person) -> String, not (Person) -> () -> String
```

Especially if there's a move in the future to also use \. to denote unbound
methods references, which was discussed during the keypath reviews. (Even
with that, I believe it would be more work though to get rid of the
explicit type name in the function case.)


On Wed, Jun 7, 2017 at 6:11 PM Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> +1. Would think that all variants should exist on Optional too unless it
> would be harmful.
> On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> This is a great idea, and ought to be easy enough to bring forward!  +1
>> from me!
>>
>> -Michael
>>
>> > On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> > 💯
>> >
>> >> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >>
>> >> The new smart key path feature is really lovely, and feels like a
>> great addition to Swift.
>> >>
>> >> It seems like it might be straightforward to add overloads of `map`
>> and `flatMap` to the standard library to make use of the new functionality:
>> >>
>> >>  let managers = flatOrganisation.managers
>> >>  let allEmployees = Set(managers.flatMap(\.directReports))
>> >>  let employeeNames = Set(allEmployees.map(\.name))
>> >>
>> >> This feels like a really natural way of working with key paths in a
>> functional style. It makes a lot of sense for collections, and possibly for
>> Optional too (although as far as I can see optional chaining is more or
>> less equivalent, and with more compact syntax).
>> >>
>> >> I’m hoping that this might be low-hanging fruit that could be
>> considered for the Swift 4 release. I’d be happy to have a go at writing a
>> proposal if there’s interest!
>> >>
>> >> –Adam
>> >>
>> >> ___
>> >> 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
>
___
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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 19:15 Víctor Pimentel Rodríguez 
wrote:

> On 7 Jun 2017, at 21:29, Xiaodi Wu  wrote:
>
>
> SE-0110 may be an obvious extension of the proposed goal, but it is clear
>> that it has been implemented in Swift 4, and that the consequences are
>> derived of those changesets.
>>
>> Those "unwanted" consequences can be reverted by temporarily reverting
>> SE-0110, without touching any other previous proposal.
>>
>> In no place I see Gwendal asking for full reversal of 5 proposals. He is
>> just voicing something that a lot of app developers and library maintainers
>> are not going to understand in September.
>>
>> For example, you can see all the changes needed in RXSwift so that it
>> compiles to Swift 4:
>>
>> https://github.com/ReactiveX/RxSwift/pull/1282/commits/
>> 915e00fa6d1e59d58cd8c38dd6dc83765fc67fe4
>>
>> I would not want to migrate to Swift 4 an app using such framework.
>>
>> I asked you in my first reply to you, is your view that the distinction
>> itself between (Int, Int) -> Int and ((Int, Int)) -> Int is problematic? If
>> so, this is a very different discussion from seeking solutions to mitigate
>> particular ergonomic issues that arise from the change. However, you have
>> not answered the question.
>>
>>
>> As far as I can see, the bigger usability regressions are caused when
>> using generics, specially in collections and functional utilities. When you
>> specify that type with a tuple, as in Dictionary, then all the related
>> methods start receiving closures receiving tuples.
>>
>> Notice that allowing some syntactic sugar on the call site of those
>> closures may not be enough, since you may have stored or passed a closure
>> for customization purposes.
>>
>
> Can you illustrate this with an example? I’m not sure I understand what
> you’re getting at here.
>
>
> Sure. Let's say you want to filter some elements from a dictionary, and
> you have this valid Swift 3 code:
>
> let conversationsById: [String: Conversation]
> let unreadConversations = conversationsById.filter { $1.isUnread }
>
> Or:
>
> let unreadConversations = conversationsById.filter { id, c in
> return !id.isEmpty && c.isUnread
> }
>
> Neither of these expressions are permitted in Swift 4, but some syntactic
> sugar can be added to allowing it again without the need of full tuple
> splatting.
>

Right.

However, if for some reason you want to pass around a filter closure, you
> will still have mismatch types:
>
> func first(passing filter: (String, Conversation) -> Bool) ->
> Conversation? {
> return conversationsById.filter(filter).first?.value
> }
>

> This example is simple and useless and contrived, but it gets even worse
> when you take generics into account to catch any type of closure.
>

I’m not going to raise any issues over how realistic the scenario might be.
It's for answering a question, after all.

However, what I don’t get is why you’d have a mismatch here. Your method
`first` accepts a closure, and surely the type it expects should be
`((String, Conversation)) -> Bool` instead, since that is the type that the
`filter` method expects in the body of your implementation?

Certainly, there are scenarios not possible (or at least, very difficult)
without tuple splatting, but that’s straight-up an argument for tuple
splatting. That's, IMO, an unnecessary argument, since the usefulness of
the feature has never been in question, only the resources to design and
implement.

This behavior is so hurtful to functional style programming, that I think
>> either SE-0110 should be reverted, or alternatives like this Susan proposal
>> should be implemented.
>>
>
> To be clear, what you and Gwendal are objecting to is the loss of tuple
> splatting, is it not? Again, SE-0110 is only the final piece; SE-0029 is
> what removed implicit tuple splatting. As that proposal said, a properly
> designed explicit tuple splatting can be considered if there’s demand, and
> it was understood that removing this functionality would be a regression
> and nonetheless the decision for removal was still deliberately undertaken.
> Re-reading that proposal, the rationale was that it never worked correctly
> to begin with, and the barrier for bringing it back is that it requires
> considerable effort to design and implement the feature correctly.
>
> I'm sorry if there has been any disrespect for my part, I appreciate what
> you all do here. But sometimes it's a bit frustrating having to explain why
> something that seems obvious to us is not obvious to others.
>
> I think that you have a bigger picture from the Swift Evolution point, but
> the thing is that Swift users like me doesn't have that context, and we are
> baffled when we encounter that some pretty simple code turns into a weird
> thing in a migration. I have linked to several real examples out there, and
> it seems to be a popular opinion. Nevertheless, it was Tony Parker's mail
> the one that kindled this discussion with a really simple question.
>
> It ma

Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Xiaodi Wu via swift-evolution
+1. Would think that all variants should exist on Optional too unless it
would be harmful.
On Wed, Jun 7, 2017 at 20:13 Michael J LeHew Jr via swift-evolution <
swift-evolution@swift.org> wrote:

> This is a great idea, and ought to be easy enough to bring forward!  +1
> from me!
>
> -Michael
>
> > On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > 💯
> >
> >> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >> The new smart key path feature is really lovely, and feels like a great
> addition to Swift.
> >>
> >> It seems like it might be straightforward to add overloads of `map` and
> `flatMap` to the standard library to make use of the new functionality:
> >>
> >>  let managers = flatOrganisation.managers
> >>  let allEmployees = Set(managers.flatMap(\.directReports))
> >>  let employeeNames = Set(allEmployees.map(\.name))
> >>
> >> This feels like a really natural way of working with key paths in a
> functional style. It makes a lot of sense for collections, and possibly for
> Optional too (although as far as I can see optional chaining is more or
> less equivalent, and with more compact syntax).
> >>
> >> I’m hoping that this might be low-hanging fruit that could be
> considered for the Swift 4 release. I’d be happy to have a go at writing a
> proposal if there’s interest!
> >>
> >> –Adam
> >>
> >> ___
> >> 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] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Michael J LeHew Jr via swift-evolution
This is a great idea, and ought to be easy enough to bring forward!  +1 from me!

-Michael

> On Jun 7, 2017, at 11:18 AM, Matt Diephouse via swift-evolution 
>  wrote:
> 
> 💯
> 
>> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution 
>>  wrote:
>> 
>> The new smart key path feature is really lovely, and feels like a great 
>> addition to Swift.
>> 
>> It seems like it might be straightforward to add overloads of `map` and 
>> `flatMap` to the standard library to make use of the new functionality:
>> 
>>  let managers = flatOrganisation.managers
>>  let allEmployees = Set(managers.flatMap(\.directReports))
>>  let employeeNames = Set(allEmployees.map(\.name))
>> 
>> This feels like a really natural way of working with key paths in a 
>> functional style. It makes a lot of sense for collections, and possibly for 
>> Optional too (although as far as I can see optional chaining is more or less 
>> equivalent, and with more compact syntax).
>> 
>> I’m hoping that this might be low-hanging fruit that could be considered for 
>> the Swift 4 release. I’d be happy to have a go at writing a proposal if 
>> there’s interest!
>> 
>> –Adam
>> 
>> ___
>> 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-07 Thread Víctor Pimentel Rodríguez via swift-evolution
On 7 Jun 2017, at 21:29, Xiaodi Wu  wrote:


SE-0110 may be an obvious extension of the proposed goal, but it is clear
> that it has been implemented in Swift 4, and that the consequences are
> derived of those changesets.
>
> Those "unwanted" consequences can be reverted by temporarily reverting
> SE-0110, without touching any other previous proposal.
>
> In no place I see Gwendal asking for full reversal of 5 proposals. He is
> just voicing something that a lot of app developers and library maintainers
> are not going to understand in September.
>
> For example, you can see all the changes needed in RXSwift so that it
> compiles to Swift 4:
>
> https://github.com/ReactiveX/RxSwift/pull/1282/commits/915e0
> 0fa6d1e59d58cd8c38dd6dc83765fc67fe4
>
> I would not want to migrate to Swift 4 an app using such framework.
>
> I asked you in my first reply to you, is your view that the distinction
> itself between (Int, Int) -> Int and ((Int, Int)) -> Int is problematic? If
> so, this is a very different discussion from seeking solutions to mitigate
> particular ergonomic issues that arise from the change. However, you have
> not answered the question.
>
>
> As far as I can see, the bigger usability regressions are caused when
> using generics, specially in collections and functional utilities. When you
> specify that type with a tuple, as in Dictionary, then all the related
> methods start receiving closures receiving tuples.
>
> Notice that allowing some syntactic sugar on the call site of those
> closures may not be enough, since you may have stored or passed a closure
> for customization purposes.
>

Can you illustrate this with an example? I’m not sure I understand what
you’re getting at here.


Sure. Let's say you want to filter some elements from a dictionary, and you
have this valid Swift 3 code:

let conversationsById: [String: Conversation]
let unreadConversations = conversationsById.filter { $1.isUnread }

Or:

let unreadConversations = conversationsById.filter { id, c in
return !id.isEmpty && c.isUnread
}

Neither of these expressions are permitted in Swift 4, but some syntactic
sugar can be added to allowing it again without the need of full tuple
splatting.

However, if for some reason you want to pass around a filter closure, you
will still have mismatch types:

func first(passing filter: (String, Conversation) -> Bool) -> Conversation?
{
return conversationsById.filter(filter).first?.value
}

This example is simple and useless and contrived, but it gets even worse
when you take generics into account to catch any type of closure.

This behavior is so hurtful to functional style programming, that I think
> either SE-0110 should be reverted, or alternatives like this Susan proposal
> should be implemented.
>

To be clear, what you and Gwendal are objecting to is the loss of tuple
splatting, is it not? Again, SE-0110 is only the final piece; SE-0029 is
what removed implicit tuple splatting. As that proposal said, a properly
designed explicit tuple splatting can be considered if there’s demand, and
it was understood that removing this functionality would be a regression
and nonetheless the decision for removal was still deliberately undertaken.
Re-reading that proposal, the rationale was that it never worked correctly
to begin with, and the barrier for bringing it back is that it requires
considerable effort to design and implement the feature correctly.

I'm sorry if there has been any disrespect for my part, I appreciate what
you all do here. But sometimes it's a bit frustrating having to explain why
something that seems obvious to us is not obvious to others.

I think that you have a bigger picture from the Swift Evolution point, but
the thing is that Swift users like me doesn't have that context, and we are
baffled when we encounter that some pretty simple code turns into a weird
thing in a migration. I have linked to several real examples out there, and
it seems to be a popular opinion. Nevertheless, it was Tony Parker's mail
the one that kindled this discussion with a really simple question.

It may be the last piece, but it is the piece that impacted simple code the
most, or at least the one that had the most unexpected consequences.
Certainly that proposal does not contain nearly enough code examples or
goes deeply enough. And this is subjective, but for me this isn't true:
"Minor changes to user code may be required if this proposal is accepted."

The fact that it affects even the standard library shows how hurtful
removing this feature is. It's not a nice-to-have feature or a
somewhat-useful feature, it's that right now it's very difficult to model
something as essential as Dictionary with a nice-to-use API. So lots of
other custom types will suffer too.

If we all agree that this is a loss of ergonomics, then the Core Team have
several options for Swift 4:

1. Do nothing.
2. Revert SE-0110 related changes.
3. Add a complex tuple-splatting feature.
4. Add some syntactic sugar keeping th

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

2017-06-07 Thread Vladimir.S via swift-evolution

On 07.06.2017 21:33, Gwendal Roué wrote:


Le 7 juin 2017 à 17:15, Vladimir.S mailto:sva...@gmail.com>> a 
écrit :


On 07.06.2017 16:20, Gwendal Roué wrote:
Le 7 juin 2017 à 15:11, Xiaodi Wu  > a écrit :


While SE-0025 was generally regarded as unfortunate, the thousands of emails that 
followed relitigating it were much, much worse.


The removal of implicit tuple splatting, which is *not* SE-0110, was approved on 
the understanding that it would be a regression until explicit tuple splatting is 
introduced. This tradeoff was considered and approved. It’s clear that you 
disagree, but that is not grounds to divert a necessary discussion on mitigating 
SE-0110 into relitigating something else.

Push me out if you want, but will you push out those blatant wounds out as well?
Example 1
-return columns.index { (column, _) in column.lowercased() == 
lowercaseName }
+return columns.index { $0.0.lowercased() == lowercaseName }


Why not
columns.index { (arg: (column: String, _: Int)) in arg.column.lowercased() == 
lowercaseName }

?


It would works, but it's less than ideal: the `args` name has no meaning. We have an 
extra type declaration instead of type inference. 


Yes, as I said below, it's clearly 'less than ideal', but I do believe this variant 
is much better than what you shown as regression example. That was my main point.


As for 'arg' name.. well.. naming is very hard task ;-) I didn't think about name in 
this case, probably 'arg' should be 'column' and current 'column' should be just 
'name', if I understand correctly:
columns.index { (column: (name: String, _: Int)) in column.name.lowercased() == 
lowercaseName }



Btw, I forgot to mention another one good(IMO) suggestion for tuple argument 
destructuring syntax in closure:


* allow type inference for tuple parts in already allowed syntax i.e. :
columns.index { (column: (name, _)) in column.name.lowercased() == 
lowercaseName }

I even feel like this one can be the best candidate *for now* as it just relaxes 
requirements for type annotation, allows type inference, that seems very naturally 
for closures. Similar like we can omit type for arguments in argument list, but just 
for tuple parts. This could be just additive sugar for closures that will help to 
migrate to Swift 4 with *less* pain. Then we'll have an ability to discuss best 
solution for tuple argument deconstruction in details in separate proposal, after 
Swift4 is released.


> It's much longer. The clarity is
> tremendously reduced.

I just can't agree with this. IMO it is slightly longer, and clarity is slightly 
reduced.




- return columns.index { (column, _) in column.lowercased() == lowercaseName }
+ return columns.index { (arg: (column: String, _)) in arg.column.lowercased() == 
lowercaseName }


Yes, I understand that first syntax short and not verbose, but the alternative you 
provided IMHO much worse than explicit type declaration in closure.


It's not an "alternative": it's Swift 3.

Maybe you did already profit from it, but did not notice.



Sorry, I don't understand.
I assume you had this code for Swift 3:
return columns.index { (column, _) in column.lowercased() == lowercaseName }
and you need to convert it to Swift 4, so you are saying "look how this is 
ugly":
return columns.index { $0.0.lowercased() == lowercaseName }
and I'm saying "we can instead in Swift 4 have this":
return columns.index { (arg: (column: String, _)) in arg.column.lowercased() ==
 lowercaseName }
which is IMO much better *and* will compile in Swift 3 also.




Example 2 :
-.map { (mappedColumn, baseColumn) -> (Int, String) in
+.map { (pair) -> (Int, String) in
+let mappedColumn = pair.key
+let baseColumn = pair.value


Can't compile something like this even in Swift 3, could you provide a small code 
snippet for this?


Sure:

 letmapping: [String: String] = ...
 mapping.map { (mappedColumn, baseColumn) -> (Int, String) in ... }



Thank you, yes, here is the same:

let mapping: [String: String] = ["1":"2", "3":"4"]
let _ = mapping.map { (item: (mappedColumn: String, baseColumn: String)) -> (Int, 
String) in (0, item.baseColumn) }



Example 3 :
-.map { (table, columns) in 
"\(table)(\(columns.sorted().joined(separator: ", ")))" }

+.map { "\($0.key)(\($0.value.sorted().joined(separator: ", 
")))" }


Same, why not

.map { (arg: (table: String, columns: [String])) in 
"\(arg.table)(\(arg.columns.sorted().joined(separator: ", ")))" }


Same answer: the extra `args` works, but we still have an ergonomics regression from 
Swift 3.


Agree. We have some ergonomics regression in this case. But for now, it is IMO the 
best solution we have to port such Swift 3 code to Swift 4. Let's wait what core team 
will decide about this.





Example 4 :
-dictionary.first { (column, value) in column.lowercased() == 
ordere

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

2017-06-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 14:33 Gwendal Roué via swift-evolution <
swift-evolution@swift.org> wrote:

> Le 7 juin 2017 à 17:15, Vladimir.S  a écrit :
>
> On 07.06.2017 16:20, Gwendal Roué wrote:
>
> Le 7 juin 2017 à 15:11, Xiaodi Wu  mailto:xiaodi...@gmail.com >> a écrit :
>
> While SE-0025 was generally regarded as unfortunate, the thousands of
> emails that followed relitigating it were much, much worse.
>
> The removal of implicit tuple splatting, which is *not* SE-0110, was
> approved on the understanding that it would be a regression until explicit
> tuple splatting is introduced. This tradeoff was considered and approved.
> It’s clear that you disagree, but that is not grounds to divert a necessary
> discussion on mitigating SE-0110 into relitigating something else.
>
> Push me out if you want, but will you push out those blatant wounds out as
> well?
> Example 1
> -return columns.index { (column, _) in column.lowercased() ==
> lowercaseName }
> +return columns.index { $0.0.lowercased() == lowercaseName }
>
>
> Why not
> columns.index { (arg: (column: String, _: Int)) in arg.column.lowercased()
> == lowercaseName }
> ?
>
>
> It would works, but it's less than ideal: the `args` name has no meaning.
> We have an extra type declaration instead of type inference. It's much
> longer. The clarity is tremendously reduced.
>
> - return columns.index { (column, _) in column.lowercased() ==
> lowercaseName }
> + return columns.index { (arg: (column: String, _)) in
> arg.column.lowercased() == lowercaseName }
>
> Yes, I understand that first syntax short and not verbose, but the
> alternative you provided IMHO much worse than explicit type declaration in
> closure.
>
>
> It's not an "alternative": it's Swift 3.
>
> Maybe you did already profit from it, but did not notice.
>
>
> Example 2 :
> -.map { (mappedColumn, baseColumn) -> (Int, String) in
> +.map { (pair) -> (Int, String) in
> +let mappedColumn = pair.key
> +let baseColumn = pair.value
>
>
> Can't compile something like this even in Swift 3, could you provide a
> small code snippet for this?
>
>
> Sure:
>
> let mapping: [String: String] = ...
> mapping.map { (mappedColumn, baseColumn) -> (Int, String) in ... }
>
> Example 3 :
> -.map { (table, columns) in
> "\(table)(\(columns.sorted().joined(separator: ", ")))" }
> +.map { "\($0.key)(\($0.value.sorted().joined(separator:
> ", ")))" }
>
>
> Same, why not
>
> .map { (arg: (table: String, columns: [String])) in
> "\(arg.table)(\(arg.columns.sorted().joined(separator: ", ")))" }
>
>
> Same answer: the extra `args` works, but we still have an ergonomics
> regression from Swift 3.
>
> Example 4 :
> -dictionary.first { (column, value) in column.lowercased()
> == orderedColumn.lowercased() }
> +dictionary.first { $0.key.lowercased() ==
> orderedColumn.lowercased() }
>
>
> Same.
>
>
> Indeed.
>
>
> See also messages from Stephen Cellis, who shows how other kinds of
> developer code has lost expressivity and clarity with those changes that
> have been "considered and approved".
>
>
> Gwendal, no one saying that new syntax is better, that it is good thing
> that we lost the short syntax for tuple argumment deconstructions in
> closures.
>
>
> Good to hear :-)
>
> But there is just no easy/obvious way to keep that syntax in Swift 4. The
> problem can't be solved just by not implementing SE-0110, as in Swift4 we
> should have two separate function types: one that takes single tuple
> argument and second that accepts a list of arguments, i.e. (Int,Int)->()
> and ((Int,Int))->() should be two different types now.
>
>
> Of course I understand that.
>
> I expect the compiler to perform the expected conversions for ergonomics'
> sake.
>
> I can understand that this sugar could be added *after* current problems
> which are not related to ergonomics are solved. I just want to make it
> clear that there is an ergonomics problem *now*, and that solving it should
> have a very high priority.
>

If this was the point you wished to make, then there isn’t any
disagreement, I don’t think. We *all* can obviously agree that there is a
loss in ergonomics due to SE-0110.

This is not just SE-0110, this is also SE-0066, so, to be correct, you
> should propose to revisit it also.
>
> Please look here:
>
> func foo(_ x: Int, _ y: Int) {} // type(of: foo) should be (Int, Int)->()
> func bar(_ x (Int, Int)) {} // type(of: bar) should be ((Int, Int))->()
>
> The above is described in SE-0066. Then, you have a closure constants:
>
> var fooClosure = {(x: Int, y: Int) in }
> var barClosure = {(x: (Int, Int)) in }
>
> what should be types of these closures? Obvious the same: (Int,Int)->()
> and ((Int,Int))->() respectively.
>
>
> I guess you mean, not the same: (Int, Int) -> () vs. ((Int, Int)) -> ().
>
> Then you have a func that accepts ((Int,Int))->Int closure:
>
> func schedule(callback: ((Int,Int))-

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

2017-06-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 14:13 Víctor Pimentel Rodríguez 
wrote:

>
> On 7 Jun 2017, at 18:10, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Wed, Jun 7, 2017 at 10:03 Gwendal Roué  wrote:
>
>> Le 7 juin 2017 à 15:52, Xiaodi Wu  a écrit :
>>
>> Let’s clarify: you just wrote that you have problems with SE-0029,
>> SE-0066, SE-0110, and “before,” did you not?
>>
>>
>> WTF? No I did not (citation below)!
>>
>> Le 7 juin 2017 à 15:02, Gwendal Roué  a écrit :
>>
>> Le 7 juin 2017 à 14:42, Vladimir.S  a écrit :
>>
>>
>> Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066
>> but mainly SE-0029 "Remove implicit tuple splat behavior from function
>> applications"
>> (
>> https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md
>> )
>>
>>
>> Do you mean that the regressions Stephen and I have shown have been
>> introduced not only by SE-0110, but before SE-0066, and SE-0029?
>>
>>
>> Your attitude is obnoxious. Enough Swift evolution for me today.
>>
>
> Please refrain from personal attacks. Are we reading the same sentence? I
> see that you literally listed three proposals (and “before”) and blamed
> them for “regressions” that you want to reverse. If that’s not your
> meaning, what do you mean?
>
>
> In the conversation you can see that Vladimir stated that proposing to
> revert this proposal would also mean reverting other previous proposals.
>
> Gwendal is only asking back if the bug was introduced by the changesets
> related to those proposals or by the changesets related to SE-0110.
>
> Asking back is very different from blaming those proposals, or asking for
> reversal of Swift 3 proposals.
>

See, I read that sentence as a rhetorical question, intensifying his claim
of not merely one but all of these proposals being regressions. If that’s
is not what’s intended, that is fine, but he is certainly capable of
replying to my question about his meaning without declaring me to be
‘obnoxious.’

SE-0110 may be an obvious extension of the proposed goal, but it is clear
> that it has been implemented in Swift 4, and that the consequences are
> derived of those changesets.
>
> Those "unwanted" consequences can be reverted by temporarily reverting
> SE-0110, without touching any other previous proposal.
>
> In no place I see Gwendal asking for full reversal of 5 proposals. He is
> just voicing something that a lot of app developers and library maintainers
> are not going to understand in September.
>
> For example, you can see all the changes needed in RXSwift so that it
> compiles to Swift 4:
>
>
> https://github.com/ReactiveX/RxSwift/pull/1282/commits/915e00fa6d1e59d58cd8c38dd6dc83765fc67fe4
>
> I would not want to migrate to Swift 4 an app using such framework.
>
> I asked you in my first reply to you, is your view that the distinction
> itself between (Int, Int) -> Int and ((Int, Int)) -> Int is problematic? If
> so, this is a very different discussion from seeking solutions to mitigate
> particular ergonomic issues that arise from the change. However, you have
> not answered the question.
>
>
> As far as I can see, the bigger usability regressions are caused when
> using generics, specially in collections and functional utilities. When you
> specify that type with a tuple, as in Dictionary, then all the related
> methods start receiving closures receiving tuples.
>
> Notice that allowing some syntactic sugar on the call site of those
> closures may not be enough, since you may have stored or passed a closure
> for customization purposes.
>

Can you illustrate this with an example? I’m not sure I understand what
you’re getting at here.

This behavior is so hurtful to functional style programming, that I think
> either SE-0110 should be reverted, or alternatives like this Susan proposal
> should be implemented.
>

To be clear, what you and Gwendal are objecting to is the loss of tuple
splatting, is it not? Again, SE-0110 is only the final piece; SE-0029 is
what removed implicit tuple splatting. As that proposal said, a properly
designed explicit tuple splatting can be considered if there’s demand, and
it was understood that removing this functionality would be a regression
and nonetheless the decision for removal was still deliberately undertaken.
Re-reading that proposal, the rationale was that it never worked correctly
to begin with, and the barrier for bringing it back is that it requires
considerable effort to design and implement the feature correctly.

However, reverting may be safer and faster than adding more new code to the
> compiler with such short time until Swift 4 release.
>
> Of course that´s the Core team call, if the gains in the compiler code is
> so great then we'll have to live with this regression. After WWDC I hope
> that they notify their decision.
>
> --
> Víctor Pimentel
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman

[swift-evolution] History and future of Swift's parentheses

2017-06-07 Thread Jens Persson via swift-evolution
Swift uses parentheses for a lot of different things (tuples, parameters,
calls, grouping, pattern matching, etc), this has led to some confusion,
for both language designers and users.

Here's a practical introduction that is possibly worth more than a thousand
words (or perhaps even swift-evo posts):

  Exercise 1
Write a (generic) function composition operator in Swift 4
(working as expected for all function types).

  Exercise 2
Write a generic type WrappedFunction that can wrap any function in
Swift 4
(with type parameters for Input and Output).

When you have completed (or given up) the exercises, please note that once
in the history of Swift, these were simple tasks. You could come up with
working solutions very quickly without any boilerplate or special casing
(although perhaps not entirely without some of the parentheses-related
inconsistencies of that time).

I've been reporting a lot of parentheses-related bugs since the first Swift
beta, and I'm only getting more and more worried that the current
incremental approach to fixing these is not working very well, resulting in
a language that is more complex and less expressive than it could be.

Discussions often seem to end up being a bit too focused on particular use
cases and details, and less on how everything fit together as a system.


So I wonder if any of you have had any thoughts about what Swift's
parentheses-related future (or evolutionary baggage) will be?


PS

My perhaps unpopular thoughts:

I wish the parentheses-related parts of Swift could be carefully evaluated
and redesigned from scratch, as a whole, in order to arrive at a solution
that is as simple and expressive as possible.

But perhaps this has already happened and we are now just taking some steps
back that are necessary for reimplementing some of the good stuff (that has
been - at least IMHO - sort of hinted in earlier versions of Swift). But it
feels like there is not enough time ...

Swift, please break my code all you want before it's too late, as long as
it results in increased (rather than decreased) consistency, simplicity,
expressiveness, optimizability and safety. Otherwise I could have used
Objective C++.

/Jens
___
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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 20:33, Gwendal Roué  a écrit :
> 
> For example, take those three functions:
> 
>   func f(_ closure:(Int, Int) -> ())
>   func g(_ closure:((Int, Int)) -> ())
>   func h(_ closure:((a: Int, b: Int)) -> ())
> 
> If one can always write (as in Swift 3):
> 
>   f { (a, b) in ... }
>   g { (a, b) in ... }
>   c { (a, b) in ... }
> 
> Then one can easily deal with a badly fit closure signature.
> 
> This is most examplified by dictionaries. They always expose (key: Key, 
> value: Value) tuples (their Element type). Problem is that 'key' and 'value' 
> are identifiers that only matter for dictionaries, not for dictionary users. 
> It's very important for dictionary users to forget about tuples, and the 
> `key` and `value` words:
> 
>   // No pollution
>   dictionary.map { (name, score) in ... }

It looks like some people in this mailing list are horrified by this "request" 
(not a feature request, but a request that Swift 3 behavior is restored, 
actually).

What could be the reasons for such a bad reaction?

1: measurable runtime overhead (slower programs in some cases, without any 
obvious way for the developper to notice where is the extra cost)
2: measurable compiler overhead (slower compilation)
3: implementation complexity (slower swift progress, technical debt, etc.)
4: other?

I understand 1. We are all fascinated by C++ and Rust "zero-overhead". If this 
is the main concern of the community, then we may focus the discussion of that 
very precise topic.

I can live with 2 (just a personal subjective preference)

About 3: I can not tell because I lack the necessary skills.

4: enlighten us!

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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 17:15, Vladimir.S  a écrit :
> 
> On 07.06.2017 16:20, Gwendal Roué wrote:
>>> Le 7 juin 2017 à 15:11, Xiaodi Wu >> > a écrit :
>>> 
>>> While SE-0025 was generally regarded as unfortunate, the thousands of 
>>> emails that followed relitigating it were much, much worse.
>>> 
>>> The removal of implicit tuple splatting, which is *not* SE-0110, was 
>>> approved on the understanding that it would be a regression until explicit 
>>> tuple splatting is introduced. This tradeoff was considered and approved. 
>>> It’s clear that you disagree, but that is not grounds to divert a necessary 
>>> discussion on mitigating SE-0110 into relitigating something else.
>> Push me out if you want, but will you push out those blatant wounds out as 
>> well?
>> Example 1
>> -return columns.index { (column, _) in column.lowercased() == 
>> lowercaseName }
>> +return columns.index { $0.0.lowercased() == lowercaseName }
> 
> Why not
> columns.index { (arg: (column: String, _: Int)) in arg.column.lowercased() == 
> lowercaseName }
> ?

It would works, but it's less than ideal: the `args` name has no meaning. We 
have an extra type declaration instead of type inference. It's much longer. The 
clarity is tremendously reduced.

- return columns.index { (column, _) in column.lowercased() == lowercaseName }
+ return columns.index { (arg: (column: String, _)) in arg.column.lowercased() 
== lowercaseName }

> Yes, I understand that first syntax short and not verbose, but the 
> alternative you provided IMHO much worse than explicit type declaration in 
> closure.

It's not an "alternative": it's Swift 3.

Maybe you did already profit from it, but did not notice.

> 
>> Example 2 :
>> -.map { (mappedColumn, baseColumn) -> (Int, String) in
>> +.map { (pair) -> (Int, String) in
>> +let mappedColumn = pair.key
>> +let baseColumn = pair.value
> 
> Can't compile something like this even in Swift 3, could you provide a small 
> code snippet for this?

Sure:

let mapping: [String: String] = ...
mapping.map { (mappedColumn, baseColumn) -> (Int, String) in ... }

>> Example 3 :
>> -.map { (table, columns) in 
>> "\(table)(\(columns.sorted().joined(separator: ", ")))" }
>> +.map { "\($0.key)(\($0.value.sorted().joined(separator: ", 
>> ")))" }
> 
> Same, why not
> 
> .map { (arg: (table: String, columns: [String])) in 
> "\(arg.table)(\(arg.columns.sorted().joined(separator: ", ")))" }

Same answer: the extra `args` works, but we still have an ergonomics regression 
from Swift 3.

>> Example 4 :
>> -dictionary.first { (column, value) in column.lowercased() 
>> == orderedColumn.lowercased() }
>> +dictionary.first { $0.key.lowercased() == 
>> orderedColumn.lowercased() }
> 
> Same.

Indeed.

> 
>> See also messages from Stephen Cellis, who shows how other kinds of 
>> developer code has lost expressivity and clarity with those changes that 
>> have been "considered and approved".
> 
> Gwendal, no one saying that new syntax is better, that it is good thing that 
> we lost the short syntax for tuple argumment deconstructions in closures.

Good to hear :-)

> But there is just no easy/obvious way to keep that syntax in Swift 4. The 
> problem can't be solved just by not implementing SE-0110, as in Swift4 we 
> should have two separate function types: one that takes single tuple argument 
> and second that accepts a list of arguments, i.e. (Int,Int)->() and 
> ((Int,Int))->() should be two different types now.

Of course I understand that.

I expect the compiler to perform the expected conversions for ergonomics' sake.

I can understand that this sugar could be added *after* current problems which 
are not related to ergonomics are solved. I just want to make it clear that 
there is an ergonomics problem *now*, and that solving it should have a very 
high priority.

> This is not just SE-0110, this is also SE-0066, so, to be correct, you should 
> propose to revisit it also.
> 
> Please look here:
> 
> func foo(_ x: Int, _ y: Int) {} // type(of: foo) should be (Int, Int)->()
> func bar(_ x (Int, Int)) {} // type(of: bar) should be ((Int, Int))->()
> 
> The above is described in SE-0066. Then, you have a closure constants:
> 
> var fooClosure = {(x: Int, y: Int) in }
> var barClosure = {(x: (Int, Int)) in }
> 
> what should be types of these closures? Obvious the same: (Int,Int)->() and 
> ((Int,Int))->() respectively.

I guess you mean, not the same: (Int, Int) -> () vs. ((Int, Int)) -> ().

> Then you have a func that accepts ((Int,Int))->Int closure:
> 
> func schedule(callback: ((Int,Int))->()) {..}
> 
> , given type of foo func is (Int, Int)->() , do you suggest to allow sending 
> foo to 'schedule' func? The same question is for fooClosure
> 
> schedule(callback: foo) // ??
> schedule(callback: fooClosure) // ??

Yes, I do. For ergonomics' sake.

> Probably w

Re: [swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Matt Diephouse via swift-evolution
💯

> On Jun 7, 2017, at 10:35 AM, Adam Sharp via swift-evolution 
>  wrote:
> 
> The new smart key path feature is really lovely, and feels like a great 
> addition to Swift.
> 
> It seems like it might be straightforward to add overloads of `map` and 
> `flatMap` to the standard library to make use of the new functionality:
> 
>   let managers = flatOrganisation.managers
>   let allEmployees = Set(managers.flatMap(\.directReports))
>   let employeeNames = Set(allEmployees.map(\.name))
> 
> This feels like a really natural way of working with key paths in a 
> functional style. It makes a lot of sense for collections, and possibly for 
> Optional too (although as far as I can see optional chaining is more or less 
> equivalent, and with more compact syntax).
> 
> I’m hoping that this might be low-hanging fruit that could be considered for 
> the Swift 4 release. I’d be happy to have a go at writing a proposal if 
> there’s interest!
> 
> –Adam
> 
> ___
> 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: Support for map and flatMap with smart key paths

2017-06-07 Thread Víctor Pimentel Rodríguez via swift-evolution
On Wed, Jun 7, 2017 at 7:35 PM, Adam Sharp via swift-evolution <
swift-evolution@swift.org> wrote:

> The new smart key path feature is really lovely, and feels like a great
> addition to Swift.
>
> It seems like it might be straightforward to add overloads of `map` and
> `flatMap` to the standard library to make use of the new functionality:
>
> let managers = flatOrganisation.managers
> let allEmployees = Set(managers.flatMap(\.directReports))
> let employeeNames = Set(allEmployees.map(\.name))
>
> This feels like a really natural way of working with key paths in a
> functional style. It makes a lot of sense for collections, and possibly for
> Optional too (although as far as I can see optional chaining is more or
> less equivalent, and with more compact syntax).
>
> I’m hoping that this might be low-hanging fruit that could be considered
> for the Swift 4 release. I’d be happy to have a go at writing a proposal if
> there’s interest!
>
> –Adam
>

+1, it seems like a wonderful addition that would make a lot of code much
shorter.

-- 
Víctor Pimentel
___
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-07 Thread Víctor Pimentel Rodríguez via swift-evolution
On 7 Jun 2017, at 18:10, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

On Wed, Jun 7, 2017 at 10:03 Gwendal Roué  wrote:

> Le 7 juin 2017 à 15:52, Xiaodi Wu  a écrit :
>
> Let’s clarify: you just wrote that you have problems with SE-0029,
> SE-0066, SE-0110, and “before,” did you not?
>
>
> WTF? No I did not (citation below)!
>
> Le 7 juin 2017 à 15:02, Gwendal Roué  a écrit :
>
> Le 7 juin 2017 à 14:42, Vladimir.S  a écrit :
>
>
> Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066
> but mainly SE-0029 "Remove implicit tuple splat behavior from function
> applications"
> (https://github.com/apple/swift-evolution/blob/master/
> proposals/0029-remove-implicit-tuple-splat.md)
>
>
> Do you mean that the regressions Stephen and I have shown have been
> introduced not only by SE-0110, but before SE-0066, and SE-0029?
>
>
> Your attitude is obnoxious. Enough Swift evolution for me today.
>

Please refrain from personal attacks. Are we reading the same sentence? I
see that you literally listed three proposals (and “before”) and blamed
them for “regressions” that you want to reverse. If that’s not your
meaning, what do you mean?


In the conversation you can see that Vladimir stated that proposing to
revert this proposal would also mean reverting other previous proposals.

Gwendal is only asking back if the bug was introduced by the changesets
related to those proposals or by the changesets related to SE-0110.

Asking back is very different from blaming those proposals, or asking for
reversal of Swift 3 proposals. SE-0110 may be an obvious extension of the
proposed goal, but it is clear that it has been implemented in Swift 4, and
that the consequences are derived of those changesets.

Those "unwanted" consequences can be reverted by temporarily reverting
SE-0110, without touching any other previous proposal.

In no place I see Gwendal asking for full reversal of 5 proposals. He is
just voicing something that a lot of app developers and library maintainers
are not going to understand in September.

For example, you can see all the changes needed in RXSwift so that it
compiles to Swift 4:

https://github.com/ReactiveX/RxSwift/pull/1282/commits/915e00fa6d1e59d58cd8c38dd6dc83765fc67fe4

I would not want to migrate to Swift 4 an app using such framework.

I asked you in my first reply to you, is your view that the distinction
itself between (Int, Int) -> Int and ((Int, Int)) -> Int is problematic? If
so, this is a very different discussion from seeking solutions to mitigate
particular ergonomic issues that arise from the change. However, you have
not answered the question.


As far as I can see, the bigger usability regressions are caused when using
generics, specially in collections and functional utilities. When you
specify that type with a tuple, as in Dictionary, then all the related
methods start receiving closures receiving tuples.

Notice that allowing some syntactic sugar on the call site of those
closures may not be enough, since you may have stored or passed a closure
for customization purposes.

This behavior is so hurtful to functional style programming, that I think
either SE-0110 should be reverted, or alternatives like this Susan proposal
should be implemented. However, reverting may be safer and faster than
adding more new code to the compiler with such short time until Swift 4
release.

Of course that´s the Core team call, if the gains in the compiler code is
so great then we'll have to live with this regression. After WWDC I hope
that they notify their decision.

--
Víctor Pimentel
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Pitch: Support for map and flatMap with smart key paths

2017-06-07 Thread Adam Sharp via swift-evolution
The new smart key path feature is really lovely, and feels like a great 
addition to Swift.

It seems like it might be straightforward to add overloads of `map` and 
`flatMap` to the standard library to make use of the new functionality:

let managers = flatOrganisation.managers
let allEmployees = Set(managers.flatMap(\.directReports))
let employeeNames = Set(allEmployees.map(\.name))

This feels like a really natural way of working with key paths in a functional 
style. It makes a lot of sense for collections, and possibly for Optional too 
(although as far as I can see optional chaining is more or less equivalent, and 
with more compact syntax).

I’m hoping that this might be low-hanging fruit that could be considered for 
the Swift 4 release. I’d be happy to have a go at writing a proposal if there’s 
interest!

–Adam

___
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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 10:03 Gwendal Roué  wrote:

> Le 7 juin 2017 à 15:52, Xiaodi Wu  a écrit :
>
> Let’s clarify: you just wrote that you have problems with SE-0029,
> SE-0066, SE-0110, and “before,” did you not?
>
>
> WTF? No I did not (citation below)!
>
> Le 7 juin 2017 à 15:02, Gwendal Roué  a écrit :
>
> Le 7 juin 2017 à 14:42, Vladimir.S  a écrit :
>
>
> Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066
> but mainly SE-0029 "Remove implicit tuple splat behavior from function
> applications"
> (
> https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md
> )
>
>
> Do you mean that the regressions Stephen and I have shown have been
> introduced not only by SE-0110, but before SE-0066, and SE-0029?
>
>
> Your attitude is obnoxious. Enough Swift evolution for me today.
>

Please refrain from personal attacks. Are we reading the same sentence? I
see that you literally listed three proposals (and “before”) and blamed
them for “regressions” that you want to reverse. If that’s not your
meaning, what do you mean?

I asked you in my first reply to you, is your view that the distinction
itself between (Int, Int) -> Int and ((Int, Int)) -> Int is problematic? If
so, this is a very different discussion from seeking solutions to mitigate
particular ergonomic issues that arise from the change. However, you have
not answered the question.
___
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-07 Thread Vladimir.S via swift-evolution

On 07.06.2017 16:20, Gwendal Roué wrote:


Le 7 juin 2017 à 15:11, Xiaodi Wu > a écrit :


While SE-0025 was generally regarded as unfortunate, the thousands of emails that 
followed relitigating it were much, much worse.


The removal of implicit tuple splatting, which is *not* SE-0110, was approved on 
the understanding that it would be a regression until explicit tuple splatting is 
introduced. This tradeoff was considered and approved. It’s clear that you 
disagree, but that is not grounds to divert a necessary discussion on mitigating 
SE-0110 into relitigating something else.


Push me out if you want, but will you push out those blatant wounds out as well?

Example 1
-return columns.index { (column, _) in column.lowercased() == 
lowercaseName }
+return columns.index { $0.0.lowercased() == lowercaseName }


Why not
columns.index { (arg: (column: String, _: Int)) in arg.column.lowercased() == 
lowercaseName }

?

Yes, I understand that first syntax short and not verbose, but the alternative you 
provided IMHO much worse than explicit type declaration in closure.




Example 2 :
-.map { (mappedColumn, baseColumn) -> (Int, String) in
+.map { (pair) -> (Int, String) in
+let mappedColumn = pair.key
+let baseColumn = pair.value



Can't compile something like this even in Swift 3, could you provide a small code 
snippet for this?




Example 3 :
-.map { (table, 
columns) in "\(table)(\(columns.sorted().joined(separator: ", ")))" }

+.map { "\($0.key)(\($0.value.sorted().joined(separator: ", 
")))" }


Same, why not

.map { (arg: (table: String, columns: [String])) in 
"\(arg.table)(\(arg.columns.sorted().joined(separator: ", ")))" }





Example 4 :
-dictionary.first { (column, value) in column.lowercased() == 
orderedColumn.lowercased() }

+dictionary.first { $0.key.lowercased() == 
orderedColumn.lowercased() }



Same.

See also messages from Stephen Cellis, who shows how other kinds of developer code 
has lost expressivity and clarity with those changes that have been "considered and 
approved".




Gwendal, no one saying that new syntax is better, that it is good thing that we lost 
the short syntax for tuple argumment deconstructions in closures.


But there is just no easy/obvious way to keep that syntax in Swift 4. The problem 
can't be solved just by not implementing SE-0110, as in Swift4 we should have two 
separate function types: one that takes single tuple argument and second that accepts 
a list of arguments, i.e. (Int,Int)->() and ((Int,Int))->() should be two different 
types now.


This is not just SE-0110, this is also SE-0066, so, to be correct, you should propose 
to revisit it also.


Please look here:

func foo(_ x: Int, _ y: Int) {} // type(of: foo) should be (Int, Int)->()
func bar(_ x (Int, Int)) {} // type(of: bar) should be ((Int, Int))->()

The above is described in SE-0066. Then, you have a closure constants:

var fooClosure = {(x: Int, y: Int) in }
var barClosure = {(x: (Int, Int)) in }

what should be types of these closures? Obvious the same: (Int,Int)->() and 
((Int,Int))->() respectively.


Then you have a func that accepts ((Int,Int))->Int closure:

func schedule(callback: ((Int,Int))->()) {..}

, given type of foo func is (Int, Int)->() , do you suggest to allow sending foo to 
'schedule' func? The same question is for fooClosure


schedule(callback: foo) // ??
schedule(callback: fooClosure) // ??

Probably we can(if technically possible, I don't know) to always allow sending of 
function/closure with list of arguments when function with one tuple is required. I 
don't know how such exceptional rule would looks like inside type system of Swift, 
what should be result of 'foo is ((Int,Int))->()' then and 'type(of:foo) == 
type(of:bar)' in such case.
But this requires a formal proposal, review period and implementation(as I 
understand, better before Swift 4 release). Probably you can submit such proposal, go 
through the review period and help with implementation.
In this case we'll have the same user-friendly closure/function parameters expirience 
but with respect to correct function types.


But currently we have a situation: argument of type ((Int,Int))->() is required, and 
we provide argument of another type : (Int,Int)->() i.e. incorrect type.
The only obvious solution here is using the common rule for type mismatch - disallow 
this.


Currently we have a number of suggestions how we can improve usability for the 
discussed problem:


* use 'let' syntax in closure argument list to deconstruct tuple argument

* use doubled parenthesis to deconstruct tuple argument: { ((key, value)) in .. 
}

* generation of closure of correct type if closure is declared inside function call 
and arguments have no type annotations, i.e.

  //schedule(callback: foo) // disallowed, type mismatch
  //schedule(callback: fooClo

Re: [swift-evolution] [swift-users] Plan to move swift-evolution and swift-users mailing lists to Discourse

2017-06-07 Thread Charles Srstka via swift-evolution
> On Mar 20, 2017, at 11:39 AM, Jon Shier via swift-evolution 
>  wrote:
> 
>   So when is this transition happening? The sooner the better, as Mail 
> can’t really handle threads with large messages, like the recent evolution 
> threads about Foundation serialization and decoding. It just stops rendering 
> messages.

Huh, I figured I was the only one that happened to since the Radar I opened on 
that actually didn’t get marked as a duplicate (rdar://31137438 
). For me, it was worse than you describe; once I clicked on 
that thread, Mail would stop rendering messages from *any* thread, not just 
that one, and basically became non-functional until I quit the app and 
restarted it. The thread was quite the land mine, and I will admit to 
occasionally using some… colorful language after accidentally clicking on it.

Charles

___
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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 15:52, Xiaodi Wu  a écrit :
> 
> Let’s clarify: you just wrote that you have problems with SE-0029, SE-0066, 
> SE-0110, and “before,” did you not?

WTF? No I did not (citation below)!

> Le 7 juin 2017 à 15:02, Gwendal Roué  a écrit :
> 
>> Le 7 juin 2017 à 14:42, Vladimir.S > > a écrit :
>> 
>> Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066 but 
>> mainly SE-0029 "Remove implicit tuple splat behavior from function 
>> applications"
>> (https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md
>>  
>> )
> 
> Do you mean that the regressions Stephen and I have shown have been 
> introduced not only by SE-0110, but before SE-0066, and SE-0029?

Your attitude is obnoxious. Enough Swift evolution for me today.

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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 08:34 Gwendal Roué  wrote:

>
> Le 7 juin 2017 à 15:28, Xiaodi Wu  a écrit :
>
> These *are* changes related to SE-0110, and Chris and others have already
> proposed possibilities for sugar that could make this better. That’s
> exactly the discussion that was originally started, to be distinguished
> from the alternative in which you and others are proposing reversing 5 or 6
> other proposals.
>
>
> That's wrong.
>
> "I and others" have always been after ergonomics regressions, not
> "reversing 5 or 6 other proposals" (how dare you???)
>

Let’s clarify: you just wrote that you have problems with SE-0029, SE-0066,
SE-0110, and “before,” did you not? In addition, Stephen has just said he
disagrees with SE-0155 also, and I’ve outlined how arguments as tuples
impacts SE-0046. That’s five or more proposals by my count–so I should
apologize, it’s only four or more other proposals, not five or six.
___
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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 15:28, Xiaodi Wu  a écrit :
> 
> These *are* changes related to SE-0110, and Chris and others have already 
> proposed possibilities for sugar that could make this better. That’s exactly 
> the discussion that was originally started, to be distinguished from the 
> alternative in which you and others are proposing reversing 5 or 6 other 
> proposals.

That's wrong.

"I and others" have always been after ergonomics regressions, not "reversing 5 
or 6 other proposals" (how dare you???)

Gw

___
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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 08:20 Gwendal Roué  wrote:

>
> Le 7 juin 2017 à 15:11, Xiaodi Wu  a écrit :
>
> While SE-0025 was generally regarded as unfortunate, the thousands of
> emails that followed relitigating it were much, much worse.
>
> The removal of implicit tuple splatting, which is *not* SE-0110, was
> approved on the understanding that it would be a regression until explicit
> tuple splatting is introduced. This tradeoff was considered and approved.
> It’s clear that you disagree, but that is not grounds to divert a necessary
> discussion on mitigating SE-0110 into relitigating something else.
>
>
> Push me out if you want, but will you push out those blatant wounds out as
> well?
>
> Example 1
> -return columns.index { (column, _) in column.lowercased() ==
> lowercaseName }
> +return columns.index { $0.0.lowercased() == lowercaseName }
>
> Example 2 :
> -.map { (mappedColumn, baseColumn) -> (Int, String) in
> +.map { (pair) -> (Int, String) in
> +let mappedColumn = pair.key
> +let baseColumn = pair.value
>
> Example 3 :
> -.map { (table,
> columns) in "\(table)(\(columns.sorted().joined(separator: ", ")))" }
> +.map { "\($0.key)(\($0.value.sorted().joined(separator:
> ", ")))" }
>
> Example 4 :
> -dictionary.first { (column, value) in column.lowercased()
> == orderedColumn.lowercased() }
> +dictionary.first { $0.key.lowercased() ==
> orderedColumn.lowercased() }
>

These *are* changes related to SE-0110, and Chris and others have already
proposed possibilities for sugar that could make this better. That’s
exactly the discussion that was originally started, to be distinguished
from the alternative in which you and others are proposing reversing 5 or 6
other proposals.

See also messages from Stephen Cellis, who shows how other kinds of
> developer code has lost expressivity and clarity with those changes that
> have been "considered and approved".
>
> Cheers,
> 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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 15:11, Xiaodi Wu  a écrit :
> 
> While SE-0025 was generally regarded as unfortunate, the thousands of emails 
> that followed relitigating it were much, much worse.
> 
> The removal of implicit tuple splatting, which is *not* SE-0110, was approved 
> on the understanding that it would be a regression until explicit tuple 
> splatting is introduced. This tradeoff was considered and approved. It’s 
> clear that you disagree, but that is not grounds to divert a necessary 
> discussion on mitigating SE-0110 into relitigating something else.

Push me out if you want, but will you push out those blatant wounds out as well?

Example 1
-return columns.index { (column, _) in column.lowercased() == 
lowercaseName }
+return columns.index { $0.0.lowercased() == lowercaseName }

Example 2 :
-.map { (mappedColumn, baseColumn) -> (Int, String) in
+.map { (pair) -> (Int, String) in
+let mappedColumn = pair.key
+let baseColumn = pair.value

Example 3 :
-.map { (table, columns) in 
"\(table)(\(columns.sorted().joined(separator: ", ")))" }
+.map { "\($0.key)(\($0.value.sorted().joined(separator: ", 
")))" }

Example 4 :
-dictionary.first { (column, value) in column.lowercased() == 
orderedColumn.lowercased() }
+dictionary.first { $0.key.lowercased() == 
orderedColumn.lowercased() }

See also messages from Stephen Cellis, who shows how other kinds of developer 
code has lost expressivity and clarity with those changes that have been 
"considered and approved".

Cheers,
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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 08:02 Gwendal Roué via swift-evolution <
swift-evolution@swift.org> wrote:

> Le 7 juin 2017 à 14:42, Vladimir.S  a écrit :
>
> On 07.06.2017 14:18, Gwendal Roué via swift-evolution wrote:
>
> Xiaodi, Adrian, you are actively pushing so that something that was
> allowed, well compiled (no runtime issue), and covered actual uses cases,
> becomes forbidden. Without any developer advantage that would somehow
> balance the change.
> That's called a regression.
> And what's the rationale, already? A sense of compiler aesthetics? Since
> when a sense of compiler aesthetics is more valuable than a sense of code
> aesthetics? Aren't both supposed to walk together as a pair?
>
>
> Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066
> but mainly SE-0029 "Remove implicit tuple splat behavior from function
> applications"
> (
> https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md
> )
>
>
> Do you mean that the regressions Stephen and I have shown have been
> introduced not only by SE-0110, but before SE-0066, and SE-0029?
>
> We can discuss what sugar we can have to have tuple destructuring in
> closure and probably some sugar to allow free function of list of arguments
> when function of one tuple is required. But I don't see how we can
> revisit(and I believe we shouldn't) a number of actively discussed(!) and
> accepted proposals and dramatically change direction of Swift evolution
> even because of "lacks in terms of user ergonomics" for some period.
>
>
> I don't know. Nobody seemed to care about regressions, so I felt like it
> was high time some light was shed on them.
>
> Btw, please also note that this will not be possible in Swift 4:
> Probably this "feature" also was used in Swift 3 code, do we need to
> revisit it also? (I believe no)
>
>
> Writing "feature" with ironic quotes is a bad attitude. Some "features"
> are the quality of life of developers.
>
> When proposals are accepted without user feedback, it's reasonable to
> expect that users come back after the harm has been done. It has happened
> before, for fileprivate (SE-0025).
>

While SE-0025 was generally regarded as unfortunate, the thousands of
emails that followed relitigating it were much, much worse.

The removal of implicit tuple splatting, which is *not* SE-0110, was
approved on the understanding that it would be a regression until explicit
tuple splatting is introduced. This tradeoff was considered and approved.
It’s clear that you disagree, but that is not grounds to divert a necessary
discussion on mitigating SE-0110 into relitigating something else.

This is the case now. Some real bad harm to the language ergonomics has
> been done.
>
> Again, I'm not talking about inner compiler design: feel free to do
> whatever is reasonable for Swift and the community. But regressions.
>
> Gwendal
>
> ___
> 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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 14:42, Vladimir.S  a écrit :
> 
> On 07.06.2017 14:18, Gwendal Roué via swift-evolution wrote:
>> Xiaodi, Adrian, you are actively pushing so that something that was allowed, 
>> well compiled (no runtime issue), and covered actual uses cases, becomes 
>> forbidden. Without any developer advantage that would somehow balance the 
>> change.
>> That's called a regression.
>> And what's the rationale, already? A sense of compiler aesthetics? Since 
>> when a sense of compiler aesthetics is more valuable than a sense of code 
>> aesthetics? Aren't both supposed to walk together as a pair?
> 
> Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066 but 
> mainly SE-0029 "Remove implicit tuple splat behavior from function 
> applications"
> (https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md
>  
> )

Do you mean that the regressions Stephen and I have shown have been introduced 
not only by SE-0110, but before SE-0066, and SE-0029?

> We can discuss what sugar we can have to have tuple destructuring in closure 
> and probably some sugar to allow free function of list of arguments when 
> function of one tuple is required. But I don't see how we can revisit(and I 
> believe we shouldn't) a number of actively discussed(!) and accepted 
> proposals and dramatically change direction of Swift evolution even because 
> of "lacks in terms of user ergonomics" for some period.

I don't know. Nobody seemed to care about regressions, so I felt like it was 
high time some light was shed on them.

> Btw, please also note that this will not be possible in Swift 4:
> Probably this "feature" also was used in Swift 3 code, do we need to revisit 
> it also? (I believe no)

Writing "feature" with ironic quotes is a bad attitude. Some "features" are the 
quality of life of developers.

When proposals are accepted without user feedback, it's reasonable to expect 
that users come back after the harm has been done. It has happened before, for 
fileprivate (SE-0025). This is the case now. Some real bad harm to the language 
ergonomics has been done.

Again, I'm not talking about inner compiler design: feel free to do whatever is 
reasonable for Swift and the community. But regressions.

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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 07:40 Stephen Celis  wrote:

> > On Jun 7, 2017, at 8:27 AM, Xiaodi Wu  wrote:
> >
> > Swift package descriptions make extensive use of enums. For example,
> .target(...) is an enum case with an associated value, unless I’m mistaken.
> I too got the order of “dependencies” and “path” reversed the other day; if
> enum associated values were tuples, then it would not have mattered. I
> assume this is what you were referring to above.
>
> Enum associated values are isomorphic to tuples. Function arguments are
> also isomorphic to tuples. You're referring to a specific ordering issue
> that exists in both enum cases with multiple associated values, functions
> arguments (like a struct initializer), and tuples.


I’m not sure what you’re getting at. My point is that tuples currently
allow “shuffling” with labels but argument lists do not, and that enum
associated values were recently revised to be initialized with an argument
list and not a tuple, although that proposal is not fully implemented.

> An arbitrary argument list cannot be represented as a tuple. For example,
> tuples cannot have elements of variadic type or inout type.
>
> Modifiers like throws/inout/@escaping affect the body of the function and
> are arguably erasable in the data structure itself.


An early proposal moved the placement of inout to reflect the fact that
`inout T` is a distinct type from `T`. Escaping vs. non-escaping closures
also have type system significance, afaik; this is why
`withoutActuallyEscaping` required quite a bit of cleverness to implement
and cannot be expressed in Swift itself. In any case, the compiler itself
no longer represents argument lists as tuples, and that distinction is
fully plumbed through, unless I’m mistaken.

Variadic tuples are disallowed but not an impossible concept (and
> supporting them hasn't been ruled out as far as I can remember).
>
> > Slow, and especially inconsistently slow, performance fits the
> definition of unreliable, wouldn’t you agree?
>
> Again, trade-offs and openness to exploring better solutions.
>
> > They are not.
>
> Other than the function body modifiers, how are they not?


Literally, they are not the same, neither in syntax, nor in the way they
are modeled by the compiler.

Stephen
>
>
___
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-07 Thread Vladimir.S via swift-evolution

On 07.06.2017 14:18, Gwendal Roué via swift-evolution wrote:
Xiaodi, Adrian, you are actively pushing so that something that was allowed, well 
compiled (no runtime issue), and covered actual uses cases, becomes forbidden. 
Without any developer advantage that would somehow balance the change.


That's called a regression.

And what's the rationale, already? A sense of compiler aesthetics? Since when a sense 
of compiler aesthetics is more valuable than a sense of code aesthetics? Aren't both 
supposed to walk together as a pair?


Gwendal, again, you are proposing to revert not just SE-0110 and SE-0066 but mainly 
SE-0029 "Remove implicit tuple splat behavior from function applications"

(https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md)

Here is rationale for acceptance of this proposal:
(Joe Groff jgroff at apple.com)
(Wed Feb 10 11:51:16 CST 2016)

The review of "SE-0029 Remove implicit tuple splat behavior from function 
applications" ran from February 5...February 9, 2016. The proposal has been accepted 
for Swift 3. We acknowledge that we're removing a useful feature without providing an 
equally expressive drop-in replacement. However, maintaining this behavior in the 
type checker is a severe source of implementation complexity, and actively interferes 
with our plans to solidify the type system. We feel that removing the existing 
behavior is a necessary step toward stabilizing the language and toward building a 
well-designed alternative feature for explicit argument forwarding in the future.


(https://lists.swift.org/pipermail/swift-evolution-announce/2016-February/33.html)

We can discuss what sugar we can have to have tuple destructuring in closure and 
probably some sugar to allow free function of list of arguments when function of one 
tuple is required. But I don't see how we can revisit(and I believe we shouldn't) a 
number of actively discussed(!) and accepted proposals and dramatically change 
direction of Swift evolution even because of "lacks in terms of user ergonomics" for 
some period.



Btw, please also note that this will not be possible in Swift 4:
func f() {}
let c : ()->() = { v in print(v) }
c() // prints ()
f(print("fdsdf")) // executes print and then f()
, as function declared without parameters now can't accept even Void argument, 
function parenthesis is not empty tuple, as was allowed in Swift 3. Now you'll have 
these errors:


error: contextual closure type '() -> ()' expects 0 arguments, but 1 was used in 
closure body

let c : ()->() = { v in print(v) }
   ^
error: argument passed to call that takes no arguments
f(print("fdsdf"))
  ^~

Probably this "feature" also was used in Swift 3 code, do we need to revisit it also? 
(I believe no)




Gwendal

Le 7 juin 2017 à 12:54, Xiaodi Wu > a écrit :


IMO, if tuples and argument lists are to be distinguished in any way, it is 
imperative that f3(+) and f4(+), and some of your other examples, _not_ work.


After all, if a tuple is not an argument list, it should possible to have a 
function of type ((Int, Int)) -> Int and a function of type (Int, Int) -> Int share 
the same name (IIUC, it’s a known bug that this does not currently work). Quite 
simply, there’s a type mismatch if you pass sum1 to f3–what happens if there’s a 
distinct, overloaded sum1 that takes a single tuple?


Chris’s suggestion restores a syntactic convenience without touching the type 
system. What you are arguing for is essentially making ((Int, Int)) -> Int and 
(Int, Int) -> Int synonymous again, either in some or in all contexts.



On Wed, Jun 7, 2017 at 05:41 Gwendal Roué via swift-evolution 
mailto:swift-evolution@swift.org>> wrote:



Le 7 juin 2017 à 12:33, Gwendal Roué mailto:gwendal.r...@gmail.com>> a écrit :



Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution
mailto:swift-evolution@swift.org>> a écrit :

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



Despite Chris Lattern being a semi-god, his double-parenthesis suggestion
cruelly lacks in terms of user ergonomics. The compiler should be able to 
deal
with the following code snippet, just like Swift 3 does:

// two arguments
funcf1(_closure: (Int, Int) -> Int) { closure(1, 2) }
[...]


Here is the full extent of the remarquable Swift 3 ergonomics. This full
snippet compiles in Swift 3:

funcsum1(_lhs: Int, _rhs: Int) -> Int{ returnlhs + rhs }
funcsum2(lhs: Int, rhs: Int) -> Int{ returnlhs + rhs }
funcsum3(tuple: (Int, Int)) -> Int{ returntuple.0 + tuple.1 }
funcsum4(tuple: (lhs: Int, rhs: Int)) -> Int{ returntuple.lhs + tuple.rhs }

// two arguments
funcf1(_closure: (Int, Int) -> Int) { closure(1, 2) }
f1{ lhs, rhs inlhs + rhs }

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

2017-06-07 Thread Stephen Celis via swift-evolution
> On Jun 7, 2017, at 8:27 AM, Xiaodi Wu  wrote:
> 
> Swift package descriptions make extensive use of enums. For example, 
> .target(...) is an enum case with an associated value, unless I’m mistaken. I 
> too got the order of “dependencies” and “path” reversed the other day; if 
> enum associated values were tuples, then it would not have mattered. I assume 
> this is what you were referring to above.

Enum associated values are isomorphic to tuples. Function arguments are also 
isomorphic to tuples. You're referring to a specific ordering issue that exists 
in both enum cases with multiple associated values, functions arguments (like a 
struct initializer), and tuples.

> An arbitrary argument list cannot be represented as a tuple. For example, 
> tuples cannot have elements of variadic type or inout type.

Modifiers like throws/inout/@escaping affect the body of the function and are 
arguably erasable in the data structure itself.

Variadic tuples are disallowed but not an impossible concept (and supporting 
them hasn't been ruled out as far as I can remember).

> Slow, and especially inconsistently slow, performance fits the definition of 
> unreliable, wouldn’t you agree?

Again, trade-offs and openness to exploring better solutions.

> They are not.

Other than the function body modifiers, how are they not?

Stephen

___
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-07 Thread Adrian Zubarev via swift-evolution
I disagree it almost feels like a revert of SE–0110. If we had more than only:

parentheses
(angle) brackets
braces
A fifth set, that would also look visually fine with tuples. This discussion 
would not even exist, no matter if the data structure behind the scenes is the 
same or not. Parameter list should stay as a list of types for a closure, 
nothing more nothing less (it can be baked as a tuple behind the scenes, but 
that’s not the main discussion here).

( ❲ Int, Int ❳ ) -> Void

is different from

( Int, Int ) -> Void



-- 
Adrian Zubarev
Sent with Airmail

Am 7. Juni 2017 um 14:17:05, Stephen Celis via swift-evolution 
(swift-evolution@swift.org) schrieb:

Susan's proposal is an elegant step towards fixing some of the issues we've 
been having while specifically preventing previous ambiguities
___
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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 07:16 Stephen Celis  wrote:

> > On Jun 7, 2017, at 2:01 AM, Xiaodi Wu  wrote:
> >
> > Those are enums, which were aligned with argument lists instead of
> tuples in yet another proposal, SE-0155.
>
> Can you clarify? I wasn't referring to enums, and SE-0155 starts by
> talking about single enum cases with multiple associated values being
> represented by a tuple.


Swift package descriptions make extensive use of enums. For example,
.target(...) is an enum case with an associated value, unless I’m mistaken.
I too got the order of “dependencies” and “path” reversed the other day; if
enum associated values were tuples, then it would not have mattered. I
assume this is what you were referring to above.

The root values of tuples and structs are product types while enums are sum
> types. In general, anything with multiple configurable values at the same
> time are representable by tuples, and argument lists are no exception.


An arbitrary argument list cannot be represented as a tuple. For example,
tuples cannot have elements of variadic type or inout type.

> Having the compiler perform reliably is the most basic of user
> ergonomics, wouldn’t you say?
>
> Can you clarify what you mean by "reliably"? My understanding was the
> compiler performed reliably, but more slowly, with more tech debt.


Slow, and especially inconsistently slow, performance fits the definition
of unreliable, wouldn’t you agree?

Regardless, why not explore paths that improve both and aren't trade-offs?
>
> The separation of argument lists and tuples was approached in a very
> specific way to eliminate a very specific ambiguity, but the data
> structures are the same.


They are not.

Susan's proposal is an elegant step towards fixing some of the issues we've
> been having while specifically preventing previous ambiguities.
>
> Stephen
>
>
___
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-07 Thread Stephen Celis via swift-evolution
> On Jun 7, 2017, at 2:01 AM, Xiaodi Wu  wrote:
> 
> Those are enums, which were aligned with argument lists instead of tuples in 
> yet another proposal, SE-0155.

Can you clarify? I wasn't referring to enums, and SE-0155 starts by talking 
about single enum cases with multiple associated values being represented by a 
tuple.

The root values of tuples and structs are product types while enums are sum 
types. In general, anything with multiple configurable values at the same time 
are representable by tuples, and argument lists are no exception.

> Having the compiler perform reliably is the most basic of user ergonomics, 
> wouldn’t you say?

Can you clarify what you mean by "reliably"? My understanding was the compiler 
performed reliably, but more slowly, with more tech debt. Regardless, why not 
explore paths that improve both and aren't trade-offs?

The separation of argument lists and tuples was approached in a very specific 
way to eliminate a very specific ambiguity, but the data structures are the 
same. Susan's proposal is an elegant step towards fixing some of the issues 
we've been having while specifically preventing previous ambiguities.

Stephen

___
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-07 Thread Adrian Zubarev via swift-evolution
( /* two parameters, not a tuple */ (Int, Int) -> Void).self == (( /* one tuple 
parameter */ (Int, Int)) -> Void).self // BUG, which SE-0110 should have fixed, 
but still didn't

Plus inlined:

-- 
Adrian Zubarev
Sent with Airmail

Am 7. Juni 2017 um 13:53:08, Gwendal Roué (gwendal.r...@gmail.com) schrieb:

    func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
    func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
    func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
    func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs + 
tuple.rhs }

    // two arguments
    func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
Bug abuse:

    f1 { tuple in tuple.0 + tuple.1 }
    f1 { (tuple) in tuple.0 + tuple.1 }
    f1(sum3)
    f1(sum4)

`f2` is no different from `f1`.

Bugs, which should be fixed by `((lhs, rhs)) in`:

    // one tuple argument
    func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
    f3 { lhs, rhs in lhs + rhs }
    f3 { (lhs, rhs) in lhs + rhs }
Not possible because ultimately the closures have different types.

    f3(+)
    f3(sum1)
    f3(sum2)    
Bugs, which should be fixed by `((lhs, rhs)) in`:

    // one keyed tuple argument
    func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
    f4 { lhs, rhs in lhs + rhs }
    f4 { (lhs, rhs) in lhs + rhs }
Not possible because ultimately the closures have different types.

    f4(+)
    f4(sum1)
    f4(sum2)
Not sure, but I assume this shouldn’t be possible because tuple labels are part 
of the type and it’s a mismatch like `(lhs: Int, rhs: Int).Type != (a: Int, b: 
Int).Type`, therefore closures should be of different types as well.

    f4(sum4)





___
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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 13:28, Adrian Zubarev  a 
> écrit :
> 
>> Xiaodi, Adrian, you are actively pushing so that something that was allowed, 
>> well compiled (no runtime issue), and covered actual uses cases, becomes 
>> forbidden. Without any developer advantage that would somehow balance the 
>> change.
>> 
>> That's called a regression.
> 
> 
> func foo(_: (Int, Int)) {}
> func bar(_: Int, _: Int) {}
> 
> type(of: foo) == type(of: bar) //=> true - It's a BUG!

Then please push for the bug to be fixed. You are much better than am I at 
that. This does not mean breaking Swift 3 ergonomics.

The bug you mention involves type comparison, which is nowhere to be seen in 
the Swift 3 ergonomics checklist below. I'm sure we can all be happy.

func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs + 
tuple.rhs }

// two arguments
func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
f1 { lhs, rhs in lhs + rhs }
f1 { (lhs, rhs) in lhs + rhs }
f1 { tuple in tuple.0 + tuple.1 }
f1 { (tuple) in tuple.0 + tuple.1 }
f1(+)
f1(sum1)
f1(sum2)
f1(sum3)
f1(sum4)

// two arguments, with documentation names
func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
f2 { lhs, rhs in lhs + rhs }
f2 { (lhs, rhs) in lhs + rhs }
f2 { tuple in tuple.0 + tuple.1 }
f2 { (tuple) in tuple.0 + tuple.1 }
f2(+)
f2(sum1)
f2(sum2)
f2(sum3)
f2(sum4)

// one tuple argument
func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
f3 { lhs, rhs in lhs + rhs }
f3 { (lhs, rhs) in lhs + rhs }
f3 { tuple in tuple.0 + tuple.1 }
f3 { (tuple) in tuple.0 + tuple.1 }
f3(+)
f3(sum1)
f3(sum2)
f3(sum3)
f3(sum4)

// one keyed tuple argument
func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
f4 { lhs, rhs in lhs + rhs }
f4 { (lhs, rhs) in lhs + rhs }
f4 { tuple in tuple.a + tuple.b }
f4 { (tuple) in tuple.a + tuple.b }
f4(+)
f4(sum1)
f4(sum2)
f4(sum3)
f4(sum4)

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-07 Thread Xiaodi Wu via swift-evolution
On Wed, Jun 7, 2017 at 06:18 Gwendal Roué  wrote:

> Xiaodi, Adrian, you are actively pushing so that something that was
> allowed, well compiled (no runtime issue), and covered actual uses cases,
> becomes forbidden.
>

To be clear, I’m not pushing to forbid anything at all. SE-0110 prohibited
this a long time ago.

Without any developer advantage that would somehow balance the change.
>
> That's called a regression.
>
> And what's the rationale, already?
>

Surely, the time to ask that question was during review of SE-0110. Today’s
question is: how do we improve the user experience given that tuples and
argument lists are now distinct? Is your starting point that you reject
that conclusion altogether? If so, we’re simply having distinct discussions.

A sense of compiler aesthetics? Since when a sense of compiler aesthetics
> is more valuable than a sense of code aesthetics? Aren't both supposed to
> walk together as a pair?
>
> Gwendal
>
> Le 7 juin 2017 à 12:54, Xiaodi Wu  a écrit :
>
> IMO, if tuples and argument lists are to be distinguished in any way, it
> is imperative that f3(+) and f4(+), and some of your other examples, _not_
> work.
>
> After all, if a tuple is not an argument list, it should possible to have
> a function of type ((Int, Int)) -> Int and a function of type (Int, Int) ->
> Int share the same name (IIUC, it’s a known bug that this does not
> currently work). Quite simply, there’s a type mismatch if you pass sum1 to
> f3–what happens if there’s a distinct, overloaded sum1 that takes a single
> tuple?
>
> Chris’s suggestion restores a syntactic convenience without touching the
> type system. What you are arguing for is essentially making ((Int, Int)) ->
> Int and (Int, Int) -> Int synonymous again, either in some or in all
> contexts.
>
>
> On Wed, Jun 7, 2017 at 05:41 Gwendal Roué via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Le 7 juin 2017 à 12:33, Gwendal Roué  a écrit :
>>
>>
>> Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution <
>> swift-evolution@swift.org> a écrit :
>>
>> 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 }
>>
>>
>> Despite Chris Lattern being a semi-god, his double-parenthesis suggestion
>> cruelly lacks in terms of user ergonomics. The compiler should be able to
>> deal with the following code snippet, just like Swift 3 does:
>>
>> // two arguments
>> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
>>
>> [...]
>>
>>
>> Here is the full extent of the remarquable Swift 3 ergonomics. This full
>> snippet compiles in Swift 3:
>>
>> func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
>> func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
>> func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
>> func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs +
>> tuple.rhs }
>>
>> // two arguments
>> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
>> f1 { lhs, rhs in lhs + rhs }
>> f1 { (lhs, rhs) in lhs + rhs }
>> f1 { tuple in tuple.0 + tuple.1 }
>> f1 { (tuple) in tuple.0 + tuple.1 }
>> f1(+)
>> f1(sum1)
>> f1(sum2)
>> f1(sum3)
>> f1(sum4)
>>
>> // two arguments, with documentation names: identical
>> func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
>> f2 { lhs, rhs in lhs + rhs }
>> f2 { (lhs, rhs) in lhs + rhs }
>> f2 { tuple in tuple.0 + tuple.1 }
>> f2 { (tuple) in tuple.0 + tuple.1 }
>> f2(+)
>> f2(sum1)
>> f2(sum2)
>> f2(sum3)
>> f2(sum4)
>>
>> // one tuple argument
>> func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
>> f3 { lhs, rhs in lhs + rhs }
>> f3 { (lhs, rhs) in lhs + rhs }
>> f3 { tuple in tuple.0 + tuple.1 }
>> f3 { (tuple) in tuple.0 + tuple.1 }
>> f3(+)
>> f3(sum1)
>> f3(sum2)
>> f3(sum3)
>> f3(sum4)
>>
>> // one keyed tuple argument
>> func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b:
>> 2)) }
>> f4 { lhs, rhs in lhs + rhs }
>> f4 { (lhs, rhs) in lhs + rhs }
>> f4 { tuple in tuple.a + tuple.b }
>> f4 { (tuple) in tuple.a + tuple.b }
>> f4(+)
>> f4(sum1)
>> f4(sum2)
>> f4(sum3)
>> f4(sum4)
>>
>> Gwendal
>>
>> ___
>> 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-07 Thread Adrian Zubarev via swift-evolution


-- 
Adrian Zubarev
Sent with Airmail

Am 7. Juni 2017 um 13:18:22, Gwendal Roué (gwendal.r...@gmail.com) schrieb:

Xiaodi, Adrian, you are actively pushing so that something that was allowed, 
well compiled (no runtime issue), and covered actual uses cases, becomes 
forbidden. Without any developer advantage that would somehow balance the 
change.

That's called a regression.

func foo(_: (Int, Int)) {}
func bar(_: Int, _: Int) {}
type(of: foo) == type(of: bar) //=> true - It's a BUG!


And what's the rationale, already? A sense of compiler aesthetics? Since when a 
sense of compiler aesthetics is more valuable than a sense of code aesthetics? 
Aren't both supposed to walk together as a pair?

Gwendal

Le 7 juin 2017 à 12:54, Xiaodi Wu  a écrit :

IMO, if tuples and argument lists are to be distinguished in any way, it is 
imperative that f3(+) and f4(+), and some of your other examples, _not_ work.

After all, if a tuple is not an argument list, it should possible to have a 
function of type ((Int, Int)) -> Int and a function of type (Int, Int) -> Int 
share the same name (IIUC, it’s a known bug that this does not currently work). 
Quite simply, there’s a type mismatch if you pass sum1 to f3–what happens if 
there’s a distinct, overloaded sum1 that takes a single tuple?

Chris’s suggestion restores a syntactic convenience without touching the type 
system. What you are arguing for is essentially making ((Int, Int)) -> Int and 
(Int, Int) -> Int synonymous again, either in some or in all contexts.


On Wed, Jun 7, 2017 at 05:41 Gwendal Roué via swift-evolution 
 wrote:
Le 7 juin 2017 à 12:33, Gwendal Roué  a écrit :


Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution 
 a écrit :

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 }


Despite Chris Lattern being a semi-god, his double-parenthesis suggestion 
cruelly lacks in terms of user ergonomics. The compiler should be able to deal 
with the following code snippet, just like Swift 3 does:

    // two arguments
    func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
[...]

Here is the full extent of the remarquable Swift 3 ergonomics. This full 
snippet compiles in Swift 3:

    func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
    func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
    func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
    func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs + 
tuple.rhs }

    // two arguments
    func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
    f1 { lhs, rhs in lhs + rhs }
    f1 { (lhs, rhs) in lhs + rhs }
    f1 { tuple in tuple.0 + tuple.1 }
    f1 { (tuple) in tuple.0 + tuple.1 }
    f1(+)
    f1(sum1)
    f1(sum2)
    f1(sum3)
    f1(sum4)
    
    // two arguments, with documentation names: identical
    func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
    f2 { lhs, rhs in lhs + rhs }
    f2 { (lhs, rhs) in lhs + rhs }
    f2 { tuple in tuple.0 + tuple.1 }
    f2 { (tuple) in tuple.0 + tuple.1 }
    f2(+)
    f2(sum1)
    f2(sum2)
    f2(sum3)
    f2(sum4)
    
    // one tuple argument
    func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
    f3 { lhs, rhs in lhs + rhs }
    f3 { (lhs, rhs) in lhs + rhs }
    f3 { tuple in tuple.0 + tuple.1 }
    f3 { (tuple) in tuple.0 + tuple.1 }
    f3(+)
    f3(sum1)
    f3(sum2)
    f3(sum3)
    f3(sum4)
    
    // one keyed tuple argument
    func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
    f4 { lhs, rhs in lhs + rhs }
    f4 { (lhs, rhs) in lhs + rhs }
    f4 { tuple in tuple.a + tuple.b }
    f4 { (tuple) in tuple.a + tuple.b }
    f4(+)
    f4(sum1)
    f4(sum2)
    f4(sum3)
    f4(sum4)

Gwendal

___
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-07 Thread Gwendal Roué via swift-evolution
Xiaodi, Adrian, you are actively pushing so that something that was allowed, 
well compiled (no runtime issue), and covered actual uses cases, becomes 
forbidden. Without any developer advantage that would somehow balance the 
change.

That's called a regression.

And what's the rationale, already? A sense of compiler aesthetics? Since when a 
sense of compiler aesthetics is more valuable than a sense of code aesthetics? 
Aren't both supposed to walk together as a pair?

Gwendal

> Le 7 juin 2017 à 12:54, Xiaodi Wu  a écrit :
> 
> IMO, if tuples and argument lists are to be distinguished in any way, it is 
> imperative that f3(+) and f4(+), and some of your other examples, _not_ work.
> 
> After all, if a tuple is not an argument list, it should possible to have a 
> function of type ((Int, Int)) -> Int and a function of type (Int, Int) -> Int 
> share the same name (IIUC, it’s a known bug that this does not currently 
> work). Quite simply, there’s a type mismatch if you pass sum1 to f3–what 
> happens if there’s a distinct, overloaded sum1 that takes a single tuple?
> 
> Chris’s suggestion restores a syntactic convenience without touching the type 
> system. What you are arguing for is essentially making ((Int, Int)) -> Int 
> and (Int, Int) -> Int synonymous again, either in some or in all contexts.
> 
> 
> On Wed, Jun 7, 2017 at 05:41 Gwendal Roué via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>> Le 7 juin 2017 à 12:33, Gwendal Roué > > a écrit :
>> 
>> 
>>> Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution 
>>> mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> 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 }
>>> 
>> 
>> Despite Chris Lattern being a semi-god, his double-parenthesis suggestion 
>> cruelly lacks in terms of user ergonomics. The compiler should be able to 
>> deal with the following code snippet, just like Swift 3 does:
>> 
>> // two arguments
>> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
> 
>> [...]
> 
> Here is the full extent of the remarquable Swift 3 ergonomics. This full 
> snippet compiles in Swift 3:
> 
> func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
> func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
> func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
> func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs + 
> tuple.rhs }
> 
> // two arguments
> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
> f1 { lhs, rhs in lhs + rhs }
> f1 { (lhs, rhs) in lhs + rhs }
> f1 { tuple in tuple.0 + tuple.1 }
> f1 { (tuple) in tuple.0 + tuple.1 }
> f1(+)
> f1(sum1)
> f1(sum2)
> f1(sum3)
> f1(sum4)
> 
> // two arguments, with documentation names: identical
> func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
> f2 { lhs, rhs in lhs + rhs }
> f2 { (lhs, rhs) in lhs + rhs }
> f2 { tuple in tuple.0 + tuple.1 }
> f2 { (tuple) in tuple.0 + tuple.1 }
> f2(+)
> f2(sum1)
> f2(sum2)
> f2(sum3)
> f2(sum4)
> 
> // one tuple argument
> func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
> f3 { lhs, rhs in lhs + rhs }
> f3 { (lhs, rhs) in lhs + rhs }
> f3 { tuple in tuple.0 + tuple.1 }
> f3 { (tuple) in tuple.0 + tuple.1 }
> f3(+)
> f3(sum1)
> f3(sum2)
> f3(sum3)
> f3(sum4)
> 
> // one keyed tuple argument
> func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
> f4 { lhs, rhs in lhs + rhs }
> f4 { (lhs, rhs) in lhs + rhs }
> f4 { tuple in tuple.a + tuple.b }
> f4 { (tuple) in tuple.a + tuple.b }
> f4(+)
> f4(sum1)
> f4(sum2)
> f4(sum3)
> f4(sum4)
> 
> Gwendal
> 
> ___
> 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] Plan to move swift-evolution and swift-users mailing lists to Discourse

2017-06-07 Thread Adrian Zubarev via swift-evolution
Any update to this? I was hoping for a global announcement at WWDC to attract 
more folks to join the discussions, but this didn’t happen.



-- 
Adrian Zubarev
Sent with Airmail

Am 10. Februar 2017 um 07:11:34, Bouke Haarsma via swift-evolution 
(swift-evolution@swift.org) schrieb:

A big +1 for Discourse from me as well. I don't want to sign up to the  
mailing list and have mailbox overflow. I did have rules put in place  
to move the messages in a separate folder, but still the amount wasn't  
manageable. Furthermore reading the threads in Mail.app is a major pain  
as a result of different quotation styles used by various authors.

Currently I use gmane.org's nntp servers and the outdated Unison.app.  
However that app also doesn't support the various quotation styles,  
which doesn't help with following topics. I'd be very happy to use  
Discourse, as it allows me to opt-in to any discussion I'd like and  
start/stop e-mail notifications as I see fit. Also Github Issues would  
allow me to do that, but I can see the benefits Discourse would  
provide; e.g. better moderation, pinning topics for recurring topics  
and ownership of the forum's data (threads).

-Bouke


___
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-07 Thread Xiaodi Wu via swift-evolution
IMO, if tuples and argument lists are to be distinguished in any way, it is
imperative that f3(+) and f4(+), and some of your other examples, _not_
work.

After all, if a tuple is not an argument list, it should possible to have a
function of type ((Int, Int)) -> Int and a function of type (Int, Int) ->
Int share the same name (IIUC, it’s a known bug that this does not
currently work). Quite simply, there’s a type mismatch if you pass sum1 to
f3–what happens if there’s a distinct, overloaded sum1 that takes a single
tuple?

Chris’s suggestion restores a syntactic convenience without touching the
type system. What you are arguing for is essentially making ((Int, Int)) ->
Int and (Int, Int) -> Int synonymous again, either in some or in all
contexts.


On Wed, Jun 7, 2017 at 05:41 Gwendal Roué via swift-evolution <
swift-evolution@swift.org> wrote:

> Le 7 juin 2017 à 12:33, Gwendal Roué  a écrit :
>
>
> Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution <
> swift-evolution@swift.org> a écrit :
>
> 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 }
>
>
> Despite Chris Lattern being a semi-god, his double-parenthesis suggestion
> cruelly lacks in terms of user ergonomics. The compiler should be able to
> deal with the following code snippet, just like Swift 3 does:
>
> // two arguments
> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
>
> [...]
>
>
> Here is the full extent of the remarquable Swift 3 ergonomics. This full
> snippet compiles in Swift 3:
>
> func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
> func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
> func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
> func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs +
> tuple.rhs }
>
> // two arguments
> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
> f1 { lhs, rhs in lhs + rhs }
> f1 { (lhs, rhs) in lhs + rhs }
> f1 { tuple in tuple.0 + tuple.1 }
> f1 { (tuple) in tuple.0 + tuple.1 }
> f1(+)
> f1(sum1)
> f1(sum2)
> f1(sum3)
> f1(sum4)
>
>
> // two arguments, with documentation names: identical
> func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
> f2 { lhs, rhs in lhs + rhs }
> f2 { (lhs, rhs) in lhs + rhs }
> f2 { tuple in tuple.0 + tuple.1 }
> f2 { (tuple) in tuple.0 + tuple.1 }
> f2(+)
> f2(sum1)
> f2(sum2)
> f2(sum3)
> f2(sum4)
>
>
> // one tuple argument
> func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
> f3 { lhs, rhs in lhs + rhs }
> f3 { (lhs, rhs) in lhs + rhs }
> f3 { tuple in tuple.0 + tuple.1 }
> f3 { (tuple) in tuple.0 + tuple.1 }
> f3(+)
> f3(sum1)
> f3(sum2)
> f3(sum3)
> f3(sum4)
>
>
> // one keyed tuple argument
> func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2))
> }
> f4 { lhs, rhs in lhs + rhs }
> f4 { (lhs, rhs) in lhs + rhs }
> f4 { tuple in tuple.a + tuple.b }
> f4 { (tuple) in tuple.a + tuple.b }
> f4(+)
> f4(sum1)
> f4(sum2)
> f4(sum3)
> f4(sum4)
>
> Gwendal
>
> ___
> 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-07 Thread Adrian Zubarev via swift-evolution

Answer inlined:
Am 7. Juni 2017 um 12:33:51, Gwendal Roué (gwendal.r...@gmail.com) schrieb:


Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution 
 a écrit :

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 }


Despite Chris Lattern being a semi-god, his double-parenthesis suggestion 
cruelly lacks in terms of user ergonomics. 
Well it’s clearly not the ideal solution from a visual perspective but it’s an 
unambiguous one. If tuples were represented differently, let’s say `@(a, b)` we 
wouldn’t sit here and debate that long because it becomes crystal clear what 
should be possible and what not.



The compiler should be able to deal with the following code snippet, just like 
Swift 3 does:

    // two arguments
    func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
    f1 { lhs, rhs in lhs + rhs }
    f1 { (lhs, rhs) in lhs + rhs }
Next one is a bug to me:


    f1 { tuple in tuple.0 + tuple.1 }
Fine:


    f1(+)
    
    // two arguments, with documentation names
    func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
    f2 { lhs, rhs in lhs + rhs }
    f2 { (lhs, rhs) in lhs + rhs }
Another bug to me:


    f2 { tuple in tuple.0 + tuple.1 }
Fine:


    f2(+)
    
    // one tuple argument
    func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
Should be `((lhs, rhs)) in` which eliminates both of the next two scenarios 
completely:


    f3 { lhs, rhs in lhs + rhs }
    f3 { (lhs, rhs) in lhs + rhs }
Fine:


    f3 { tuple in tuple.0 + tuple.1 }
Should be an error:


    f3(+)
See `f3`


    
    // one keyed tuple argument
    func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
    f4 { lhs, rhs in lhs + rhs }
    f4 { (lhs, rhs) in lhs + rhs }
    f4 { tuple in tuple.a + tuple.b }
    f4(+)

This covers the Swift 3 regressions developped by Stephen Celis and I, unless I 
have missed any. And this should be the goal of the designers of this language, 
*regardless of the actual types*. Developers are olding their breath: please 
just make this happen.

Now Swift 3 may have an issue with $n parameters. Here is my suggestion, should 
`((Int, Int)) -> Int` be different from `(Int, Int) -> Int`:


That’s what I would expect.

    f1 { $0 + $1 } // OK
    f1 { $0.0 + $0.1 } // OK in Swift 3, compiler error in Swift 4?
    
    f2 { $0 + $1 } // OK
    f2 { $0.0 + $0.1 } // OK in Swift 3, compiler error in Swift 4?
    
    f3 { $0 + $1 } // OK in Swift 3, compiler error in Swift 4?
    f3 { $0.0 + $0.1 } // OK
    
    f4 { $0 + $1 } // OK in Swift 3, compiler error in Swift 4?
    f4 { $0.a + $0.b } // OK

Gwendal Roué


These rules should as strict as they possible can be now. Later on we can add 
sugar to relax some of them. Here is a quote, again from Chris Lattner:

The art of evolving Swift forward is to carefully pick and choose areas to 
focus on, both because we want to ensure a coherent language, but also because 
implementor bandwidth is limited.

Beyond that, though syntactic sugar is always motivated by strong rationale and 
use-cases, in my opinion, it is the most dangerous kind of additive feature to 
consider at this point of Swift’s evolution. While these features are useful, 
they also clearly add complexity to the language, and it is difficult to gauge 
whether the problem being addressed will even exist in Swift as the other 
bigger features come in (for example, a macro system). These features can also 
make future language evolution more problematic because they consume syntactic 
real estate in the language.

If you’re into analogies, I see features like the generics improvements, 
ownership model, concurrency model, macro system, new frameworks, and other 
large scale efforts as the “bricks" that make up the house of Swift. In that 
analogy, syntactic sugar proposals are “mortar” that fills in the cracks 
between the bricks. If we add too much mortar too early on, we run the risk of 
the house of Swift being built out of mortar, or of not being able to fit the 
bricks into the right places. That would be very bad, given that we all want 
the house of Swift to be strong and beautiful over the long term.

-Chris 
___
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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 12:33, Gwendal Roué  a écrit :
> 
> 
>> Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution 
>> mailto:swift-evolution@swift.org>> a écrit :
>> 
>> 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 }
>> 
> 
> Despite Chris Lattern being a semi-god, his double-parenthesis suggestion 
> cruelly lacks in terms of user ergonomics. The compiler should be able to 
> deal with the following code snippet, just like Swift 3 does:
> 
> // two arguments
> func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
> [...]

Here is the full extent of the remarquable Swift 3 ergonomics. This full 
snippet compiles in Swift 3:

func sum1(_ lhs: Int, _ rhs: Int) -> Int { return lhs + rhs }
func sum2(lhs: Int, rhs: Int) -> Int { return lhs + rhs }
func sum3(tuple: (Int, Int)) -> Int { return tuple.0 + tuple.1 }
func sum4(tuple: (lhs: Int, rhs: Int)) -> Int { return tuple.lhs + 
tuple.rhs }

// two arguments
func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
f1 { lhs, rhs in lhs + rhs }
f1 { (lhs, rhs) in lhs + rhs }
f1 { tuple in tuple.0 + tuple.1 }
f1 { (tuple) in tuple.0 + tuple.1 }
f1(+)
f1(sum1)
f1(sum2)
f1(sum3)
f1(sum4)

// two arguments, with documentation names: identical
func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
f2 { lhs, rhs in lhs + rhs }
f2 { (lhs, rhs) in lhs + rhs }
f2 { tuple in tuple.0 + tuple.1 }
f2 { (tuple) in tuple.0 + tuple.1 }
f2(+)
f2(sum1)
f2(sum2)
f2(sum3)
f2(sum4)

// one tuple argument
func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
f3 { lhs, rhs in lhs + rhs }
f3 { (lhs, rhs) in lhs + rhs }
f3 { tuple in tuple.0 + tuple.1 }
f3 { (tuple) in tuple.0 + tuple.1 }
f3(+)
f3(sum1)
f3(sum2)
f3(sum3)
f3(sum4)

// one keyed tuple argument
func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
f4 { lhs, rhs in lhs + rhs }
f4 { (lhs, rhs) in lhs + rhs }
f4 { tuple in tuple.a + tuple.b }
f4 { (tuple) in tuple.a + tuple.b }
f4(+)
f4(sum1)
f4(sum2)
f4(sum3)
f4(sum4)

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-07 Thread Adrian Zubarev via swift-evolution
Well I’m clearly against this, it doesn’t hurt to use some more paeans inside a 
closure to tell the compiler if you want to destructure a tuple or use a single 
argument for the whole tuple.



-- 
Adrian Zubarev
Sent with Airmail

Am 7. Juni 2017 um 12:31:47, Susan Cheng (susan.dog...@gmail.com) schrieb:

`((Int, Int)) -> Void` will be same type as `(Int, Int) -> Void`

2017-06-07 18:09 GMT+08:00 Adrian Zubarev :
Keep in mind there is also SE–0111 cometary which promises sugar for parameter 
labels for closures:

// **
let foo(tuple:): ((Int, Int)) -> Void

// Sugar for **
let foo: (tuple: (Int, Int)) -> Void
What will happen if you’d always flatten here?



-- 
Adrian Zubarev
Sent with Airmail

Am 7. Juni 2017 um 12:03:08, Adrian Zubarev (adrian.zuba...@devandartist.com) 
schrieb:

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 }

That’s a correct error:

let fn3: (Int, Int) -> Void = { _ in }
This should be allowed, because we might want to work with the whole tuple and 
not a desctructured elements only:

let fn4: ((Int, Int)) -> Void = { tuple in }


-- 
Adrian Zubarev
Sent with Airmail

___
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-07 Thread Gwendal Roué via swift-evolution

> Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution 
>  a écrit :
> 
> 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 }
> 

Despite Chris Lattern being a semi-god, his double-parenthesis suggestion 
cruelly lacks in terms of user ergonomics. The compiler should be able to deal 
with the following code snippet, just like Swift 3 does:

// two arguments
func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
f1 { lhs, rhs in lhs + rhs }
f1 { (lhs, rhs) in lhs + rhs }
f1 { tuple in tuple.0 + tuple.1 }
f1(+)

// two arguments, with documentation names
func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
f2 { lhs, rhs in lhs + rhs }
f2 { (lhs, rhs) in lhs + rhs }
f2 { tuple in tuple.0 + tuple.1 }
f2(+)

// one tuple argument
func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
f3 { lhs, rhs in lhs + rhs }
f3 { (lhs, rhs) in lhs + rhs }
f3 { tuple in tuple.0 + tuple.1 }
f3(+)

// one keyed tuple argument
func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
f4 { lhs, rhs in lhs + rhs }
f4 { (lhs, rhs) in lhs + rhs }
f4 { tuple in tuple.a + tuple.b }
f4(+)

This covers the Swift 3 regressions developped by Stephen Celis and I, unless I 
have missed any. And this should be the goal of the designers of this language, 
*regardless of the actual types*. Developers are olding their breath: please 
just make this happen.

Now Swift 3 may have an issue with $n parameters. Here is my suggestion, should 
`((Int, Int)) -> Int` be different from `(Int, Int) -> Int`:

f1 { $0 + $1 } // OK
f1 { $0.0 + $0.1 } // OK in Swift 3, compiler error in Swift 4?

f2 { $0 + $1 } // OK
f2 { $0.0 + $0.1 } // OK in Swift 3, compiler error in Swift 4?

f3 { $0 + $1 } // OK in Swift 3, compiler error in Swift 4?
f3 { $0.0 + $0.1 } // OK

f4 { $0 + $1 } // OK in Swift 3, compiler error in Swift 4?
f4 { $0.a + $0.b } // OK

Gwendal Roué

___
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-07 Thread Susan Cheng via swift-evolution
`((Int, Int)) -> Void` will be same type as `(Int, Int) -> Void`

2017-06-07 18:09 GMT+08:00 Adrian Zubarev :

> Keep in mind there is also SE–0111 cometary which promises sugar for
> parameter labels for closures:
>
> // **
> let foo(tuple:): ((Int, Int)) -> Void
>
> // Sugar for **
> let foo: (tuple: (Int, Int)) -> Void
>
> What will happen if you’d always flatten here?
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 7. Juni 2017 um 12:03:08, Adrian Zubarev (adrian.zubarev@devandartist.
> com) schrieb:
>
> 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 }
>
> That’s a correct error:
>
> let fn3: (Int, Int) -> Void = { _ in }
>
> This should be allowed, because we might want to work with the whole tuple
> and not a desctructured elements only:
>
> let fn4: ((Int, Int)) -> Void = { tuple in }
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
>
___
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-07 Thread Susan Cheng via swift-evolution
Replacement for fn4 is just make a tuple inside the closure

let workWithTuple: (Int, Int) -> Void = { doSomething(withTuple: ($0, $1)) }

2017-06-07 18:03 GMT+08:00 Adrian Zubarev :

> 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 }
>
> That’s a correct error:
>
> let fn3: (Int, Int) -> Void = { _ in }
>
> This should be allowed, because we might want to work with the whole tuple
> and not a desctructured elements only:
>
> let fn4: ((Int, Int)) -> Void = { tuple in }
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
>
___
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-07 Thread Adrian Zubarev via swift-evolution
Keep in mind there is also SE–0111 cometary which promises sugar for parameter 
labels for closures:

// **
let foo(tuple:): ((Int, Int)) -> Void

// Sugar for **
let foo: (tuple: (Int, Int)) -> Void
What will happen if you’d always flatten here?



-- 
Adrian Zubarev
Sent with Airmail

Am 7. Juni 2017 um 12:03:08, Adrian Zubarev (adrian.zuba...@devandartist.com) 
schrieb:

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 }

That’s a correct error:

let fn3: (Int, Int) -> Void = { _ in }
This should be allowed, because we might want to work with the whole tuple and 
not a desctructured elements only:

let fn4: ((Int, Int)) -> Void = { tuple in }


-- 
Adrian Zubarev
Sent with Airmail
___
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-07 Thread Adrian Zubarev via swift-evolution
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 }

That’s a correct error:

let fn3: (Int, Int) -> Void = { _ in }
This should be allowed, because we might want to work with the whole tuple and 
not a desctructured elements only:

let fn4: ((Int, Int)) -> Void = { tuple in }


-- 
Adrian Zubarev
Sent with Airmail
___
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-07 Thread Susan Cheng via swift-evolution
Argument lists should or shouldn't be tuples. I think the question likes a
concept more than a technical question.

2017-06-07 14:56 GMT+08:00 Xiaodi Wu :

> On Wed, Jun 7, 2017 at 01:51 Susan Cheng  wrote:
>
>> I don't think it's a roll back change.
>>
>
> Function argument lists were once tuples, but they have not been for many
> years. All of the proposals I listed above proceed on the basis that these
> are not the same. Your proposal says that function argument lists should be
> tuples: that is rolling back a >5 year old change, is it not?
>
> The proposal is not proposing allow to reorder the parameters by using the
>> tuple or implicit tuple splat to fit the function parameters.
>> It's just clarify the relationship of tuples and argument lists.
>>
>> as the grammar of Swift 3, it's allowed wrapping the argument with a
>> single tuple to a function with two argument.
>>
>> [(1, 2)].map(+)
>>
>> and SE-0110 is the proposal make the distinguished and not allowed this
>> line of code.
>>
>> although we fix the compiler to accept the destructuring of tuples
>>
>> [(1, 2)].map({ ((lhs, rhs)) in lhs + rhs })
>>
>> it's not accepting the code of [(1, 2)].map(+) which the operator + are
>> not function with accepting the tuple of two elements.
>>
>> the only way we can thought is that the arguments with single tuple is
>> flattened and it's most compatible with Swift 3.
>>
>> 2017-06-07 13:05 GMT+08:00 Xiaodi Wu :
>>
>>> This is not what was meant during discussion about re-evaluating
>>> SE-0110. Tuples already behave as described, but function argument lists
>>> are not tuples and have not been for a very long time: see SE-0029, SE-0066.
>>>
>>> Also, consider SE-0046, which makes possible labels in single-argument
>>> argument lists (not possible in tuples), and SE-0060, which prohibits
>>> arbitrary reordering (although still possible in tuples). This is to say
>>> that the whole direction of Swift since version 2 has been to erase the
>>> historical relationship between tuples and argument lists.
>>>
>>> The question is how to accommodate some common use cases for
>>> destructuring as a matter of syntactic sugar after having carefully
>>> distinguished argument lists and tuples in the compiler, which is a given,
>>> not how to roll back a change that was settled in 2011, by Chris’s telling.
>>>
>>> On Tue, Jun 6, 2017 at 23:14 Susan Cheng via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>

 func add2(_ pair: (Int, Int)) -> Int {
 return pair.0 + pair.1
 }

 consider the follows

 let _add2 =  add2 // add2 have the typeof `((Int, Int)) -> Int`,
 it should flatten to `(Int, Int) -> Int`

 so these two lines are also acceptable
 [(1, 2)].map(add1)
 [(1, 2)].map(add2)

 this proposal is not just changing the behaviour of closure, this
 proposal also changing the tuple type

 (((Int, Int)))   flatten to   (Int, Int)
 (Int, (((Int, Int))), Int)   flatten to   (Int, (Int, Int), Int)


 2017-06-07 12:03 GMT+08:00 Stephen Celis :

> The inline cases make sense to me, but my concern for ambiguity are
> because we can define both of these functions:
>
> func add1(_ x: Int, _ y: Int) -> Int {
>   return x + y
> }
> func add2(_ pair: (Int, Int)) -> Int {
>   return pair.0 + pair.1
> }
>
> // What's the behavior here?
> [(1, 2)].map(add1)
> [(1, 2)].map(add2)
>
> What comes to mind, though, is, Swift already prevents single-element
> tuples, so why not prevent functions that take a single tuple as the only
> argument?
>
> Swift could provide a fix-it for functions that take single tuples and
> say: "Swift functions cannot take a single tuple. Please write a function
> that takes as many arguments as the tuple specified."
>
> Considering the fact that Swift generally operates in a multi-argument
> world, and given that functions taking a single tuple are the minority, I
> think this would be a good way to move forward.
>
> Stephen
>
> > On Jun 6, 2017, at 11:21 PM, Susan Cheng 
> wrote:
> >
> >  [(1, 2)].map({ x, y in x + y })  // this line is correct
> >  [(1, 2)].map({ tuple in tuple.0 + tuple.1 })  // this line should
> not accepted
> >
> > or
> >
> >  [(1, 2)].map({ $0 + $1 })  // this line is correct
> >  [(1, 2)].map({ $0.0 + $0.1 })  // this line should not accepted
> >
> > it's because `((Int, Int)) -> Int` always flatten to `(Int, Int) ->
> Int`
> > so, it should only accept the function with two arguments
> >
> >
> >
> > 2017-06-07 11:07 GMT+08:00 Stephen Celis :
> > I like this a lot, but how do we solve for the function case?
> >
> > func add(_ x: Int, _ y: Int) -> Int {
> >   return x + y
> > }
> > [(1, 2)].map(add)
> >
> > Wh