# Pitch: Variadic generic types abstracting over packs

**URL:** <https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377>\
**Category:** Pitches\
**Tags:** generics\
**Created:** [April 13, 2023, 4:52pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377 "2023-04-13T16:52:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 4:52pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/1 "2023-04-13T16:52:02Z")

</div>

# Allow Generic Types to Abstract Over Packs

- Proposal: SE-NNNN
- Authors: [Slava Pestov](https://github.com/slavapestov)
- Review Manager: TBD
- Upcoming Feature Flag: `VariadicGenerics`
- Previous Proposal: SE-0393

## Introduction

Previously SE-0393 introduced type parameter packs and several related concepts, allowing generic function declarations to abstract over a variable number of types. This proposal generalizes these ideas to generic type declarations.

## Motivation

Generic type declarations that abstract over a variable number of types arise naturally when attempting to generalize common algorithms on collections. For example, a lazy `ZipSequence` might be generic over two sequences. It would be possible to declare a `ZipSequence` type which presents the elements of a fixed list of sequences as a sequence of tuples:

```swift
struct ZipSequence<each S: Sequence>: Sequence {
  typealias Element = (repeat each S.Element)

  let seq: (repeat each S)

  func makeIterator() -> Iterator {
    return Iterator(iter: (repeat (each seq).makeIterator()))
  }

  struct Iterator: IteratorProtocol {
    typealias Element = (repeat each S.Element)

    var iter: (repeat each S.Iterator)

    mutating func next() -> Element? {
      return ...
    }
  }
}

```

## Proposed solution

In the generic parameter list of a generic type, the `each` keyword declares a generic parameter pack, just like it does in the generic parameter list of a generic function. The types of stored properties can contain pack expansion types, as in `let seq` and `var iter` above.

## Detailed design

Swift has the following kinds of generic type declarations:

- Structs
- Enums
- Classes (and actors)
- Type aliases

A generic type is _variadic_ if it directly declares a type parameter pack with `each`, or if it is nested inside of another variadic type. In this proposal, structs, classes, actors and type aliases can be variadic. Enums will be addressed in a follow-up proposal.

### Single parameter

A generic type is limited to declaring at most one type parameter pack. The following are allowed:

```swift
struct S1<each T> {}
struct S2<T, each U> {}
struct S3<each T, U> {}

```

But this is not:

```swift
struct S4<each T, each U> {}

```

However, by virtue of nesting, a variadic type might can still abstract over multiple type parameter packs:

```swift
struct Outer<each T> {
  struct Inner<each U> {
    var fn: (repeat each T) -> (repeat each U)
  }
}

```

### Referencing a variadic type

When used with a variadic type, the generic argument syntax `S<...>` allows a variable number of arguments to be specified. Since there can only be one generic parameter pack, the non-pack parameters are always specified with a fixed prefix and suffix of the generic argument list.

```swift
struct S<T, each U, V> {}

S<Int, Float>.self // T := Int, U := Pack{}, V := Float
S<Int, Bool, Float>.self // T := Int, U := Pack{Bool}, V := Float
S<Int, Bool, String, Float>.self // T := Int, U := Pack{Bool, String}, V := Float

```

Note that `S<Int, Float>` substitutes U with the empty pack type, which is allowed. The minimum number of generic arguments is equal to the number of non-pack generic parameters. In our above example, the minimum argument count is 2, because `T` and `V` must always be specified:

```swift
S<Int>.self // error: expected at least 2 generic arguments

```

If the generic parameter list of a variadic type consists of a single generic parameter pack and nothing else, it is possible to reference it with an empty generic argument list:

```swift
struct V<each T> {}

V<>.self

```

Note that `V<>` is not the same as `V`. The former substitutes the generic parameter pack `T` with the empty pack. The latter does not constrain the pack at all and is only permitted in contexts where the generic argument can be inferred.

A placeholder type in the generic argument list of a variadic generic type is always understood as a single pack element. For example:

```swift
struct V<each T> {}

let x: V<_> = V<Int>() // okay
let x: V<_, _> = V<Int, String>() // okay
let x: V<_> = V<Int, String>() // error

```

### Stored properties

In a variadic type, the type of a stored property can contain pack expansion types. The type of a stored property cannot _itself_ be a pack expansion type. Stored properties are limited to having pack expansions nested inside tuple types, function types and other named variadic types:

```swift
struct S<each T> {
  var a: (repeat each Array<T>)
  var b: (repeat each T) -> (Int)
  var c: Other<repeat each T>
}

```

This is in contrast with the parameters of generic function declarations, which can have a pack expansion type. A future proposal might lift this restriction and introduce true "stored property packs":

```swift
struct S<each T> {
  var a: repeat each Array<T>
}

```

### Requirements

The behavior of generic requirements on type parameter packs is unchanged between generic functions and generic types.

### Conformances

Variadic structs, classes and actors can conform to protocols. The associated type requirements of the protocol may be fulfilled by a type alias whose underlying type contains pack expansions.

### Type aliases

As with the other variadic types, a variadic type alias either has a generic parameter pack of its own, or can be nested inside of another variadic generic type.

The underlying type of a variadic type alias can reference pack expansion types in the same manner as the type of a stored property. That is, the pack expansions must appear in nested positions, but not at the top level.

```swift
typealias Element = (repeat each S.Element)
typealias Callback = (repeat each S) -> ()
typealias Factory = Other<repeat each S>

```

Unlike structs and classes, but like other type aliases, variadic type aliases can also be nested inside of generic functions.

### Classes

While there are no restrictions on non-final classes adopting type parameter packs, for the time being the proposal restricts such classes from being the superclass of another class.

An attempt to inherit from a variadic generic class outputs an error. The correct behavior of override checking and initializer inheritance in variadic generic classes will be dealt with in a follow-up proposal:

```swift
class Base<each T> {
  func foo(t: repeat each T) {}
}

// error: cannot inherit from a class with a type parameter pack
class Derived<U, V>: Base<U, V> {
  override func foo(t: U, _: V) {}
}

```

## Source compatibility

Variadic generic types are a new language feature which does not impact source compatibility with existing code.

## ABI compatibility

Variadic type aliases are not part of the binary interface of a module and do not require runtime support.

All other variadic types make use of new entry points and other behaviors being added to the Swift runtime. Since the runtime support requires extensive changes to the type metadata logic, backward deployment to older runtimes is not supported.

Replacing a non-variadic generic type with a variadic generic type is **not** binary-compatible in either direction. When adopting variadic generic types, binary-stable frameworks must introduce them as wholly-new symbols.

## Future directions

A future proposal will address variadic generic enums, and complete support for variadic generic classes.

Another possible future direction is stored property packs, which would eliminate the need to wrap a pack expansion in a tuple type in order to store a variable number of values inside of a variadic type. However, there is no expressivity lost in requiring the tuple today, since the contents of a tuple can be converted into a value pack.

## Alternatives considered

The one-parameter limitation could be lifted if we introduced labeled generic parameters at the same time. The choice to allow only a single (unlabeled) generic parameter pack does not preclude this possibility from being explored in the future.

Another alternative is to not enforce the one-parameter limitation at all. There would then exist variadic generic types which cannot be spelled explicitly, but can still be constructed by type inference:

```swift
struct S<each T, each U> {
  init(t: repeat each T, u: repeat each U) {}
}

S(t: 1, "hi", u: false)

```

It was felt that in the end, the single-parameter model is the simplest.

We could require that variadic classes are declared `final`, instead of rejecting subclassing at the point of use. However, since adding or removing `final` on a class is an ABI break, this would preclude the possibility of publishing APIs which work with the existing compiler but can allow subclassing in the future.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 13, 2023, 5:30pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/2 "2023-04-13T17:30:45Z")

</div>

> [@Slava\_Pestov](#):
>
> A placeholder type in the generic argument list of a variadic generic type is always understood as a single pack element.

If the need arises, would it be possible to have `let x: V<repeat _> = V<Int, String>()` or some such to indicate a variable number of inferred types?

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 6:02pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/3 "2023-04-13T18:02:23Z")

</div>

> [@xwu](#):
>
> If the need arises, would it be possible to have `let x: V<repeat _> = V<Int, String>()` or some such to indicate a variable number of inferred types?

Or in full generality, `repeat each _`. Then you can get really fancy: `G<repeat Array<each _>>`.

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [April 13, 2023, 6:28pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/4 "2023-04-13T18:28:23Z")

</div>

This is great, but I find the limitation on properties hard to understand, why can't you have _a_ when presumably you could have _b_?

```swift
struct S<each T> {
  var a: (repeat each T)
  var b: (repeat each Box<T>)
}
struct Box<T> { 
  var contents: T
}

```

Is it harder to implement, or what is the reason to not allow it?

It also seems like a pretty strange situation that we don't allow multiple variadic generic parameters, simply because of notation. It would seem that we should then look for alternative notation, rather than limit the functionality. For example, we could use semicolons within type packs, or braces around them when needed:

```swift
struct V<each T, each R> {}

let x1 = V<Int, Bool; String>() // T is { Int }, R is { Bool String }
let x2 = V<Int, { Bool, String }>() // ditto
let x3 = V<Int, (Bool, String)>() // ditto

```

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 7:17pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/5 "2023-04-13T19:17:25Z")

</div>

> [@GreatApe](#):
>
> This is great, but I find the limitation on properties hard to understand, why can't you have _a_ when presumably you could have _b_?

You can have both `a` and `b`. What you cannot have is this, without the parens:

```swift
struct S<each T> {
  var a: repeat each T
}

```

Recall that in a variadic generic function you can have both:

```swift
func f<each T>(t: repeat each T, tt: (repeat each T)) {}

f(t: 1, "hi", false, tt: (1, "hi", false))

```

> [@GreatApe](#):
>
> It also seems like a pretty strange situation that we don't allow multiple variadic generic parameters, simply because of notation. It would seem that we should then look for alternative notation, rather than limit the functionality. For example, we could use semicolons within type packs, or braces around them when needed:

Elsewhere pack types don't have a concrete spelling and we flatten them out into the surrounding comma-separated list, so it would be a bit odd if variadic generic types had this new syntactic form. I think labeled generic parameters would fit in better with the rest of the model, but I'd rather explore that in a separate proposal.

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [April 13, 2023, 7:36pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/6 "2023-04-13T19:36:19Z")

</div>

> [@Slava\_Pestov](#):
>
> You can have both `a` and `b`. What you cannot have is this, without the parens:

Hm, then it’s even harder to understand the reason for this limitation! What is the difference between storing it in a tuple and without? What does the tupleness prevent us from doing?

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 7:39pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/7 "2023-04-13T19:39:46Z")

</div>

> [@GreatApe](#):
>
> Hm, then it’s even harder to understand the reason for this limitation! What is the difference between storing it in a tuple and without? What does the tupleness prevent us from doing?

The limitation is there because you can do something with stored properties that you cannot with function parameters, and that is apply substitutions.

Consider these two definitions:

```swift
struct G1<each T> {
  var x: (repeat each T)
}

struct G2<each T> {
  var x: repeat each T
}

```

If I have

```swift
func f1(value: G1<Int, String>) {
  let x = value.x
}

```

Then the type of `value.x` is the tuple type `(Int, String)` because it's what we get after replacing `T` with `Int, String` inside `(repeat each T)`.

Now consider

```swift
func f2(value: G2<Int, String>) {
  let x = value.x
}

```

Here it would appear that `value.x` is an "unwrapped" concrete pack type. This is the same reason that a function cannot return a pack expansion:

```swift
func bad<each T>(_ t: repeat each T) -> repeat each T {}
func good<each T>(_ t: repeat each T) -> (repeat each T) {}

```

In the above, it is not clear what concrete type to assign to the result of something like `bad(1, "hi")`.

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [April 13, 2023, 8:51pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/8 "2023-04-13T20:51:02Z")

</div>

Thanks for the explanation, though I must say I never understood that limitation either, i.e. why you can't have a local variable with type `repeat each T`, or why you can't return that -- I don't quite understand what you mean by " it is not clear what concrete type to assign to the result of something like `bad(1, "hi")`". Wouldn't it just be `{ Int, String }`?

I know there is no such syntax "in the surface language", though that is another thing I don't get. Why not just introduce it, especially if the lack of syntax is what's stopping us from having `var x: repeat each T = ...`.

It seems that there is a desire to keep the full "vector" abstract in some sense, but that just seems to serve to make things harder to understand. Is there a technical reason against simply introducing a concrete (but elementwise and lengthwise generic) vector type? That would at least be much easier to understand.

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [April 13, 2023, 8:58pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/9 "2023-04-13T20:58:53Z")

</div>

> [@GreatApe](#):
>
> I know there is no such syntax "in the surface language", though that is another thing I don't get. Why not just introduce it, especially if the lack of syntax is what's stopping us from having `var x: repeat each T = ...`.

The lack of surface syntax is not what's preventing us from introducing local variable and stored property packs. I think we should have _both_ local variable and stored property packs in the future, but 1) those are both additive, and 2) those features do not prevent us from needing to work with abstract tuples. For example, to enhance the functionality of tuples themselves, we need to be able to write generic code that abstracts over the number of tuple elements, e.g. to implement conformances for all tuple types when their elements each conform to some protocol.

The issue with stored property packs is that they admit concrete packs as a concept into the language. Packs are not first-class values, so you cannot access a stored property pack concretely as a scalar value. We need to be able to project out certain elements from the stored property pack. That's another feature I think we should have, but it involves designing a suite of pack projection APIs into the language and standard library. Types that can abstract over parameter packs are still extremely useful without these enhancements, which is why there are separate [future directions of SE-0393](https://github.com/apple/swift-evolution/blob/main/proposals/0393-parameter-packs.md#future-directions).

EDIT: There's a bit more commentary on concrete packs in the "variadic generics vision" document that I wrote a few months ago, though it uses the old `...` syntax for pack expansion: [https://github.com/hborla/swift-evolution/blob/variadic-generics-vision/vision-documents/variadic-generics.md#concrete-packs](https://github.com/hborla/swift-evolution/blob/variadic-generics-vision/vision-documents/variadic-generics.md#concrete-packs)

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 9:00pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/10 "2023-04-13T21:00:27Z")

</div>

> [@GreatApe](#):
>
> Thanks for the explanation, though I must say I never understood that limitation either, i.e. why you can't have a local variable with type `repeat each T`, or why you can't return that -- I don't quite understand what you mean by " it is not clear what concrete type to assign to the result of something like `bad(1, "hi")`". Wouldn't it just be `{ Int, String }`?

Even before packs, we had this kind of thing because you can't write

```swift
func f() -> Int, String {}

```

And instead you write

```swift
func f() -> (Int, String) {}

```

The desire here is to avoid introducing a new concrete aggregate type that is basically the same as a tuple type.

---

<div class="post-metadata">

**Author:** ![GreatApe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/greatape/32/2640_2.png) [@GreatApe](https://forums.swift.org/u/GreatApe)\
**Post date:** [April 13, 2023, 9:15pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/11 "2023-04-13T21:15:09Z")

</div>

> [@hborla](#):
>
> Packs are not first-class values

I guess it all comes down to this. I don't quite get why they aren't, or even exactly what that means. I mean normal generic types aren't concretely known at compile time either, but we can still use a generic `T` as if it were, because in a concrete situation it will be known:

```swift
func allowed<T>(value: T) -> T? {
    let local: T = value // By the time we get here, T will be known
    if Bool.random() {
        return local
    } else {
        return nil
    }
}

func forbidden<each T>(value: repeat each T) {
    let local: repeat each T = value // presumably when we get here, we know what value looks like
}

```

EDIT:

I suppose it's related to the idea that a pack is "a comma separated list". And this is what I don't understand, why can't a pack just **be** a tuple? In the concrete case, that is essentially what it is anyway.

What do we gain from making this so abstract?

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [April 13, 2023, 10:17pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/12 "2023-04-13T22:17:34Z")

</div>

> [@GreatApe](#):
>
> I suppose it's related to the idea that a pack is "a comma separated list". And this is what I don't understand, why can't a pack just **be** a tuple? In the concrete case, that is essentially what it is anyway.

This is addressed in the [alternatives considered of SE-0393](https://github.com/apple/swift-evolution/blob/main/proposals/0393-parameter-packs.md#modeling-packs-as-tuples-with-abstract-elements).

---

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [April 13, 2023, 10:23pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/13 "2023-04-13T22:23:23Z")

</div>

Can a placeholder represent the empty pack type? For example:

```swift
struct S<T, each U, V> {}

S<Int, _, Float>.self // T := Int, U := Pack{}, V := Float

```

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [April 13, 2023, 10:36pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/14 "2023-04-13T22:36:39Z")

</div>

> [@hborla](#):
>
> > [@GreatApe](#):
> >
> > I suppose it's related to the idea that a pack is "a comma separated list". And this is what I don't understand, why can't a pack just **be** a tuple? In the concrete case, that is essentially what it is anyway.
> 
> This is addressed in the [alternatives considered of SE-0393](https://github.com/apple/swift-evolution/blob/main/proposals/0393-parameter-packs.md#modeling-packs-as-tuples-with-abstract-elements).

The reasoning here reminds me of [why Swift doesn’t model function arguments as tuples](https://forums.swift.org/t/review-se-0111-remove-type-system-significance-of-function-argument-labels/3209/41).

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 11:05pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/15 "2023-04-13T23:05:41Z")

</div>

> [@GreatApe](#):
>
> `let local: repeat each T = value`

We do plan on allowing this eventually, but you will probably need to write `let local: repeat each T = repeat each value`.

Compare this with

```swift
let local: (repeat each T) = (repeat each value)

```

In the latter, `local` is a single value you can refer to and pass around. It's type is a tuple type.

I can also write:

```swift
let fn: (repeat each T) -> () = { ... }

```

And define a closure which takes a variable number of arguments. Now this is not the same as a closure taking a single tuple argument. This shows why packs are defined abstractly as "things that go in a comma-separated list" and not as a new set of expressions involving tuple types specifically.

Packs and non-packs exist in separate universes, and a pack can only be used with an explicit expansion operation. Tuples, function parameter lists and named variadic generic types are all first-class "locations" where type packs can expand. Value packs similarly appear in tuple literal expressions, call argument expressions, and one day, inside collection literal expressions too. If we privileged tuples as the core thing that can be variadic, we'd need new kinds of "splat" operations on both types and values to make it work in all of these other contexts where packs can expand today.

(Perhaps if someone else is designing a new Swift-like language that happens to have variadic generics, they wouldn't need tuples at all, instead there could be a `struct Tuple<each T>` type in the standard library.)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 13, 2023, 11:11pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/16 "2023-04-13T23:11:23Z")

</div>

> [@benrimmington](#):
>
> Can a placeholder represent the empty pack type? For example:
> 
> ```swift
> struct S<T, each U, V> {}
> 
> S<Int, _, Float>.self // T := Int, U := Pack{}, V := Float
> 
> ```

I would think not: the placeholder being for a scalar type only, I'd expect an empty pack would have to be spelled like any other pack with the hypothetical `repeat each _`.

(Not to mention that, in that specific example, `_` shouldn't be inferred to be an empty pack anyway _regardless_ of spelling, as placeholders have always indicated that there is something there to be inferred from other information without a fallthrough to "nothingness" in the absence of any information. For example, for a non-variadic generic type `S<T>`, `S<_>` isn't equivalent in the absence of other context to either `S<Never>` or a hypothetical type-erased `AnyS`.)

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [April 13, 2023, 11:25pm UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/17 "2023-04-13T23:25:12Z")

</div>

> [@benrimmington](#):
>
> Can a placeholder represent the empty pack type? For example:
> 
> ```swift
> struct S<T, each U, V> {}
> 
> S<Int, _, Float>.self // T := Int, U := Pack{}, V := Float
> 
> ```

The _absence_ of a placeholder represents the empty pack type. `S<_, _>` leaves T and V open, but binds U to the empty pack type.

---

<div class="post-metadata">

**Author:** ![ensan-hcl](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ensan-hcl/32/15186_2.png) [@ensan-hcl](https://forums.swift.org/u/ensan-hcl)\
**Post date:** [April 14, 2023, 12:23am UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/18 "2023-04-14T00:23:11Z")

</div>

Within the proposed features, how can I write `ChainSequence<each S: Sequence>`, in which all `each S` should have a type `T` as their element?

It will be possible to write as this.

```swift
struct ChainSequence<each S: Sequence, Element> where (each S).Element == Element {}

```

But it requires additional `Element` in the type declaration, and users have to write `ChainSequences<[Int], Set<Int>, ArraySlice<Int>, Int>` even though the last `Element` is evident.

Is there any other way to express this kind of types?

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [April 14, 2023, 1:41am UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/19 "2023-04-14T01:41:01Z")

</div>

> [@ensan-hcl](#):
>
> But it requires additional `Element` in the type declaration, and users have to write `ChainSequences<[Int], Set<Int>, ArraySlice<Int>, Int>` even though the last `Element` is evident.
> 
> Is there any other way to express this kind of types?

If an empty chain `ChainSequences<>` isn't important, one could presumably make the first sequence a scalar parameter, i.e.: `ChainSequences<FirstSequence: Sequence, each S: Sequence> where repeat (each S).Element == FirstSequence.Element`, I think?

---

<div class="post-metadata">

**Author:** ![ensan-hcl](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ensan-hcl/32/15186_2.png) [@ensan-hcl](https://forums.swift.org/u/ensan-hcl)\
**Post date:** [April 14, 2023, 1:55am UTC](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377/20 "2023-04-14T01:55:33Z")

</div>

This is a swell way to do it.

> [@xwu](#):
>
> ChainSequences\<FirstSequence: Sequence, each S: Sequence\> where repeat (each S).Element == FirstSequence.Element

But I suspect empty chain is important, especially in generic context. For example, this will be impossible, because there's no 'non-empty' constraint.

```swift
func foo<each T: Sequence>(sequences: T) where (each T).Element == Int {
    var chain = ChainSequence(repeat each sequences)
}

```

And it must be something like this.

```swift
func foo<each T: Sequence>(firstSequence: some Sequence<Int>, _ sequences: T) where (each T).Element == Int {
    var chain = ChainSequence(firstSequence, repeat each sequences)
}

```

I don't think it is desirable to propagate this workaround to generic context.

[Next page](https://forums.swift.org/t/pitch-variadic-generic-types-abstracting-over-packs/64377.md?page=2)
