# Value Pack Expansion and Single Element Tuples

**URL:** <https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692>\
**Category:** Using Swift\
**Tags:** macros, parameter-packs\
**Created:** [August 4, 2024, 7:11pm UTC](https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692 "2024-08-04T19:11:16Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![George](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/george/32/37757_2.png) [@George](https://forums.swift.org/u/George)\
**Post date:** [August 4, 2024, 7:11pm UTC](https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692/1 "2024-08-04T19:11:16Z")

</div>

I'm having an issue with some code I'm writing that uses pack expansion and macros

The fundamental issue is that `(repeat each foo)` doesn't expand to a tuple if there is only a single value:

```swift
func tuple<each T>(foos: (repeat each T)) -> (repeat each T) {
  (repeat each foos)
}
let singleElementTuple = tuple(foos: (1))
singleElementTuple.0 // Value of type 'Int' has no member '0'
let twoElementTuple = tuple(foos: (1, 2))
twoElementTuple.0 // Works fine

```

In regular code this is mostly-fine, but in generated code (such as a macro) it is a little annoying as I need to special-case the single-element case. Is there any better way to deal with this?

---

<div class="post-metadata">

**Author:** ![Quedlinbug](https://avatars.discourse-cdn.com/v4/letter/q/77aa72/32.png) [@Quedlinbug](https://forums.swift.org/u/Quedlinbug)\
**Post date:** [August 4, 2024, 9:00pm UTC](https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692/2 "2024-08-04T21:00:01Z")

</div>

> [@George](#):
>
> Is there any better way to deal with this?

I don't think so, because not only do packs support single elements, but also, zero elements:

```swift
tuple(foos: ()).0 //🙂‍↔️

```

Maybe this is helpful, for the special casing?

```swift
func isReallyTuple<each Element>(_ element: (repeat each Element)) -> Bool {
  var hasFirstElement = false
  for _ in repeat (each Element).self {
    if hasFirstElement { return true }
    else { hasFirstElement = true }
  }
  return false
}

```

---

<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:** [August 4, 2024, 10:10pm UTC](https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692/3 "2024-08-04T22:10:37Z")

</div>

One element tuples were pitched and rejected in [[Pitch] One-Element Tuples](https://forums.swift.org/t/pitch-one-element-tuples/60219).

Maybe you want something like this?

```swift
func first<T, each U>(_ tuple: (T, repeat each U)) -> T {
  return tuple.0
}

```

---

<div class="post-metadata">

**Author:** ![Quedlinbug](https://avatars.discourse-cdn.com/v4/letter/q/77aa72/32.png) [@Quedlinbug](https://forums.swift.org/u/Quedlinbug)\
**Post date:** [August 4, 2024, 10:58pm UTC](https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692/4 "2024-08-04T22:58:53Z")

</div>

That crashes the compiler in the latest Xcode beta. Do you actually have it working?

---

<div class="post-metadata">

**Author:** ![George](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/george/32/37757_2.png) [@George](https://forums.swift.org/u/George)\
**Post date:** [August 5, 2024, 4:00am UTC](https://forums.swift.org/t/value-pack-expansion-and-single-element-tuples/73692/5 "2024-08-05T04:00:57Z")

</div>

I tried something like this, but for my use case it is actually a `(repeat (ConcreteType, each ParameterPackType))` so in order to make that work I'd need to provide a value of `ConcreteType` in order to make it work. Fortunately, it isn't a huge issue for the logic to be conditional on whether or not there is one or multiple elements (0 elements is actually another interesting case). I was just wondering if there was some language feature I missed which cleaned this up but it seems like that isn't the case.
