# Future: On value-based generic arguments for functions

**URL:** <https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669>\
**Category:** Discussion\
**Tags:** generics\
**Created:** [July 23, 2018, 2:02am UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669 "2018-07-23T02:02:50Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [July 23, 2018, 2:02am UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/1 "2018-07-23T02:02:50Z")

</div>

For generic types we can explicitly mention the generic arguments:

```
Array<Int>

```

Can we do the same for generic functions? As far as I know, the answer is no.

If I'm correct here, is that going to change when/if value-based generic parameters are added? Or are we going to be stuck with requiring every generic argument having to be able to be reversed-engineered from the call-arguments' types?

If support is added, what are everyone's ideas for the syntax? Could we use C++ syntax, which it applies to both the declarations of templated items and their usage (where Swift here uses the syntax for both type and function declarations but only for type usages)?

---

<div class="post-metadata">

**Author:** ![dennisvennink](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dennisvennink/32/3637_2.png) [@dennisvennink](https://forums.swift.org/u/dennisvennink)\
**Post date:** [July 23, 2018, 4:07am UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/2 "2018-07-23T04:07:47Z")

</div>

We can already do this, no?

```swift
print(((Int) -> Int).self)
// (Int) -> Int

print(Array<Int>.self)
// [Int]

```

But in order to use the same syntax we would need functions to be nominal types, which they currently aren't. Then you'd get something like `Function<Int, Int>`.

---

<div class="post-metadata">

**Author:** ![CTMacUser](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ctmacuser/32/1802_2.png) [@CTMacUser](https://forums.swift.org/u/CTMacUser)\
**Post date:** [July 23, 2018, 4:48am UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/3 "2018-07-23T04:48:09Z")

</div>

I mean if we have

```
func test<T>(_ x: T) { /* ... */ }

```

we can only call it with

```
test(6)

```

AFAIK we can't use

```
test<Int>(6)

```

Or am I wrong here? If not, should this be changed, especially before value-based generic parameters are added? This is a required step before using arguments that aren't implied by the call's arguments.

---

<div class="post-metadata">

**Author:** ![anon31136981](https://avatars.discourse-cdn.com/v4/letter/a/c2a13f/32.png) [@anon31136981](https://forums.swift.org/u/anon31136981)\
**Post date:** [July 23, 2018, 5:01am UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/4 "2018-07-23T05:01:12Z")

</div>

I think this would be a good addition to the language eventually, but I've never personally been held back by the lack of the feature. Even when/if value-based generics are added, I suspect their primary use-case will be in the generic parameter lists of types, not functions. In a lot of cases, even with functions parameterized by values, those values will be able to be inferred, like so:

```swift
struct FixedSizedArray<Element, Count: Int> {
    //...
}
func foo<Count: Int>(_ array: FixedSizedArray<Foo, Count>) {}

```

---

<div class="post-metadata">

**Author:** ![huon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/huon/32/1887_2.png) [@huon](https://forums.swift.org/u/huon)\
**Post date:** [July 23, 2018, 5:08am UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/5 "2018-07-23T05:08:40Z")

</div>

> [@CTMacUser](#):
>
> If not, should this be changed, especially before value-based generic parameters are added?

This is getting a little ahead, I think. _If_ value generic parameters are added, then we will need some way to specify them, but we don't need to fix that problem _before_ we have value generic parameters, or at least a serious proposal for them (although maybe I've missed it?). Pre-emptively solving a problem before fully understanding what the motivation will look like seems like a recipe for not completely covering every aspect.

In any case, currently, if a parameter can't be inferred from the arguments, the recommended fix is to pass a type argument, e.g.:

```swift
// instead of:
func foo<T>() {}
foo() // what's T?

// use:
func bar<T>(_: T.Type) {}
bar(Int.self)

```

I'd guess this style could be extended to value generic parameters too.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [July 23, 2018, 1:55pm UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/6 "2018-07-23T13:55:48Z")

</div>

Do you happen to know why it's like that? i.e. why _can't_ we just write `foo<Int>()` directly?

I always wondered about this. It feels like a bit of an arbitrary limitation.

---

<div class="post-metadata">

**Author:** ![dennisvennink](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dennisvennink/32/3637_2.png) [@dennisvennink](https://forums.swift.org/u/dennisvennink)\
**Post date:** [July 23, 2018, 4:34pm UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/7 "2018-07-23T16:34:43Z")

</div>

The reason could be that it would read like an `init` for a type named `foo`:

```swift
typealias foo = Optional

print(foo<Int>(0))
// Optional(0)

```

By the way, @huon's example made me of a use case why we would want some like this. (Because the whole concept didn't really click with me before.)

I currently make heavy use of two `extension`s on `Mirror` for a DSL:

```swift
public extension Mirror {
  func children <T> (_ type: T.Type) -> [T] {
    return self.children.fmap({$0.value}).filter({$0 is T}) as! [T]
  }

  func descendants <T> (_ type: T.Type) -> [T] {
    return self.children.fmap({$0.value}).bind({(element: Any) -> [T] in
      let mirror = Mirror(reflecting: element)

      if element is T {
        return [T].pure(element).mappend(mirror.descendants(type))
      }

      return mirror.descendants(type)
    }
  }
}

```

Calling `children(_:)` would then be:

```swift
struct Struct {
  let integer1 = 1
  let boolean1 = true
  let string1 = "a"
  let integer2 = 2
  let boolean2 = false
  let integer3 = 3
}

print(Mirror(reflecting: Struct()).children(Int.self))
// [1, 2, 3]

```

**(All of the following is currently non-working.)**

This could then indeed be rewritten by:

```swift
print(Mirror(reflecting: Struct()).children<Int>())
// [1, 2, 3]

```

But then I'd personally even go a step further; allow generics on computed properties as well and extend the syntax:

```swift
public extension Mirror {
  var children <T>: [T] {
    return self.children.fmap({$0.value}).filter({$0 is T}) as! [T]
  }
}

```

```swift
print(Mirror(reflecting: Struct()).children<Int>)
// [1, 2, 3]

```

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [July 23, 2018, 4:37pm UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/8 "2018-07-23T16:37:32Z")

</div>

I think once upon a time we thought it would make parsing and type-checking simpler if we could assume that attaching angle brackets to something always meant it was a type, but I'm not sure that's true any more. (That same line of thought led to `[Foo.Bar]()` not working for a long time even though `Array<Foo.Bar>()` was fine.) It's entirely possible that today's compiler could support this pretty easily, but I haven't looked into it recently.

One interesting note is that _not_ having this sometimes makes source-compatible changes easier. For instance, a second generic parameter can be added to a function as long as all existing calls continue to work. Generic parameters in functions can also be reordered freely, which they can't be in classes. (I'm not sure why someone would go out of their way to do this, but maybe a bunch of different functions were added separately and now someone is tidying them up to be consistent.)

@Douglas_Gregor, do you remember any more history here?

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [July 23, 2018, 9:48pm UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/9 "2018-07-23T21:48:59Z")

</div>

> [@jrose](#):
>
> For instance, a second generic parameter can be added to a function as long as all existing calls continue to work.

I feel like there are design options that could reduce friction here as much as possible. E.g., we could allow inference of some generic parameters (as well as default types) and have a rule that partial list match the earliest parameters first). Concretely, you could define a function as

```
func foo<T>(t: T) { ... }

```

and call it as

```
foo<String>(t: "bar")

```

Then, if you need to add a generic parameter later, you could write it as:

```
func foo<T, U = Int>(t: T, u: U = 0) { ... }

```

or even just

```
func foo<T, U>(t: T, u: U = 0) { ... }

```

which, when called as

```
foo<String>(t: "bar")

```

would be equivalent to both of the following

```
foo<String, Int>(t: "bar", u: 0)
foo(t: "bar", u: 0)

```

EDIT: On second thought, I'm a bit confused about how you could add such a parameter... the code below fails to compile:

```
func foo<T, U: ExpressibleByIntegerLiteral>(t: T, u: U = 0)
{
    print(t)
    print(u)
}

foo(t: 5) // Generic parameter 'U' could not be inferred

```

How is it possible right now to add a generic parameter and have existing calls function properly?

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [July 23, 2018, 10:21pm UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/10 "2018-07-23T22:21:31Z")

</div>

I was thinking of generalization:

```swift
// Before:
func repeatingThrice<Result: RangeReplaceableCollection>(
  _ str: String
) -> Result
where Result.Element == String {
  var result = Result()
  result.append(str)
  result.append(str)
  result.append(str)
  return result
}

```

```swift
// After:
func repeatingThrice<Result: RangeReplaceableCollection, Value>(
  _ val: Value
) -> Result
where Result.Element == String {
  var result = Result()
  result.append(String(describing: val))
  result.append(String(describing: val))
  result.append(String(describing: val))
  return result
}

```

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [July 24, 2018, 7:30pm UTC](https://forums.swift.org/t/future-on-value-based-generic-arguments-for-functions/14669/11 "2018-07-24T19:30:22Z")

</div>

@jrose is certainly correct that this was originally a compiler limitation; we didn't get around to implementing support for this syntax in the type checker in the early days.

Later on, the additional of the `f<T, U>()` syntax for specifying generic arguments of a generic function was discussed in some of the Swift language design meetings. We decided at that time not to add the feature, because we felt it unnecessary:

- Type inference can usually get the right answer. When it can't, one can often use `as` to fix it. This works well for, e.g., `numericCast(_:)`.

- Sometimes a function wants one of the types to be explicitly specified. For that, we felt that a an explicit (possibly-labeled) argument that takes a metatype (e.g., `T.self`) was a better solution. `unsafeBitCast` is a good example here, because type inference here can be a bit... unsafe.... Explicit metatype arguments can also handle dynamic types. For example, I could have: `var foo: Superclass.Type = Subclass.self; unsafeBitCast(something, to: foo)` and that will pass through (dynamically) the subclass's metatype. Explicit generic arguments would likely not handle that, because they deal in static types.
