<div dir="ltr"><span style="font-size:12.8px">&gt;  Is it well settled, either in Swift or in C++/Rust/etc., that the value returned by a default initializer/constructor is regarded as an identity element or zero? </span><br><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Int() == 0, String() == &quot;&quot; so to some extent by convention, a lot of types have a default value as is.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">&gt; Is the thread that I get by writing `let t = Thread()` some kind of zero in any reasonable sense of the word?</span><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">DefaultConstructibility makes less sense for types that represent some sort of resource but make sense for things that are values. But even in this case, Thread() gives you a default value for example if you are working with a resizable collection of threads. A better question is why does thread currently implement a default constructor? </span></div><div><span style="font-size:12.8px"><br></span></div><div><div style="font-size:12.8px">&gt; Do you mean to argue that for an integer the additive identity should be considered &quot;more prominent and useful&quot; than the multiplicative identity? I&#39;m not aware of any mathematical justification for such a conclusion.</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">I do. The justification is that if I call the default constructor of Int currently, I get the value of 0. Which means that the binary operation must be addition. If I call String() I get &quot;&quot; which is the identity of the + String operation.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">&gt; <span style="font-size:12.8px">Going to your original example, I should add: other languages provide a version of `reduce` that doesn&#39;t require an initial result (for instance, JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) =&gt; a + b)` uses the element at array index 0 as the initial result, and the accumulator function is invoked starting with the element at array index 1. This is precisely equivalent to having `reduce` use the additive identity as the default initial result when + is the accumulator function and the multiplicative identity when * is the accumulator function (with the accumulator function being invoked starting with the element at array index 0). It does not require a DefaultConstructible protocol. What more ergonomic solution could be implemented using a monoidic wrapper type?</span></div><div style="font-size:12.8px"><span style="font-size:12.8px"><br></span></div><div style="font-size:12.8px">These two will have different signatures. The reduce you describe returns an optional, the other one would returns the default value. Fundamentally the default constructibles are useful in numerical computations e..g. dealing with tensors.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Dec 25, 2016 at 3:30 PM, Xiaodi Wu <span dir="ltr">&lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="">On Sun, Dec 25, 2016 at 5:27 PM, Adam Nemecek <span dir="ltr">&lt;<a href="mailto:adamnemecek@gmail.com" target="_blank">adamnemecek@gmail.com</a>&gt;</span> wrote:<br></span><div class="gmail_extra"><div class="gmail_quote"><span class=""><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 dir="ltr"><span class="m_-5821329404718624302gmail-"><div>&gt; <span style="font-size:12.8px">*Which* APIs become more ergonomic?</span></div><div><span style="font-size:12.8px"><br></span></div></span><div>I&#39;ll get back to this question in a second if I may. This would be a longer discussion and I first want to make sure that before we get into the details that there is a possibility of this being introduced (I&#39;m asking if violating the no zero defaults is more important than slightly more ergonomic APIs). But to give a broad answer I think that the concept of a zero is closely related to the concept of equality (and all the things that build up on equality such as comparability and negation). </div><span class="m_-5821329404718624302gmail-"><div><br></div><div>&gt; <span style="font-size:12.8px">1) How does this square with Swift’s general philosophy to not default initialize values to “zero”?</span></div><div><span style="font-size:12.8px"><br></span></div></span><div><span style="font-size:12.8px">I actually wasn&#39;t aware of this philosophy. Despite this philosophy, look at how many types actually currently implement a default constructor.</span></div></div></blockquote><div><br></div></span><div>(Not a rhetorical question:) Is it well settled, either in Swift or in C++/Rust/etc., that the value returned by a default initializer/constructor is regarded as an identity element or zero? Is the thread that I get by writing `let t = Thread()` some kind of zero in any reasonable sense of the word?</div><span class=""><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 dir="ltr"><div><span style="font-size:12.8px">Also can I ask what&#39;s the motivation behind this philosophy? </span></div><div><span style="font-size:12.8px">I think that in Swift, default constructibility makes complete sense for (most?) structs, maybe less so for classes. </span></div><span class="m_-5821329404718624302gmail-"><div><br></div>&gt; <span style="font-size:12.8px">2) To your original example, it isn’t immediately clear to me that reduce should choose a default identity.  Some types (e.g. integers and FP) belong to multiple different ring algebras, and therefore have different identity values that correspond to the relevant binary operations.</span><div><span style="font-size:12.8px"><br></span></div></span><div><span style="font-size:12.8px">This is a good point that I&#39;ve considered as well but felt that for the most part, there is one particular identity and associated operation that is more prominent and useful than others. Furthermore, modeling different algebras isn&#39;t mutually exclusive with writing generic algorithms that rely on this protocol, you can always introduce some monoidic wrapper type that defines the more appropriate default value and operation.</span></div></div></blockquote><div><br></div></span><div>Do you mean to argue that for an integer the additive identity should be considered &quot;more prominent and useful&quot; than the multiplicative identity? I&#39;m not aware of any mathematical justification for such a conclusion.</div><div><br></div><div>Going to your original example, I should add: other languages provide a version of `reduce` that doesn&#39;t require an initial result (for instance, JavaScript). In JavaScript, `[1, 2, 3].reduce((a, b) =&gt; a + b)` uses the element at array index 0 as the initial result, and the accumulator function is invoked starting with the element at array index 1. This is precisely equivalent to having `reduce` use the additive identity as the default initial result when + is the accumulator function and the multiplicative identity when * is the accumulator function (with the accumulator function being invoked starting with the element at array index 0). It does not require a DefaultConstructible protocol. What more ergonomic solution could be implemented using a monoidic wrapper type?</div><div><div class="h5"><div><br></div><div><div><br></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 class="m_-5821329404718624302gmail-HOEnZb"><div class="m_-5821329404718624302gmail-h5"><div class="gmail_extra"><div class="gmail_quote">On Sun, Dec 25, 2016 at 1:24 PM, Chris Lattner <span dir="ltr">&lt;<a href="mailto:clattner@apple.com" target="_blank">clattner@apple.com</a>&gt;</span> wrote:<br><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"><span>On Dec 25, 2016, at 12:54 PM, Adam Nemecek via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</span><div><span><blockquote type="cite"><div><div dir="ltr">Does enabling a lot of small improvements that make APIs more ergonomic count as practical?</div></div></blockquote><div><br></div></span><div>Yes, that would count as practical, but Xiaodi’s question is just as important.  *Which* APIs become more ergonomic?</div><div><br></div><div>Here are a couple of more questions:</div><div><br></div><div>1) How does this square with Swift’s general philosophy to not default initialize values to “zero”?</div><div><br></div><div>2) To your original example, it isn’t immediately clear to me that reduce should choose a default identity.  Some types (e.g. integers and FP) belong to multiple different ring algebras, and therefore have different identity values that correspond to the relevant binary operations.</div><span class="m_-5821329404718624302gmail-m_3993794689939404596HOEnZb"><font color="#888888"><div><br></div><div>-Chris</div></font></span><div><div class="m_-5821329404718624302gmail-m_3993794689939404596h5"><br><blockquote type="cite"><div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Dec 25, 2016 at 12:19 PM, Xiaodi Wu <span dir="ltr">&lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;</span> wrote:<br><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 dir="ltr"><span>On Sun, Dec 25, 2016 at 3:07 PM, Adam Nemecek <span dir="ltr">&lt;<a href="mailto:adamnemecek@gmail.com" target="_blank">adamnemecek@gmail.com</a>&gt;</span> wrote:<br></span><div class="gmail_extra"><div class="gmail_quote"><span><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 dir="ltr">There&#39;s a book that provides quite a bit of info on this <div><br></div><div><a href="https://smile.amazon.com/Elements-Programming-Alexander-Stepanov/dp/032163537X?sa-no-redirect=1" target="_blank">https://smile.amazon.com/Eleme<wbr>nts-Programming-Alexander-Step<wbr>anov/dp/032163537X?sa-no-redir<wbr>ect=1</a><br></div><div><br></div><div>They say that DefaultConstructible is one of the essential protocols on which most algorithms rely in one way or another. One of the authors is the designer of the C++ STL and basically the father of modern generics.</div><div><br></div><div>This protocol is important for any algebraic structure that deals with the concept of appending or addition (as &quot;zero&quot; is one of the requirements of monoid). There isn&#39;t a good short answer to your question. It&#39;s a building block of algorithms. Think about why a RangeReplaceableCollection can provide you with a default constructor but a Collection can&#39;t. </div><div><span style="color:rgb(80,0,80)"></span></div></div></blockquote><div><br></div></span><div>It&#39;s well and fine that most algorithms rely on the concept in one way or another. Yet the Swift standard library already implements many generic algorithms but has no DefaultConstructible, presumably because there are other protocols that guarantee `init()` and the algorithms being implemented don&#39;t need to be (practically speaking) generic over all DefaultConstructible types. My question is: what practical use cases are there for an explicit DefaultConstructible that are impractical today?</div><span><div><br></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 dir="ltr"><div><span style="color:rgb(80,0,80)">On Sun, Dec 25, 2016 at 11:37 AM, Xiaodi Wu </span><span dir="ltr" style="color:rgb(80,0,80)">&lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt;</span><span style="color:rgb(80,0,80)"> wrote:</span><br></div></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289HOEnZb"><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289h5"><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">Can you give some other examples of generic algorithms that would make use of this DefaultConstructible? I&#39;m having trouble coming up with any other than reduce.<br><div class="gmail_quote"><div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951h5"><div dir="ltr">On Sun, Dec 25, 2016 at 14:23 Adam Nemecek via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></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><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951h5"><div dir="ltr" class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">This protocol is present in C++ <a href="http://en.cppreference.com/w/cpp/concept/DefaultConstructible" class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg" target="_blank">http://en.cppreference.com<wbr>/w/cpp/concept/DefaultConstruc<wbr>tible</a> as well as in Rust <a href="https://doc.rust-lang.org/std/default/" class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg" target="_blank">https://doc.rust-lang.org/std/<wbr>default/</a><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">It&#39;s the identity element/unit of a monoid or a zero.<br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">The Swift implementation is very simple (I&#39;m open to different names)<br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">protocol DefaultConstructible {</div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">    init() </div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">}</div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">A lot of the standard types could then be made to conform to this protocol. These include all the numeric types, collection types (array, set, dict), string, basically at least every type that currently has a constructor without any arguments.</div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">The RangeReplaceableCollection protocol would inherit from this protocol as well. <br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">This protocol would simplify a lot of generic algorithms where you need the concept of a zero (which shows up a lot)</div></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">Once introduced, Sequence could define an alternative implementation of reduce where the initial result doesn&#39;t need to be provided as it can be default constructed.</div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div><div class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg"></div></div></div></div></div>
______________________________<wbr>_________________<br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">
swift-evolution mailing list<br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br class="m_-5821329404718624302gmail-m_3993794689939404596m_-267952324834337685m_8912025549324475289m_699475458640075951m_-6015751673947924360gmail_msg">
</blockquote></div>
</blockquote></div><br></div>
</div></div></blockquote></span></div><br></div></div>
</blockquote></div><br></div>
______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br></div></blockquote></div></div></div><br></div></blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>