Sent from my iPad
> On May 22, 2016, at 11:33 AM, Pyry Jahkola via swift-evolution > <[email protected]> wrote: > > >> On 22 May 2016, David Hart wrote: >> >> If the design team is very serious about not integrating optional warnings, >> then I don’t think it is a huge bother to implement think in linters like >> SwiftLint is doing. > > I'm fine with the way SE-0009 was decided but I think the review left one > consideration for linters unexplored: How to be explicit about what's > captured by a closure if the coding style enforced by a linter involves using > `self.` everywhere? > > There were (are) basically two reasons for keeping `self.` implicit the way > it is: > > Reason 1. It keeps noise level down. E.g. computed properties often read > better this way: > > var area: Double { > return width * height > // rather than: 'self.width * self.height' > } > > Reason 2. It makes the capturing of `self` explicit, because `self.` is only > required in escaping closures and thus the capturing expressions require > thinking when writing code and also stand out when reading code. > > I think those are good reasons. But then, the language rules don't really > favour the other coding style where the `self.` prefix is used throughout, > even if it *can* be enforced by a linter: > > Example 1. There's no other way (but using the `self.` prefix) to indicate > that `self` should be retained by a closure: > > self.prepareWork() > queue.async { [self] in > // ^ > // error: Expected 'weak', 'unowned', or no > // specifier in capture list > self.doTheWork() > } > > Example 2. There's currently no way to mark when an escaping closure is > intended to **not** capture any other references but those explicitly listed: > > queue.async { [bar] in > if bar.isAdjustable { > baz.adjust() > } > } > // Meant 'bar', but compiler didn't alert! > > So I think it would be a good idea to adjust the capture list syntax a bit: > > Suggestion 1. Allow capture lists to explicitly state that they capture > `self` strongly by spelling it out with no weak/unowned specifier, i.e. > `[self]`. > > Suggestion 2. Add a succinct way to indicate that the capture list is > *comprehensive*, i.e. that implicitly capturing other variables from the > local scope is an error. (Capturing variables from the file scope should be > allowed though, I reckon.) The syntax for this could be e.g. postfixing the > capture list brackets with the exclamation mark `!`: > > queue.async { [service]! in > service.handleTask(self.task) > // ^ > // error: Implicit capture of 'self' in closure > } > queue.async { [service, self]! in > service.execute(self.task) // ok > } > queue.async { [service, task = self.task]! in > service.execute(task) // also ok; didn't capture 'self' > } > queue.async { [bar]! in > if bar.isAdjustable { > baz.adjust() > // ^ > // error: Implicit capture of 'baz' in closure > } > } > > With these two changes, the coding style choice of what to use the `self.` > prefix for would be better supported both ways, and no optional warnings > would be needed. A linter could then require capturing `self` explicitly > where it's used inside an escaping block. Myself, I wouldn't use > comprehensive capture lists all the time but there have been a few cases > where it would've been useful to prevent mistakenly capturing anything that > could create a retain cycle. > > Any thoughts? Would an idea like this help any of the people who started this > mailing list thread—that is, with the aid of a respectively configured linter > of course? +1. I like both ideas (and don't like mandating style). One other thing that might be nice is a plugin mechanism for the build system that provides a standard interface for linters / style checkers and allows them to emit style "warnings" (ideally integrated with Xcode). > > — Pyry > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
