Deprecating Trailing Closures

    let foo = myArray
        .filter { $0 & 1 == 1 }
        .map { $0 + 1 }
        .reduce(0) { $0 + $1 }

This doesn’t really seem much neater or more readable to me than:

  let foo = myArray
    .filter({ $0 & 1 == 1 })
    .map({ $0 + 1 })
    .reduce(0, { $0 + $1 })

I, on the other hand, cannot imagine how you would not see a difference between the two. The paren-less form is *far* more readable to me; when you put a parenthesis and a curly bracket next to each other, the curly bracket disappears and I can no longer see that the expression is a closure.

Swift generally doesn't mandate any particular style. I think this is a good time to continue that tradition.

···

--
Brent Royal-Gordon
Architechies

Agreed.

···

Sent from my iPhone

On Mar 25, 2016, at 07:44, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

   let foo = myArray
       .filter { $0 & 1 == 1 }
       .map { $0 + 1 }
       .reduce(0) { $0 + $1 }

This doesn’t really seem much neater or more readable to me than:

   let foo = myArray
       .filter({ $0 & 1 == 1 })
       .map({ $0 + 1 })
       .reduce(0, { $0 + $1 })

I, on the other hand, cannot imagine how you would not see a difference between the two. The paren-less form is *far* more readable to me; when you put a parenthesis and a curly bracket next to each other, the curly bracket disappears and I can no longer see that the expression is a closure.

Swift generally doesn't mandate any particular style. I think this is a good time to continue that tradition.

--
Brent Royal-Gordon
Architechies

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

On the other hand, I find the addition of the parenthesis makes it less readable than the one without. So please don't assume that what is equally readable for you applies to everyone else.

Alex

···

On 25 Mar 2016, at 08:10, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

On 24 Mar 2016, at 21:08, Howard Lovatt <howard.lovatt@gmail.com> wrote:

I use trailing closures all the time because I find the brackets too noisy, like ; at the end of a line is too noisy. The sort of code I use is:

    let foo = myArray
        .filter { $0 & 1 == 1 }
        .map { $0 + 1 }
        .reduce(0) { $0 + $1 }

This doesn’t really seem much neater or more readable to me than:

  let foo = myArray
    .filter({ $0 & 1 == 1 })
    .map({ $0 + 1 })
    .reduce(0, { $0 + $1 })

While they may add a small amount of noise, in the latter case the parenthesis clarifies that each is a method, and what all of its arguments are, and don’t use any custom syntax. Of course this assumes that .reduce() would have an optional label on its closure argument.

Following a style rule is just like using a linter. It's not language mandated and I have not argued for enforcement.

-- E

···

On Mar 31, 2016, at 5:56 AM, Radosław Pietruszewski <radexpl@gmail.com> wrote:

I follow the "Rule of Kevin", which is not language enforced. Parens around functional
closures (->T), not around procedural (->Void) ones. This promotes "language construct"-like
Void calls, avoids compiler parsing issues when chaining (or using "guard", "if", etc). It lets
me know instantly how the closure is used.

While I was originally reluctant to adopt it, its advantages have become self-evident over time.
This ends up being slightly wordier, especially in the few cases you need to use argument labels.

I think it's worth it.

I don’t follow the Rule of Kevin myself, although I’m not against it either, and I see why some people would like it.

But, if we’re going to have trailing closures at all (which seems desirable for creating things that look like language features), enforcement based on syntactic preference doesn’t make sense to me.

This really reminds me of a “remove implicit self” discussion. Some people (me included) were against, because they disliked the noisiness of “self” everywhere. Others argued that the implicitness is somewhat unsafe. A valid position to take. But it’s a kind of thing teams can use a linter for, if they want to enforce it as a rule.

Trailing closures seem like a similar thing. We could remove it altogether (although I think that would be a shame), or let’s just leave it up to preference (and developing guidelines) on where to use them.

Best,
— Radek

