<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div>I totally agree with you. </div><div><br></div><div>But I think that the suggested Summable with zero fits the bill of your citation quite nicely as it actually is a very generic concept which is widely useful. </div><div><br></div><div>FWIW I had chosen the name Summable instead of Monoid for two reasons: (1) there has been reluctance by some people on this list to add algebraic types to the standard library and (2) Summable is one concrete instance of Monoid for numbers (with respect to addition) just as my other suggestion Multiplicative is another instance of Monoid for numbers (with respect to multiplication).</div><div><br></div><div>If we want to add Monoid (and other algebraic types) to the standard library (I would welcome that), you are certainly right that we should design this well. The above actually suggests that summable and multiplicative instances for numbers might just be that: (singleton?) instances of Monoid with an associated type of Number (instead of protocols) so that they can be passed around more easily. </div><div>On the other hand we could borrow some ideas from Eiffel to solve the (semantic) diamond problem via renaming and choosing defaults. Like the early work about generics you found, Eiffel's solution sadly is ignored in most language designs (and interfaces thought of as a solution of the diamond problem... they are not). Not too long ago I wrote a lenghty mail on this list about that in the Mixin thread IIRC.</div><div><br></div><div><blockquote type="cite"><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">I'm not sure I'm adding anything by saying this, but one problem with<br>creating protocols that satisfy the absolute minimum requirements for a<br>particular algorithm is that you end up without any meaningful<br>abstractions.</span></font></blockquote><br></div><div>I think Dave Sweeris' example is not about creating Addable a.k.a Summable just because it satisfies the algorithm but rather it happens that Monoid *is* such a useful abstraction that it naturally pops up in many algorithms.</div><div><br></div><div>-Thorsten </div><div><br>Am 21.04.2016 um 20:36 schrieb Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>:<br><br></div><blockquote type="cite"><div><span></span><br><span>on Wed Apr 20 2016, <a href="http://davesweeris-at-mac.com">davesweeris-AT-mac.com</a> wrote:</span><br><span></span><br><blockquote type="cite"><blockquote type="cite"><span>On Apr 20, 2016, at 1:15 PM, Dave Abrahams via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>on Tue Apr 19 2016, Thorsten Seitz <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>I'd like to have something like Summable with 'add', 'adding' and 'zero' being a</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>separate protocol as well as somthing like Multiplicative with 'multiply',</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>'multiplied' and 'one' being a separate protocol, because these are universally</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>interesting for other cases, e.g. Summable would be useful for defining path</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>lengths in a graph library.</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>Would you mind adding that to the proposal?</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I suspect you may be headed into the realm of</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>protocols-as-bags-of-syntax.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>You say that like it’s a bad thing… </span><br></blockquote><span></span><br><span>Indeed!</span><br><span></span><br><blockquote type="cite"><span>Am I missing the point? (NOT a rhetorical question)</span><br></blockquote><span></span><br><span>I don't know, but I'll try to help answer...</span><br><span></span><br><blockquote type="cite"><span>Speaking only for myself, I want stuff broken up into many simpler</span><br></blockquote><blockquote type="cite"><span>protocols (which `Arithmetic` and such conform to) because there are</span><br></blockquote><blockquote type="cite"><span>many algorithms which only require small parts of the larger</span><br></blockquote><blockquote type="cite"><span>protocol. What if I wanted to add a function that sums all the</span><br></blockquote><blockquote type="cite"><span>elements in a collection?</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>extension CollectionType where Generator.Element: Arithmetic {</span><br></blockquote><blockquote type="cite"><span> func sum() -> Generator.Element {</span><br></blockquote><blockquote type="cite"><span> var s = Generator.Element()</span><br></blockquote><blockquote type="cite"><span> for e in self {</span><br></blockquote><blockquote type="cite"><span> s.add(e)</span><br></blockquote><blockquote type="cite"><span> }</span><br></blockquote><blockquote type="cite"><span> return s</span><br></blockquote><blockquote type="cite"><span> }</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Yeah, it works, but if I want to get the sum of a collection of some custom type, I</span><br></blockquote><blockquote type="cite"><span>have to implement *all* of `Arithmetic`, as opposed to just the two</span><br></blockquote><blockquote type="cite"><span>parts of it (`init()` and `.add(:)`) that the algorithm actually</span><br></blockquote><blockquote type="cite"><span>uses. It’d be both simpler for the users and *more to the point of the</span><br></blockquote><blockquote type="cite"><span>function*, if it could be written like this:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>extension CollectionType where Generator.Element: Addable { // "Addable" instead of "Arithmetic"</span><br></blockquote><blockquote type="cite"><span> ... // No change here</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><span></span><br><span>This method is undocumented. What does it *do*, given an arbitrary</span><br><span>element type conforming to Addable? The answer needs to be a</span><br><span>description of the semantics that doesn't require me to effectively</span><br><span>execute the source of the function in my head. How can I test that the</span><br><span>method does the right thing? To answer these questions, you have to</span><br><span>attach some semantics to Addable so that it's more than a mere bag of</span><br><span>syntax. For example, for the above to produce the usual semantics of</span><br><span>summing, the Element's init() method needs to produce the additive</span><br><span>identity element.</span><br><span></span><br><span>Choosing the granularity of protocols is something of an art. Lots has</span><br><span>been written about generic programming's “requirement minimization</span><br><span>principle,” in which the more requirements you add, the less reusable</span><br><span>algorithms become. Almost nothing has been written about the other side</span><br><span>of the coin, but...</span><br><span></span><br><span>After much googling I came up with a reference to one of Alexander</span><br><span>Stepanov and James Dehnert's early papers on generic programming (it</span><br><span>sometimes amazes me how many of the key insights can only be found in</span><br><span>that early work):</span><br><span></span><br><span><a href="http://www.stepanovpapers.com/DeSt98.pdf">http://www.stepanovpapers.com/DeSt98.pdf</a></span><br><span></span><br><span> We call the set of axioms satisfied by a data type and a set of</span><br><span> operations on it a concept. Examples of concepts might be an integer</span><br><span> data type with an addition operation satisfying the usual axioms; or a</span><br><span> list of data objects with a first element, an iterator for traversing</span><br><span> the list, and a test for identifying the end of the list. **The critical</span><br><span> insight which produced generic programming is that highly reusable</span><br><span> components must be programmed assuming a minimal collection of such</span><br><span> concepts, and that the concepts used must match as wide a variety of</span><br><span> concrete program structures as possible**. Thus, successful production</span><br><span> of a generic component is not simply a matter of identifying the</span><br><span> minimal requirements of an arbitrary type or algorithm – it requires</span><br><span> identifying the common requirements of a broad collection of similar</span><br><span> components. The final requirement is that we accomplish this without</span><br><span> sacrificing performance relative to programming with concrete</span><br><span> structures. A good generic library becomes a repository of highly</span><br><span> efficient data structures and algorithms, based on a small number of</span><br><span> broadly useful concepts, such that a library user can combine them and</span><br><span> his own components in a wide variety of ways.</span><br><span></span><br><span>(emphasis mine).</span><br><span></span><br><span>I'm not sure I'm adding anything by saying this, but one problem with</span><br><span>creating protocols that satisfy the absolute minimum requirements for a</span><br><span>particular algorithm is that you end up without any meaningful</span><br><span>abstractions.</span><br><span></span><br><span>“*The* critical insight,” wow. And it's so easily overlooked.</span><br><span></span><br><span>HTH,</span><br><span></span><br><span>-- </span><br><span>Dave</span><br><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>