<div dir="ltr">Hi,<br><br>The implementation of SE-0116 "Import Objective-C id as Swift Any type" requires a type-erased container for hashable values.<br><br>We are proposing to add such a type-erased container under the name AnyHashable to the standard library.<div><br></div><div>This proposal is additive, source-breaking changes are discussed in SE-0116.<br><br><ins style="display:block;border-radius:0px;border-top-width:0px;border-bottom-width:0px;text-decoration:none;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;line-height:24px"><pre class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:10px 20px;overflow:auto;border-radius:3px;margin-left:15px;background-color:rgb(247,247,247)"><span class="" style="color:rgb(150,152,150)">/// A type-erased hashable value.</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// Forwards equality comparisons and hashing operations to an</span>
<span class="" style="color:rgb(150,152,150)">/// underlying hashable value, hiding its specific type.</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// You can store mixed-type keys in `Dictionary` and other</span>
<span class="" style="color:rgb(150,152,150)">/// collections that require `Hashable` by wrapping mixed-type keys in</span>
<span class="" style="color:rgb(150,152,150)">/// `AnyHashable` instances:</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// let descriptions: [AnyHashable : Any] = [</span>
<span class="" style="color:rgb(150,152,150)">/// AnyHashable("😄"): "emoji",</span>
<span class="" style="color:rgb(150,152,150)">/// AnyHashable(42): "an Int",</span>
<span class="" style="color:rgb(150,152,150)">/// AnyHashable(Int8(43)): "an Int8",</span>
<span class="" style="color:rgb(150,152,150)">/// AnyHashable(Set(["a", "b"])): "a set of strings"</span>
<span class="" style="color:rgb(150,152,150)">/// ]</span>
<span class="" style="color:rgb(150,152,150)">/// print(descriptions[AnyHashable(42)]!) // prints "an Int"</span>
<span class="" style="color:rgb(150,152,150)">/// print(descriptions[AnyHashable(43)]) // prints "nil"</span>
<span class="" style="color:rgb(150,152,150)">/// print(descriptions[AnyHashable(Int8(43))]!) // prints "an Int8"</span>
<span class="" style="color:rgb(150,152,150)">/// print(descriptions[AnyHashable(Set(["a", "b"]))]!) // prints "a set of strings"</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">struct</span> AnyHashable {
<span class="" style="color:rgb(150,152,150)">/// Creates an opaque hashable value that wraps `base`.</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// Example:</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// let x = AnyHashable(Int(42))</span>
<span class="" style="color:rgb(150,152,150)">/// let y = AnyHashable(UInt8(42))</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// print(x == y) // Prints "false" because `Int` and `UInt8`</span>
<span class="" style="color:rgb(150,152,150)">/// // are different types.</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// print(x == AnyHashable(Int(42))) // Prints "true".</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">init</span><span class="" style="color:rgb(167,29,93)"><</span>H <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span><span class="" style="color:rgb(167,29,93)">></span>(_ base: H)
<span class="" style="color:rgb(150,152,150)">/// The value wrapped in this `AnyHashable` instance.</span>
<span class="" style="color:rgb(150,152,150)">///</span>
<span class="" style="color:rgb(150,152,150)">/// let anyMessage = AnyHashable("Hello")</span>
<span class="" style="color:rgb(150,152,150)">/// let unwrappedMessage: Any = anyMessage.base</span>
<span class="" style="color:rgb(150,152,150)">/// print(unwrappedMessage) // prints "hello"</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">var</span> base: <span class="" style="color:rgb(0,134,179)">Any</span>
}
<span class="" style="color:rgb(167,29,93)">extension</span> AnyHashable <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Equatable</span>, <span class="" style="color:rgb(0,134,179)">Hashable</span> {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">==</span> (lhs: AnyHashable, rhs: AnyHashable) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Bool</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">var</span> hashValue: <span class="" style="color:rgb(0,134,179)">Int</span> {
}
</pre></ins><ins style="display:block;border-radius:0px;border-top-width:0px;border-bottom-width:0px;text-decoration:none;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;line-height:24px"><p class="" style="margin-top:0px;margin-bottom:16px;margin-left:15px">We are adding convenience APIs to <code class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Set<AnyHashable></code> that allow using existing <code class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Set</code> APIs with concrete values that conform to <code class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Hashable</code>. For example:</p></ins><ins style="display:block;border-radius:0px;border-top-width:0px;border-bottom-width:0px;text-decoration:none;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;line-height:24px"><pre class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:10px 20px;overflow:auto;border-radius:3px;margin-left:15px;background-color:rgb(247,247,247)"><span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">contains42</span>(<span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">data</span>: <span class="" style="color:rgb(0,134,179)">Set</span><span class="" style="color:rgb(167,29,93)"><</span>AnyHashable<span class="" style="color:rgb(167,29,93)">></span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Bool</span> {
<span class="" style="color:rgb(150,152,150)">// Works, but is too verbose:</span>
<span class="" style="color:rgb(150,152,150)">// return data.contains(AnyHashable(42))</span>
<span class="" style="color:rgb(167,29,93)">return</span> data<span class="" style="color:rgb(167,29,93)">.</span><span class="" style="color:rgb(0,134,179)">contains</span>(<span class="" style="color:rgb(0,134,179)">42</span>) <span class="" style="color:rgb(150,152,150)">// Convenience API.</span>
}<br></pre><pre class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:10px 20px;overflow:auto;border-radius:3px;margin-left:15px;background-color:rgb(247,247,247)"><span class="" style="color:rgb(167,29,93)">extension</span> <span class="" style="color:rgb(0,134,179)">Set</span> <span class="" style="color:rgb(167,29,93)">where</span> Element <span class="" style="color:rgb(167,29,93)">==</span> AnyHashable {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">contains</span><ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">member</span>: ConcreteElement
) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Bool</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">index</span><ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">of</span> <span class="" style="">member</span>: ConcreteElement
) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">SetIndex</span><Element>?
<span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">insert</span><ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">newMember</span>: ConcreteElement
) <span class="" style="color:rgb(167,29,93)">-></span> (inserted: <span class="" style="color:rgb(0,134,179)">Bool</span>, memberAfterInsert: ConcreteElement)
<span class="" style="color:rgb(167,29,93)">@discardableResult</span>
<span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">update</span><ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">with</span> <span class="" style="">newMember</span>: ConcreteElement
) <span class="" style="color:rgb(167,29,93)">-></span> ConcreteElement?
<span class="" style="color:rgb(167,29,93)">@discardableResult</span>
<span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">remove</span><ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">member</span>: ConcreteElement
) <span class="" style="color:rgb(167,29,93)">-></span> ConcreteElement?
}</pre></ins><ins style="display:block;border-radius:0px;border-top-width:0px;border-bottom-width:0px;text-decoration:none;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;line-height:24px"><p class="" style="margin-top:0px;margin-bottom:16px;margin-left:15px">Convenience APIs for <code class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;padding:0.2em 0px;margin:0px;border-radius:3px;background-color:rgba(0,0,0,0.0392157)">Dictionary<AnyHashable, *></code>:</p></ins><ins style="display:block;border-radius:0px;border-top-width:0px;border-bottom-width:0px;text-decoration:none;color:rgb(51,51,51);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:16px;line-height:24px"><pre class="" style="font-family:Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:16px;font-stretch:normal;line-height:1.45;word-wrap:normal;padding:10px 20px;overflow:auto;border-radius:3px;margin-left:15px;background-color:rgb(247,247,247)"><span class="" style="color:rgb(167,29,93)">extension</span> <span class="" style="color:rgb(0,134,179)">Dictionary</span> <span class="" style="color:rgb(167,29,93)">where</span> Key <span class="" style="color:rgb(167,29,93)">==</span> AnyHashable {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">index</span><ConcreteKey <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(<span class="" style="color:rgb(121,93,163)">forKey</span> <span class="" style="">key</span>: ConcreteKey)
<span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">DictionaryIndex</span><span class="" style="color:rgb(167,29,93)"><</span>Key, Value<span class="" style="color:rgb(167,29,93)">></span>?
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">subscript</span>(_ key: _Hashable) <span class="" style="color:rgb(167,29,93)">-></span> Value? { <span class="" style="color:rgb(167,29,93)">get</span> <span class="" style="color:rgb(167,29,93)">set</span> }
<span class="" style="color:rgb(167,29,93)">@discardableResult</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">updateValue</span><ConcreteKey <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">value</span>: Value, <span class="" style="color:rgb(121,93,163)">forKey</span> <span class="" style="">key</span>: ConcreteKey
) <span class="" style="color:rgb(167,29,93)">-></span> Value?
<span class="" style="color:rgb(167,29,93)">@discardableResult</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">removeValue</span><ConcreteKey <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>>(
<span class="" style="color:rgb(121,93,163)">forKey</span> <span class="" style="">key</span>: ConcreteKey
) <span class="" style="color:rgb(167,29,93)">-></span> Value?
}</pre></ins><br>Dmitri<br><br>-- <br>main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf("%d\n",i);}}} /*Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>>*/</div></div>