<div dir="ltr">Hi,<br><br>The implementation of SE-0116 &quot;Import Objective-C id as Swift Any type&quot; 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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;;font-size:16px;line-height:24px"><pre class="" style="font-family:Consolas,&quot;Liberation Mono&quot;,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(&quot;😄&quot;): &quot;emoji&quot;,</span>
<span class="" style="color:rgb(150,152,150)">///         AnyHashable(42): &quot;an Int&quot;,</span>
<span class="" style="color:rgb(150,152,150)">///         AnyHashable(Int8(43)): &quot;an Int8&quot;,</span>
<span class="" style="color:rgb(150,152,150)">///         AnyHashable(Set([&quot;a&quot;, &quot;b&quot;])): &quot;a set of strings&quot;</span>
<span class="" style="color:rgb(150,152,150)">///     ]</span>
<span class="" style="color:rgb(150,152,150)">///     print(descriptions[AnyHashable(42)]!)      // prints &quot;an Int&quot;</span>
<span class="" style="color:rgb(150,152,150)">///     print(descriptions[AnyHashable(43)])       // prints &quot;nil&quot;</span>
<span class="" style="color:rgb(150,152,150)">///     print(descriptions[AnyHashable(Int8(43))]!) // prints &quot;an Int8&quot;</span>
<span class="" style="color:rgb(150,152,150)">///     print(descriptions[AnyHashable(Set([&quot;a&quot;, &quot;b&quot;]))]!) // prints &quot;a set of strings&quot;</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 &quot;false&quot; 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 &quot;true&quot;.</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)">&lt;</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)">&gt;</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(&quot;Hello&quot;)</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 &quot;hello&quot;</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)">-&gt;</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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;;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,&quot;Liberation Mono&quot;,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&lt;AnyHashable&gt;</code> that allow using existing <code class="" style="font-family:Consolas,&quot;Liberation Mono&quot;,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,&quot;Liberation Mono&quot;,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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;;font-size:16px;line-height:24px"><pre class="" style="font-family:Consolas,&quot;Liberation Mono&quot;,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)">&lt;</span>AnyHashable<span class="" style="color:rgb(167,29,93)">&gt;</span>) <span class="" style="color:rgb(167,29,93)">-&gt;</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,&quot;Liberation Mono&quot;,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>&lt;ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">member</span>: ConcreteElement
  ) <span class="" style="color:rgb(167,29,93)">-&gt;</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>&lt;ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <span class="" style="color:rgb(121,93,163)">of</span> <span class="" style="">member</span>: ConcreteElement
  ) <span class="" style="color:rgb(167,29,93)">-&gt;</span> <span class="" style="color:rgb(0,134,179)">SetIndex</span>&lt;Element&gt;?

  <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>&lt;ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">newMember</span>: ConcreteElement
  ) <span class="" style="color:rgb(167,29,93)">-&gt;</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>&lt;ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <span class="" style="color:rgb(121,93,163)">with</span> <span class="" style="">newMember</span>: ConcreteElement
  ) <span class="" style="color:rgb(167,29,93)">-&gt;</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>&lt;ConcreteElement <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <span class="" style="color:rgb(121,93,163)">_</span> <span class="" style="">member</span>: ConcreteElement
  ) <span class="" style="color:rgb(167,29,93)">-&gt;</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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;;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,&quot;Liberation Mono&quot;,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&lt;AnyHashable, *&gt;</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,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;;font-size:16px;line-height:24px"><pre class="" style="font-family:Consolas,&quot;Liberation Mono&quot;,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>&lt;ConcreteKey <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(<span class="" style="color:rgb(121,93,163)">forKey</span> <span class="" style="">key</span>: ConcreteKey)
    <span class="" style="color:rgb(167,29,93)">-&gt;</span> <span class="" style="color:rgb(0,134,179)">DictionaryIndex</span><span class="" style="color:rgb(167,29,93)">&lt;</span>Key, Value<span class="" style="color:rgb(167,29,93)">&gt;</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)">-&gt;</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>&lt;ConcreteKey <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <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)">-&gt;</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>&lt;ConcreteKey <span class="" style="color:rgb(167,29,93)">:</span> <span class="" style="color:rgb(0,134,179)">Hashable</span>&gt;(
    <span class="" style="color:rgb(121,93,163)">forKey</span> <span class="" style="">key</span>: ConcreteKey
  ) <span class="" style="color:rgb(167,29,93)">-&gt;</span> Value?
}</pre></ins><br>Dmitri<br><br>-- <br>main(i,j){for(i=2;;i++){for(j=2;j&lt;i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf(&quot;%d\n&quot;,i);}}} /*Dmitri Gribenko &lt;<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>&gt;*/</div></div>