<div dir="ltr">On Tue, May 23, 2017 at 5:36 AM, Haravikk <span dir="ltr">&lt;<a href="mailto:swift-evolution@haravikk.me" target="_blank">swift-evolution@haravikk.me</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>This is getting too muddled, so I&#39;m going to summarise thusly; I believe the principle the OP raised is sound, that any initialiser performing a lossy conversion from another type should be clear that this happening, and that a label can do that best, as it makes the conversion self-documenting at the call-site.</div></div></blockquote><div><br></div><div>This is a much wider claim that any advanced in the conversation previously. Swift documentation refers to `init(_:)` as the &quot;default initializer.&quot; If I understand you, you are arguing that _any default initializer must be value-preserving (monomorphic)_. This is plainly not the current standard. For example, the following is a default conversion but not a monomorphic conversion because multiple different arrays yield the same resulting set:</div><div><br></div><div>```</div><div>let x = Set([1, 2, 3, 4, 3, 2, 1])</div><div><br></div><div>// x: Set&lt;Int&gt; = {</div><div>//  [0] = 2</div><div>//  [1] = 3</div><div>//  [2] = 1</div><div>//  [3] = 4</div><div>// }</div><div>```</div><div><br></div><div>Much has been quoted from the Swift API guidelines. The language in that document is fairly terse: it gives guidelines in imperative form (e.g., &quot;Omit useless words&quot;) with some follow-on suggestions worded more softly. The strong guideline is that value-preserving (monomorphic) initializers should omit the label. Notably, it is _not_ the other way around: that is, it does _not_ require that all initializers omitting the label are value-preserving. Now, there _is_ a &quot;recommend[ation]&quot; to distinguish non-value-preserving initializers by a label. During the discussion on this list about that recommendation, IIRC, the gist was that this is geared toward situations where some conversions from type A to type B are lossy and others are not; in that case, a label should be provided for the lossy conversion(s) so that users don&#39;t use it when they mean to use the lossless conversion.</div><div><br></div><div>In the example of array-to-set conversion, there is _no possible non-failable monomorphic conversion_ from array to set; however, there is an accepted default lossy way to make the conversion, and therefore the default initializer adopts that behavior and does not need to announce that it is lossy. Likewise, there is _no possible non-failable monomorphic conversion_ from floating point to integer; however, there is an accepted default lossy way to make the conversion (it is an LLVM intrinsic), and therefore the default initializer adopts that behavior and does not need to announce that it is lossy.</div><div><br></div><div>Now, if you want to argue that you in particular do not accept that the LLVM intrinsic is the default lossy way to convert from floating point to integer, or that it is highly confusing, here&#39;s the place for that discussion. But you&#39;re now arguing (IIUC) that regardless of how accepted the default behavior is, if it is not lossless then it must be spelled with a label, and that is plainly not the current convention in Swift.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>Consider for example; with type-inference it&#39;s not always obvious what the type of a variable is, and an unlabelled initialiser does nothing to help, like-so:</div><div><br></div><div><font face="Monaco"><span class="gmail-m_-5196468749934338947Apple-tab-span" style="white-space:pre-wrap">        </span>var someValue = someMethod()</font></div><div><font face="Monaco"><span class="gmail-m_-5196468749934338947Apple-tab-span" style="white-space:pre-wrap">        </span>…</font></div><div><font face="Monaco"><span class="gmail-m_-5196468749934338947Apple-tab-span" style="white-space:pre-wrap">        </span>var someInt = Int(someValue)</font></div><div><br></div><div>At a glance it&#39;s not all obvious what is happening to someValue here; in fact I&#39;d argue that this looks like a lossless conversion, requiring you to find out that someMethod() returns a Float before you can know for sure what&#39;s really going on.</div></div></blockquote><div><br></div><div>Again, this is based on the claim that _only_ lossless conversions use unlabeled initializers. You express the opinion that it _should_ be the case above, but as I have already replied, it is factually _not_ the case currently. That is, for an arbitrary pair of types A and B:</div><div><br></div><div>```</div><div>let x = A()</div><div>let y = B(x) // There is _no guarantee_ that this is lossless.</div><div>```</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>Whereas the following is more clear:</div><div><br></div><div><font face="Monaco"><span class="gmail-m_-5196468749934338947Apple-tab-span" style="white-space:pre-wrap">        </span>var someValue = someMethod()</font></div><div><font face="Monaco"><span class="gmail-m_-5196468749934338947Apple-tab-span" style="white-space:pre-wrap">        </span>…</font></div><div><font face="Monaco"><span class="gmail-m_-5196468749934338947Apple-tab-span" style="white-space:pre-wrap">        </span>var someInt = Int(truncating: someValue)</font></div><div><br></div><div>It may not communicate everything that&#39;s happening, but at least now it&#39;s clear at a glance that <b>something</b> is happening, and the term truncating suggests that something is being lost/removed from someValue.</div><div><br></div><div>Now I don&#39;t really care if truncating is the best term for it or not, though I do still think it is and won&#39;t change my mind on that;</div></div></blockquote><div><br></div><div>I think we&#39;re done here, then. What is the point of having a discussion with reasoned arguments if you&#39;re pre-committed to not changing your mind?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>the key thing here is that it&#39;s providing that extra safety to developers by making it clear that an important conversion is taking place, and this to me is more consistent with other initialisers on Int etc. where distinctions are made between types that can and cannot be represented exactly.</div><div><br></div><div>I&#39;m not saying it should be limited to floats either; I think any initialiser that cannot, or may not, represent the passed value accurately should be labelled for clarity.</div></div></blockquote><div><br></div><div>If you want to make that argument, it is a different discussion from the one here about integer math and floating point. You&#39;d be re-opening a discussion on the Swift API naming guidelines and asking for a much wider re-examination of the entire Swift API surface.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>So passing an Int16 into Int32(_:) would be fine for example, but the reverse should not be.</div><div><br></div><div>It&#39;s not just an issue of new developers; experienced ones make mistakes too, or forget to consider whether the conversion will impact their code. A label helps, though I still think forcing a decision on rounding is even better, as both prevent a developer from simply throwing in a value in a way that may be a mistake.</div></div></blockquote></div><br></div></div>