<div dir="ltr">I keep seeing the argument brought up that "allowing implicit self can lead to hard to find bugs," but no one seems to be mentioning the bugs it helps avoid. To me, it's not a tradeoff between boilerplate and bugs; it's a tradeoff between one type of hard to find bug and another type of hard to find bug. Let me share my own experience on both sides to clarify.<div><br></div><div>In Objective-C, self was always required, so I never encountered the hard-to-find shadowing bugs discussed in this list. However, because self was required everywhere, I had nothing to help me realize that using self in a block captured self and potentially created retain cycles. These bugs are (for me) some of the hardest to track down because memory leaks aren't a problem until they are, and then all of a sudden potentially months of bad practice in this area can come back to bite you all at once. And maybe I'm just an Instruments noob, but tracking down the leak and the source of the retain cycle was always a _huge_ pain.</div><div><br></div><div>Then we switched to Swift, and our team quickly adopted (and enforced through code review) the code style where self is only allowed where it is required. By getting in the habit of never using self, every time we write code in a closure that implicitly captured self, the compiler would yell at us. We learned to interpret these yells as a warning to think about memory inside that closure, and the result has been far fewer retain-cycle bugs.</div><div><br></div><div>And, to be honest, in all my time using Swift (I've been writing in it pretty much exclusively since its beta days), I can't recall a shadowing bug that has given me much trouble at all.</div><div><br></div><div>So, for me (and I think I can speak for others I've worked with who also love the reminder from the compiler to think about memory), readability doesn't even really factor into this proposal. This proposal is mainly about sacrificing help with avoiding very-hard-to-find bugs in retain cycles for the sake of making easier-to-find bugs with shadowing less likely. That is an obvious loss in my experience, and I'm hoping this proposal won't be taken seriously until there is an alternate way for the compiler to warn me about retain cycles.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 16, 2015 at 9:20 AM, James Dempsey via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">>> I think the mandatory self problem is analogous to never wanting to use x!, as! or try!. If you restrict yourself to always using self.whatever, it is not unusual to someone else, and if they leave off the compiler flag or pragma that enforces this, the code will still compile.<br>
<br>
</span>I think there is a fundamental difference between code that does / does not use x! as! or try! and code that may or may not require the use of self.<br>
<br>
Even if you do not use x! as! or try! in your own code, you can easily read and understand code that does use those features.<br>
<br>
But if you choose to enforce using self in your own code, suddenly you need to read and reason about code in two different ways.<br>
<br>
In ‘mandatory self’ code, you can assume self is always being used and you cannot accidentally use something in local scope by mistake. The ‘mandatory self’ removes a set of potential bugs you need to check for when reading code. But when you encounter ’non enforced self’ code, you can’t make those assumptions and you need to check for those issues.<br>
<br>
For me, choosing not to use x! as! or try! in your code is like choosing not to use swear words when you speak. You easily understand them when someone else uses them, but you choose not to.<br>
<br>
Being able to choose ‘mandatory self’ or not is more like a dialect. For each dialect you need to adjust your mental model of how the language works.<br>
<br>
Overall, I am +1 for the proposal of making self mandatory because I find the lack of 'mandatory self' makes the code less readable, less explicit as to intent and can also introduce subtle bugs.<br>
<br>
If it comes down to adding some sort of switch or not I am -1 for that because that does seem like the creation of two dialects of the language.<br>
<br>
James<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
> On Dec 15, 2015, at 9:54 PM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
><br>
><br>
>> On Dec 15, 2015, at 8:10 PM, Kenny Leung via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
>><br>
>> This is the full text of what Chris said in regard to “Proposal: Add Flags to Disable [Optional] Conversions"<br>
>><br>
>>> I don’t like the idea of having different incompatible dialects, and behavior changing modes. That said, I’m personally not opposed to providing functionality that would enable people to use a reduced subsets of the language, and have the compiler enforce it. For example, I don’t have a problem with someone saying they never want to use the x!, as!, try! family and have the compiler tell them if they do.<br>
>>><br>
>>> To relate this to your question, I’d be fine with functionality that causes the compiler to produce an error when code requires an implicit conversion, but I wouldn’t want them to be just “disabled”, because I think this could change the interpretation of valid swift code (in admittedly weird cases).<br>
>>><br>
>>> In terms of how to express this, I’m not in love with modal compiler flags :-). I’d much rather this sort of requirement be specified as a pragma-like construct that applies to an arbitrary scope (e.g. class or function body) or a whole file. This keeps the code self describing.<br>
>><br>
>> I think the mandatory self problem is analogous to never wanting to use x!, as! or try!. If you restrict yourself to always using self.whatever, it is not unusual to someone else, and if they leave off the compiler flag or pragma that enforces this, the code will still compile.<br>
><br>
> I agree with you.<br>
><br>
> -Chris<br>
> _______________________________________________<br>
> swift-evolution mailing list<br>
> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br></div>