[swift-evolution] Revisiting SE-0110

rintaro ishizaki fs.output at gmail.com
Mon Jun 5 02:03:24 CDT 2017


2017-06-05 2:16 GMT+09:00 Chris Lattner via swift-evolution <
swift-evolution at swift.org>:

>
> On Jun 1, 2017, at 3:06 PM, John McCall via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>
> On Jun 1, 2017, at 2:39 PM, Pavol Vaskovic <pali at pali.sk> wrote:
>
> On Thu, Jun 1, 2017 at 8:52 PM, John McCall via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> I understand that there are developers who dislike SE-0110's impact on
>> certain kinds of functional programming, but that is a very broad complaint
>> that is unlikely to reach consensus or acceptance, especially for Swift 4.
>
>
> The impact of SE-0110 as currently implemented in Swift 4 leads to
> following migration choice wherever you have a closure that takes tuple
> argument:
> * concise but obfuscate code ($0.1, ...)
> * readable but verbose code (requiring a ton of boilerplate: intermediate
> argument, expand signature to include return type, desctructure tuple on
> new line using let, add return clause)
>
> Maybe I misunderstood you, but I don't think this is marginal issue
> affecting only some "developers that dislike the impact on certain kinds of
> functional programming".
>
>
> You're misunderstanding me.  I have explicitly said, several times, that I
> agree that the impact on tuple destructuring in closures is a serious
> regression.  There have *also* been objections to losing argument-splat
> behavior, and while that does negatively affect some functional styles, I
> think it would be a mistake to try to address that now.
>
>
> I agree with both points: we need to fix the type checker
> semantics+performance regression, but I also sympathize with the beauty
> regression for closures.  Here are some the examples Gwendal Roué cited
> up-thread (just to make the discussion concrete):
>
> 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() }
>
>
>
>
> One way to split the difference here is to eliminate the splatting
> behavior, but keep the destructuring (irrefutable pattern matching)
> behavior as well.  In these cases, just require an extra explicit paren for
> the parameter list.  This would change the diff's to:
>
> Example 1
> -        return columns.index { (column, _) in column.lowercased() ==
> lowercaseName }
> +       return columns.index { ((column, _)) in column.lowercased() ==
> lowercaseName }
>
> Example 2 :
> -            .map { (mappedColumn, baseColumn) -> (Int, String) in
> +            .map { ((mappedColumn, baseColumn)) -> (Int, String) in
>
> Example 3 :
> -                .map { (table, columns) in "\(table)(\(columns.sorted().joined(separator:
> ", ")))" }
> +                .map { ((table, columns)) in "\(table)(\(columns.sorted().joined(separator:
> ", ")))" }
>
> Example 4 :
> -                dictionary.first { (column, value) in
> column.lowercased() == orderedColumn.lowercased() }
> +                dictionary.first { ((column, value)) in
> column.lowercased() == orderedColumn.lowercased() }
>
>
> What do you think?  Seems like it would solve the type checker problem,
> uglify the code a lot less, and make the fixit/migration happily trivial.
>
>
+1.

Migration path would be a little less simple if the parameter clause has
type annotations:

-    let fn: Int = { (v: String, k: Int) in
+    let fn: Int = { ((v, k): (String, Int)) in

Also, if we accept patterns for closure parameters, we probably don't want
to accept '...' for them.

let fn = { ((_, v): (Int, String)...) -> Int in



> -Chris
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170605/2e497035/attachment.html>


More information about the swift-evolution mailing list