On 07.06.2017 16:20, Gwendal Roué wrote:
Le 7 juin 2017 à 15:11, Xiaodi Wu <xiaodi...@gmail.com
<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 }
?
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: fooClosure) // disallowed, type mismatch
// allowed. compiler will generate closure of type ((Int,Int))->() from this
code
schedule { x,y in }
// type mismatch, this syntax defines closure of (Int,Int)->() type
//schedule { (x: Int, y: Int) in }
But because all of this are additional features that can be added later, and each
required to be reviewed/discussed in details, core team can decide to delay such
'fix' for after-release period. Let's wait and see what core team had to say about
this subject.
Cheers,
Gwendal
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution