[Pitch] Opaque parameter types

Both _T1 and _T2 are parameter packs, i.e., each represents a sequence of zero or more types.

I feel like your concern is about variadic generics, not opaque parameters. Let's dig into this function more:

func f<T1: Hashable..., T2: Equatable...>(_ dicts: [T1: T2]...)

There are no opaque parameters here. The variadic generics proposal under discussion is clear about what this means. Let's form a call:

``swift
let intsToStrings: [Int: String] = [:]
let stringsToDoubles: [String: Double] = [:]
let intsToDoubles: [Int: Double] = [:]
f(intsToStrings, stringsToDoubles, intsToDoubles) // okay: T1 = { Int, String, Int }, T2 = {String, Double, Double}


As you can see, the arguments to `f` are all dictionaries, but instantiated with different key and value types. Because `T1` and `T2` are parameter packs (declared with the `...`), they represent multiple generic arguments, as seen in the lists above.

If you drop the `...` from either generic parameter, you get a different API. For example, we could require that all of the value types be the same:

```swift
func g<T1: Hashable..., T2: Equatable>(_ dicts: [T1: T2]...)

// ...

g(stringsToDoubles, intsToDoubles) // okay: T1 = { String, Int }, T2 = Double
g(intsToStrings, stringsToDoubles, intsToDoubles) // error: T1 = { Int, String, Int }, but T2 can't be both String and Double

Dictionary is a generic type, but it's not a protocol and there is no conformance to it. Dictionary<T, U> is a particular specialization of the generic type: for different T and U arguments it will create a distinct type, but they are all specializations of the same generic type and have the same structure. The structural similarity is hugely important to Swift's type-checking model for generics.

Doug

1 Like