<div dir="ltr">If I correctly understand the proposal, I&#39;m -1 on this. <div><br></div><div>(1) You can define different methods with the same name on T and Optional&lt;T&gt; (description is such an example). Then what does this do?<div><br></div><div>// someMethod is defined both for T and T?</div><div>// var foo: T?</div><div>if foo != nil {</div><div>    foo.someMethod()</div><div>}</div><div><br></div><div>I say there is a clear expectation that foo.someMethod() should call the method of T?, even inside the if block, since this is how the dot works. However, according to the proposal it will call another method (or become an error?).<br></div><div><div><br></div></div></div><div>I think the languages that use optional narrowing are the ones where T? is not a separate type, so that it cannot have its own methods.</div><div><br></div><div>(2) Should this work?</div><div><br></div><div>// compilcatedStuff is a method of T</div><div><div>// class A { var foo: T? }</div><div><br></div><div>if foo != nil {</div><div>    foo.compilcatedStuff()</div><div>    foo.compilcatedStuff()</div><div><div>    foo.compilcatedStuff()</div><div>}<br></div></div><div><br></div></div><div>Suppose the compiler doesn&#39;t have enough information about compilcatedStuff to know what happens inside. Then it&#39;s possible that foo.compilcatedStuff will actually change foo (for example, foo could be a relationship and compilcatedStuff may be deleting the relationship). So, what is the suggestion for this example? Perhaps</div><div><br></div><div><div>if foo != nil {</div><div>    foo.compilcatedStuff()</div><div>    foo?.compilcatedStuff()</div><div>    foo?.compilcatedStuff()</div><div>}</div><div><br></div></div><div>or some other choice?</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Nov 8, 2016 at 9:44 AM Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On 7 Nov 2016, at 19:31, Charlie Monroe &lt;<a href="mailto:charlie@charliemonroe.net" class="gmail_msg" target="_blank">charlie@charliemonroe.net</a>&gt; wrote:</div><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">There are two cases:</div><div class="gmail_msg"><br class="gmail_msg"></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">if foo != nil { </font></div><div class="gmail_msg"><font face="Menlo" class="gmail_msg">    foo!.doSomething() </font></div><div class="gmail_msg"><font face="Menlo" class="gmail_msg">}</font></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Currently, accessing a non-optional value with ! produces an error:</div><div class="gmail_msg"><br class="gmail_msg"></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">let foo = Bar()</font></div><div class="gmail_msg"><font face="Menlo" class="gmail_msg">foo!.doSomething() // ERROR</font></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Second:</div><div class="gmail_msg"><br class="gmail_msg"></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">if foo != nil { </font></div></div><div class="gmail_msg"><font face="Menlo" class="gmail_msg">    </font><span style="font-family:Menlo" class="gmail_msg">// Using ? to be extra cautious, if foo is var</span></div><div class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">    foo?.doSomething() </font></div></div><div class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">}</font></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">This again currently produces an error:</div><div class="gmail_msg"><br class="gmail_msg"></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">let foo = Bar()</font></div></div><div class="gmail_msg"><div class="gmail_msg"><font face="Menlo" class="gmail_msg">foo?.doSomething() // ERROR</font></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Which is generally, what would semantically happen - the variable would loose it optionality. Or am I wrong?</div></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I probably haven&#39;t clarified well enough but under type-narrowing these would be warnings rather than errors; i.e- the general type of foo is still Optional, the type-checker merely knows that it can&#39;t be nil at that point, so would inform you that the ? or ! are unnecessary.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">This is what I was trying to get at in the type-widening section; basically, if you have a variable whose type is narrowed, but do something that makes no sense for the narrowed type, then the type is widened until either a match is found or it can&#39;t go any wider (producing an error as normal).</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">So in your examples foo is Optional&lt;Bar&gt;.some, as a result the ? and ! operators make no sense, so the type is widened back to Optional&lt;Bar&gt; where it does make sense and the code compiles, but a warning is produced to inform you that you don&#39;t need to use those operators.</div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On 7 Nov 2016, at 19:31, Charlie Monroe &lt;<a href="mailto:charlie@charliemonroe.net" class="gmail_msg" target="_blank">charlie@charliemonroe.net</a>&gt; wrote:</div><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I agree that designing a language around the compiler speed is wrong, but I believe designing the language without taking it into account is just as wrong. It&#39;s not worth designing features that would make the compilation so slow it would render the language unusable.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Note that I have only very limited experience with compiler implementation, I&#39;ve only made a few minor things with Clang a few years back, so please feel free to correct me.</div></div></div></div></blockquote><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">I&#39;m not that familiar with the actual architecture either, but narrowing *should* be fairly simple; basically any time the compiler hits a condition or statement defined as a narrowing trigger, it pops the new narrower type onto a stack of types for that variable (in that branch). Now whenever the compiler reaches another statement for that variable (method call etc.) it resolves it first against the narrowest type, otherwise it goes up the stack (widening) till it finds a match or fails.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">When a branch closes with a stack of types, the compiler will compare to other branches to see which type is the narrowest that they have in common; this is actually fairly simple (shorten the stack for each branch to the length of the shortest stack, then discard elements until the current one is a match for all branches, thus you now know what the narrowest type is past that point).</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">So, for types that never narrow there should be no speed difference, while for narrowed types there shouldn&#39;t be much of a difference, as these stacks of types shouldn&#39;t get very large in most cases (I&#39;d expect anything more than three to be pretty rare).</div></div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>