<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div>+1&nbsp;</div><div>Splitting the init seems to be a good idea, though I would have thought that a non-throwing default would not require a try on a call using the default (I'm not near a Swift compiler currently, so can't check that right now).</div><div>I like the mutating functions!</div><div><br></div><div>-Thorsten</div><div><br>Am 16.01.2016 um 08:28 schrieb Nate Cook via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt;:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><div class="">Adding a `combine` closure with Donnacha's default seems like a pretty good solution for this, but giving a `try`-marked closure parameter a default &nbsp;messes with the rethrows behavior and requires a try on every call. I think it's important that when used by default, this initializer has the same behavior as looping over the sequence and setting values for keys. That is, it should replicate:</div><div class=""><br class=""></div><div class="">for (key, value) in sequence {&nbsp;</div><div class="">&nbsp; &nbsp; newDictionary[key] = value&nbsp;</div><div class="">}</div><div class=""><br class=""></div><div class="">and use the last value for any duplicate keys, rather than failing or trapping.</div><div class=""><br class=""></div><div class="">To handle this properly we'd need two new initializers:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&lt;S: </span>SequenceType<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span>S<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>Generator<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>Element<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> == </span>Generator<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>Element<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&gt;(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> sequence: </span>S<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>&lt;S: SequenceType <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> S.Generator.Element == Generator.Element&gt;</div><div style="margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; (<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> sequence: S, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> combine: (Value, Value) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -&gt; Value) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span></div><div class=""><br class=""></div></div><div class="">Perhaps we also need a mutating `mergeContentsOf` function with the same signatures as the initializers:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">mutating</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> mergeContentsOf&lt;S: </span>SequenceType<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span>S<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>Generator<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>Element<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> == </span>Generator<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.</span>Element<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&gt;(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> sequence: </span>S<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""><br class=""></span></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">mutating</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> mergeContentsOf&lt;S: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> S.Generator.Element == <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Generator</span>.Element&gt;</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; (<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">_</span> sequence: S, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> combine: (Value, Value) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -&gt; Value) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class=""><br class=""></span></div><div class="">I'm pretty sure I would use all four of those, and that would bring Dictionary more into alignment with how you can use Array and Set. Would a slightly expanded proposal make sense?</div><div class=""><br class=""></div>Nate<div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 15, 2016, at 9:01 AM, Nicola Salmoria via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="">I'm ambivalent about the preconditionFailure. Since there would otherwise be silent loss of data, I think it fits Swift's "safe by default" paradigm. It's also consistent with what the normal initialization from a DictionaryLiteral does.<br class=""></div><div class="">However, I can also see how it might be more convenient to just pick the last value.<br class=""></div><br class="">Nicola<br class=""><br class=""><div class=""><div class="gmail_extra"><div class="gmail_quote">On Fri, Jan 15, 2016 at 11:53 AM, Alan Skipp<span class="Apple-converted-space">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:al_skipp@icloud.com" target="_blank" class="">al_skipp@icloud.com</a>&gt;</span><span class="Apple-converted-space">&nbsp;</span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div style="word-wrap: break-word;" class="">I’ve been absorbed in the world of Monoids lately, so I find the suggestion below to be particularly brilliant. : )<div class="">It solves the issue of arbitrarily choosing the value for duplicate keys rather nicely. Only thing I’m not too sure about is the idea of failing by default on duplicate keys?</div><div class=""><br class=""></div><div class=""><div class=""><span class=""><div class=""><blockquote type="cite" class=""><div class="">On 15 Jan 2016, at 10:18, Nicola Salmoria via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">To handle the case of duplicate keys, why not allow to pass in a 'combine' function?<br class="">The function could default to a preconditionFailure to be consistent with the DictionaryLiteral behavior, but be overridden by the caller as needed.<br class=""><br class="">extension Dictionary {<br class="">&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>/// Creates a dictionary with the keys and values in the given sequence.<br class="">&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>init&lt;S: SequenceType where S.Generator.Element == Generator.Element&gt;(_ sequence: S, combine: (existing: Value, other: Value) -&gt; Value = { preconditionFailure("Sequence contains duplicate keys"); return $1 } ) {<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>self.init()<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>for (key, value) in sequence {<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>if let existing = updateValue(value, forKey: key) {<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>updateValue(combine(existing: existing, other: value), forKey: key)<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>}<br class="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>}<br class="">&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span>}<br class="">}<br class=""><br class=""><br class="">usage examples:<br class=""><br class="">let samples = [("Rome", 40.2), ("New York", 35.1), ("Rome", 42.5), ("New York", 32.8)]<br class="">let minTemperatures = Dictionary(samples, combine: min)<br class="">// ["Rome": 40.2, "New York": 32.8]<br class="">let maxTemperatures = Dictionary(samples, combine: max)<br class="">// ["Rome": 42.5, "New York": 35.1]<br class=""><br class="">let probabilities = [("a", 0.25), ("b", 0.25), ("c", 0.25), ("a", 0.25)]<br class="">let stateProbabilities = Dictionary(probabilities, combine: +)<br class="">// ["b": 0.25, "a": 0.5, "c": 0.25]<br class=""><br class=""></div><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">Nicola</span></div></blockquote><br class=""></div></span><div class=""><div class="">It’d be great if there was also an init that restricted the Values to Monoids, which would mean the combine function would be taken from the supplied Monoid values (I understand I’ve departed to fantasy island at this point, but one can dream : )</div><div class=""><br class=""></div><div class="">Al<br class=""></div><div class=""><br class=""></div></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=4GlEpM11j-2BGED-2FudNhzzUKGouoeTKtIEqwsP-2B6t6Pznw62fwc6eD7hA5jHkKPGv4C1Yq7IFXDogBVK-2Fqbt3p1fwf4Dk4iN5FsHRZphL81XTPbkyTzEb8nG6B9kzZObH1DUzAG7RTdq79UTGxXqQ5kCTJgqWs6-2FOahACF007ATtJPwyHmkUUF0F38iT97HDxQ-2FZrWLxJKMGL9PN2Q0Gnjy-2BvGb-2B5uou9LRqIjke0uoUU-3D" alt="" width="1" height="1" border="0" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><span class="Apple-converted-space">&nbsp;</span>_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></div></div></blockquote><blockquote type="cite"><div><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>