I don’t see how trailing closures, or lack thereof, is special enough to enforce like that. I mean, you could say that about so many features. Should we even allow “init?” and leave it up to personal preference, if only later will developers consider if it’s actually a good idea and they shouldn’t use “init throws”?

I’d be sad to see trailing closures go, but it’s a reasonable proposal to make. However, enforcing usage of trailing closures (a mainly stylistic choice that doesn’t even have the same safety concerns as the “remove implicit self” discussion) seems pointless.

— Radek

···

On 24 Mar 2016, at 18:57, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

That’s a pretty good rule, and I think it’s what I’m now doing myself as well. Any thoughts on whether it should be enforced, though?
There’s a thread currently about allowing trailing closures within guard etc., but personally I think that that’s a bad idea, and that it may actually be better to head in the opposite direction (use them less), but currently it’s an automatic feature which I’m not sure is a good thing.

Given your “Rule of Kevin” we could have the a rule for closures as a last parameter that if they have a non-Void return type, they must add a new @trailing attribute, otherwise trailing is implied.

I realise there’s an argument to be made that it should just be up to linters or personal preference, but I’m concerned that many developers like myself will use trailing closures everywhere they’re permitted because it seems like the right thing to do, and only later start to consider whether it’s a good idea to actually use them in specific cases. But for consistency’s sake I’d say it’s not good to use them except for language construct type calls (like .forEach actually, which I always forget about too), which is where the main advantage lies.
_______________________________________________

   let foo = myArray
       .filter { $0 & 1 == 1 }
       .map { $0 + 1 }
       .reduce(0) { $0 + $1 }

This doesn’t really seem much neater or more readable to me than:

   let foo = myArray
       .filter({ $0 & 1 == 1 })
       .map({ $0 + 1 })
       .reduce(0, { $0 + $1 })

I, on the other hand, cannot imagine how you would not see a difference between the two. The paren-less form is *far* more readable to me; when you put a parenthesis and a curly bracket next to each other, the curly bracket disappears and I can no longer see that the expression is a closure.

Same for me!

Swift generally doesn't mandate any particular style. I think this is a good time to continue that tradition.

Indeed.

-Thorsten

···

Am 25.03.2016 um 13:44 schrieb Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org>:

Apologies, I didn’t mean to suggest you argued for enforcement. Just adding my 2¢ about why enforcement makes no sense to me.

Best,
— Radek

···

On 31 Mar 2016, at 16:08, Erica Sadun <erica@ericasadun.com> wrote:

On Mar 31, 2016, at 5:56 AM, Radosław Pietruszewski <radexpl@gmail.com <mailto:radexpl@gmail.com>> wrote:

I follow the "Rule of Kevin", which is not language enforced. Parens around functional
closures (->T), not around procedural (->Void) ones. This promotes "language construct"-like
Void calls, avoids compiler parsing issues when chaining (or using "guard", "if", etc). It lets
me know instantly how the closure is used.

While I was originally reluctant to adopt it, its advantages have become self-evident over time.
This ends up being slightly wordier, especially in the few cases you need to use argument labels.

I think it's worth it.

I don’t follow the Rule of Kevin myself, although I’m not against it either, and I see why some people would like it.

But, if we’re going to have trailing closures at all (which seems desirable for creating things that look like language features), enforcement based on syntactic preference doesn’t make sense to me.

This really reminds me of a “remove implicit self” discussion. Some people (me included) were against, because they disliked the noisiness of “self” everywhere. Others argued that the implicitness is somewhat unsafe. A valid position to take. But it’s a kind of thing teams can use a linter for, if they want to enforce it as a rule.

Trailing closures seem like a similar thing. We could remove it altogether (although I think that would be a shame), or let’s just leave it up to preference (and developing guidelines) on where to use them.

Best,
— Radek

Following a style rule is just like using a linter. It's not language mandated and I have not argued for enforcement.

-- E