# A new idea about generics

**URL:** <https://forums.swift.org/t/a-new-idea-about-generics/49251>\
**Category:** Pitches\
**Tags:** generics, existential\
**Created:** [June 3, 2021, 11:21pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251 "2021-06-03T23:21:43Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 3, 2021, 11:21pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/1 "2021-06-03T23:21:43Z")

</div>

I posted this on the ["Improving the UI of generics"](https://forums.swift.org/t/improving-the-ui-of-generics/22814/170) thread, but I wanted to also post it separately to hear some independent discussion on the matter without either bumping or clogging that thread:

I have an idea that I quite like so far but I could be convinced otherwise - I would love to hear what people think about it. I know that the idea is inspired by many ideas of others that I've read here on the forum, but I don't remember seeing exactly this as I'm proposing it. However, it is also possible that without knowing it I'm proudly presenting someone else's idea as if it were my own. Apologies if so.

### The Idea

What if we expand the use of the generic `<T: Constraint>` syntax to be usable in every (or maybe almost every) situation where a normal type name can be used? The syntax would have the same meaning in the new context as it does in its current usage, namely that the type in question will be chosen by the caller (subject to certain constraints).

Simplest example:

```swift
// Current syntax
func doNothing <Value> (with value: Value)

// New syntax
func doNothing (with value: <Value>)

```

The `Value` type is introduced at the same time as being used in the type expression.

### Details

The placeholder type names that are introduced in this way are accessible in the whole function signature and within the body of the function just like with the current generic syntax:

```swift
// Current syntax
func first <C: Collection> (of collection: C) -> C.Element

// New syntax
func first (of collection: <C: Collection>) -> C.Element

```

Any type names wrapped in angle brackets must be unique within the scope. This, for example, is an error:

```swift
// Wrong
func assign (_ newValue: <Value>, to destination: inout <Value>) // Error - invalid redeclaration of `Value`

```

Exactly one usage of `Value` must be wrapped in angle brackets, and everywhere else it is referenced by name like any other type. Generic constraints can be applied either within the angle brackets or by way of a `where` clause.

Thus, the correct ways to write that function are:

```swift
func assign (_ newValue: <Value>, to destination: inout Value)
func assign (_ newValue: Value, to destination: inout <Value>)

func assign <Value> (_ newValue: Value, to destination: inout Value)

```

If an angle bracket type declaration appears in the return type position that does not mean that it is a reverse generic. It is still a regular generic type, in the sense that the caller chooses the return type.

All of these signatures are equivalent:

```swift
// Current syntax
func echo <Value> (_ value: Value) -> Value

// New syntax
func echo (_ value: Value) -> <Value>
func echo (_ value: <Value>) -> Value

```

The order in which the types are declared within the function signature doesn't matter, in the sense that the declared types can be referenced in earlier parameters:

```swift
// Old syntax
func feed <Recipient: Eater> (_ food: Recipient.Food, to recipient: Recipient) -> Recipient.FormOfThanks

// New syntax
func feed (_ food: Recipient.Food, to recipient: <Recipient: Eater>) -> Recipient.FormOfThanks

```

I find the reduction of angle-bracket-blindness in the latter relative to the former fairly significant.

It seems reasonable to me to allow this syntax to be nested in a type expression:

```swift
// Old syntax
func dropLatterHalf <T> (of array: [T]) -> [T]

// New syntax
func dropLatterHalf (of array: [<T>]) -> [T]
func dropLatterHalf (of array: [T]) -> [<T>]

```

### Properties

Given that `<T>` means a type that will be chosen by the caller, how do we interpret this?:

```swift
let foo: <T> = 7

```

This is effectively the same as this:

```swift
typealias T = Int
let foo = 7

```

in the sense that after using `<T>` as the type of `foo` we can then reference `T` for the rest of the scope:

```swift
let foo: <T> = 7
let maximumInteger = T.max // This is `Int.max`

```

(I can't quite put my finger on it at the moment but I have a feeling that there's something about this use-case that could prove extremely useful for writing and especially for maintaining unit tests).

If there is a constraint included in the type declaration then it is enforced at compile time as always:

```swift
let a: <T: Numeric> = 1.4 // Ok
let b: <T: Numeric> = "string" // Error

let c: <T: Numeric>
switch something {
case .oneThing: c = 1.2
case .anotherThing: c = 1.9 // Ok - both are `Double`
}

let d: <T: Numeric>
switch something {
case .oneThing: d = 1.5
case .anotherThing: d = Int(7) // Error: mismatched types
}

```

This would allow computed properties to have generic return types:

```swift
var anyKindOfSevenYouWant: <T: ExpressibleByIntegerLiteral> {
    .init(integerLiteral: 7)
}

```

### Existentials

This syntax would naturally allow us to unwrap existentials. For example:

```swift
let boxedUpValue: some Equatable = ...
let value: <Value> = boxedUpValue
if let dynamicallyCasted = someOtherValue as? Value {
    print(value == dynamicallyCasted)
}

```

I'm thinking where clauses would be allowed on any declaration that contains a type placeholder declaration:

```swift
let existential: some Equatable = ...
let value: <T> = existential where T: Equatable

```

I suppose that in many cases the generic constraint on the type declaration can be implicit:

```swift
let existential: some Equatable = ...
let value: <T> = existential // T is known to conform to `Equatable`

```

### Alternative Generic Type Syntax? (Controversial and not to be taken too seriously)

Here's another thought (and this one's a little bit out there) - could using one of these within the type expression of a stored property of a type be interpreted as a new generic parameter of the enclosing type?

```swift
struct Queue {

    private(set) var elements: [<Element>]
}

```

would be equal to:

```swift
struct Queue <Element> {

    private(set) var elements: [Element]
}

```

it could also be done like this:

```swift
struct Queue {

    private var _privateDictBecauseWhoKnowsWhy: [Int: <Element>]

    var elements: [Element] {
        Array(_privateDictBecauseWhoKnowsWhy.values)
    }
}

```

Either way, the `Queue` type would be usable as a normal generic type (e.g., `Queue<Int>`).

The `Result` type for example could then be declared like this:

```swift
enum Result {
    case success (<Success>)
    case failure (<Failure: Error>)
}

```

I suppose the proper order of generic type parameters for a type could be determined simply by the order in which they appear in the type declaration.  
This has the order `A` then `B`:

```swift
struct Foo {
    var a: <A>
    var b: <B: Collection>
}

let _: Foo<Int, Array<Bool>> // Ok
let _: Foo<Array<Bool>, Int> // Error, the Collection must come second

```

### Extensions On Any

Lastly, perhaps this would also be the right syntax for extending any type (if that's actually a good idea in the first place):

```swift
extension <T> {
    func mutated (by mutation: (inout Self)->()) -> Self {
        var copy = self
        mutation(&copy)
        return copy
    }
}

```

One obvious question here is regarding the usage of the letter `T`, when we could equivalently have written:

```swift
extension <AnythingWeWantToWrite> {
    func mutated (by mutation: (inout Self)->()) -> Self {
        var copy = self
        mutation(&copy)
        return copy
    }
}

```

and achieved the same result. I suppose that the name chosen is nothing more than a typealias for `Self` which is declared in the scope of that extension, so the name is chosen by the programmer the same way a more descriptive local typealias is chosen by the programmer, as it won't affect anything but the way his or her own code reads. Writing this paragraph then evoked the idea for me, when we don't feel the need for a new `typealias T = Self` could we write it like this?:

```swift
extension <_> {
    func mutated (by mutation: (inout Self)->()) -> Self {
        var copy = self
        mutation(&copy)
        return copy
    }
}

```

---

<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:** [June 4, 2021, 12:19am UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/2 "2021-06-04T00:19:59Z")

</div>

I don't like to have type parameters scattered all over the function. If we want to have named type parameter that can used anywhere, it's better to declare all of them at first, and shorthand should work only if there is no needs for name, so that they don't cause any additional complexity.

> [@jeremyabannister](#):
>
> ```Swift
> struct Queue {
> 
> private var _privateDictBecauseWhoKnowsWhy: [Int: <Element>]
> 
> var elements: [Element] {
> Array(_privateDictBecauseWhoKnowsWhy.values)
> }
> }
> 
> ```

I disagree. What happens in this case? Why not `T` is used as type parameter of `Queue`? As the same reason for function type parameter, they should gathered in one place; otherwise it's hard to read (though easy to write).

```Swift
struct Queue {
    func someFunction(_ value: <T>) {}
}

```

* * *

> [@jeremyabannister](#):
>
> Given that `<T>` means a type that will be chosen by the caller, how do we interpret this?:
> 
> ```Swift
> let foo: <T> = 7
> 
> ```
> 
> This is effectively the same as this:
> 
> ```Swift
> typealias T = Int
> let foo = 7
> 
> ```

> [@jeremyabannister](#):
>
> ```Swift
> var anyKindOfSevenYouWant: <T: ExpressibleByIntegerLiteral> {
> .init(integerLiteral: 7)
> }
> 
> ```

I cannot understand what changed here. In the [generics manifesto](https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md#generic-constants), syntax similar to the former is treated as 'generic constant', it works the same as the latter. I think we should treat these two things as the same feature.

And though there is no type name, the similar feature to what you expected for the former can be already done.

```Swift
let foo: some Numeric = 7

```

Therefore, it is a feature that reverse generics should treat. I think it should be like this.

```Swift
let foo: <some T> = 7

```

> [@jeremyabannister](#):
>
> This syntax would naturally allow us to unwrap existentials. For example:
> 
> ```Swift
> let existential: any Equatable = ...
> let otherExistential: any Equatable = ...
> let value: <T: Equatable> = existential
> if let otherValue = otherExistential as? T {
> if value == otherValue {
> // Do something
> }
> }
> 
> ```

I agree [opening existential](https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md#opening-existentials) is a feature worth adding. But from the same reason, I don't think the syntax `let value: <T: Equatable> = existential` is apporopriate to do it.

* * *

> [@jeremyabannister](#):
>
> Lastly, perhaps this would also be the right syntax for extending any type (if that's actually a good idea in the first place):
> 
> ```Swift
> extension <T> {
> func mutated (by mutation: (inout Self)->()) -> Self {
> var copy = self
> mutation(&copy)
> return copy
> }
> }
> 
> ```

This is referred in [generics manifesto](https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md#extensions-of-structural-types) and previously discussed as parameterized extension [here](https://forums.swift.org/t/parameterized-extensions/25563).

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [June 4, 2021, 1:25am UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/3 "2021-06-04T01:25:20Z")

</div>

The initial idea (being able to introduce type variables in situ instead of all at the start of the function declaration) is certainly an interesting one. The `func f<T>` syntax is a confusing one for first-timers. I would be curious to see, in a little informal user study of people new to generics, whether `func f(x: <T>)` makes any more sense to them.

My guess is it would only help a little, and it would take something more fluent like, say…

```
func f(x: T) forAnyType T

```

…to really help. But the value of speculation here is limited; actually showing the syntax alternatives to people and observing their reaction would be illuminating.

---

<div class="post-metadata">

**Author:** ![Alejandro\_Martinez](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/alejandro_martinez/32/821_2.png) [@Alejandro\_Martinez](https://forums.swift.org/u/Alejandro_Martinez)\
**Post date:** [June 4, 2021, 7:59am UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/4 "2021-06-04T07:59:50Z")

</div>

My first impression may just be because is a new syntax, but let me express it anyway :)

> [@jeremyabannister](#):
>
> The Value type is introduced at the same time as being used in the type expression.

This is a nice idea and property to have. It works well in simple examples but I think it muddies the waters for anything more complex.

The first case where the improvements break for me is here:

> [@jeremyabannister](#):
>
> ```swift
> // Wrong
> func assign (_ newValue: <Value>, to destination: inout <Value>) // Error - invalid redeclaration of `Value`
> 
> ```
> 
> Exactly one usage of `Value` must be wrapped in angle brackets, and everywhere else it is referenced by name like any other type.

This makes total sense. But I feel that the distinction between `Type` and `<Type>` is diluted to the point that the error may seem surprising.

> [@jeremyabannister](#):
>
> The order in which the types are declared within the function signature doesn't matter, in the sense that the declared types can be referenced in earlier parameters:
> 
> ```swift
> // Old syntax
> func feed <Recipient: Eater> (_ food: Recipient.Food, to recipient: Recipient) -> Recipient.FormOfThanks
> 
> // New syntax
> func feed (_ food: Recipient.Food, to recipient: <Recipient: Eater>) -> Recipient.FormOfThanks
> 
> ```
> 
> I find the reduction of angle-bracket-blindness in the first relative to the second fairly significant.

And here is where I think I feel like we lost any benefit. The nice property of `The Value type is introduced at the same time as being used in the type expression.` is lost here. It feels very weird to me to start reading a declaration and see a type that is not declared anywhere yet. Maybe is just getting used to it but at this point it feels like we are not gaining much.

As a general note I would also like to point out that having so any different ways of doing the same is not always desirable.

> [@jeremyabannister](#):
>
> perhaps this would also be the right syntax for extending any type (if that's actually a good idea in the first place):

As a side note, this is something I would love Swift to handle sooner rather than later. I wish there was no distinction between nominal and non-nominal types. It gets very frustrating in a lot of cases.

* * *

Overall I think is a nice exploration of how we could improve type system syntax. I'm just not sure is an appropriate take on it. But as I said, first impressions!

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 4, 2021, 12:38pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/5 "2021-06-04T12:38:53Z")

</div>

> [@jeremyabannister](#):
>
> ```swift
> // New syntax
> func feed (_ food: Recipient.Food, to recipient: <Recipient: Eater>) -> Recipient.FormOfThanks
> 
> ```

> [@Alejandro\_Martinez](#):
>
> It feels very weird to me to start reading a declaration and see a type that is not declared anywhere yet.

Do you see it any more problematic than this that we already deal with?:

```swift
struct Moon {
    var phase: Phase

    enum Phase {
        case new, crescent, full
    }
}

```

or even:

```swift
struct Moon {
    var phase: Phase
}

extension Moon {
    enum Phase {
        case new, crescent, full
    }
}

```

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 4, 2021, 12:51pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/6 "2021-06-04T12:51:03Z")

</div>

> [@ensan-hcl](#):
>
> What happens in this case? Why not `T` is used as type parameter of `Queue` ? As the same reason for function type parameter, they should gathered in one place; otherwise it's hard to read (though easy to write).
> 
> ```swift
> struct Queue {
> func someFunction(_ value: <T>) {}
> }
> 
> ```

As I indicated, I'm not at all sold on the idea of using this syntax to implicitly declare type parameters. I could imagine it being very problematic...

However, the answer to your specific question is that in your example `T` would not be treated as a type parameter of `Queue` because it does not appear in the type of a _stored property_ of `Queue`.

The reason for this is that while the return type of a computed property or function can be chosen by the caller in the moment of calling (as in the `var anyKindOfSevenYouWant` example that I gave above), and of course the inputs to functions and subscripts can be chosen by the caller in the moment of calling, in the case of a stored property it only makes sense for the caller to choose the return type at the moment of creating the enclosing type, not in the moment of calling the property. Choosing the return types of some properties of an enclosing type at the moment of creation of the enclosing instance is what a type parameter is.

---

<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:** [June 4, 2021, 12:58pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/7 "2021-06-04T12:58:03Z")

</div>

> [@jeremyabannister](#):
>
> This is effectively the same as this:
> 
> ```swift
> typealias T = Int
> let foo = 7
> 
> ```
> 
> in the sense that after using `<T>` as the type of `foo` we can then reference `T` for the rest of the scope:
> 
> ```swift
> let foo: <T> = 7
> let maximumInteger = T.max // This is `Int.max`
> 
> ```

> [@jeremyabannister](#):
>
> However, the answer to your specific question is that in your example `T` would not be treated as a type parameter of `Queue` because it does not appear in the type of a _stored property_ of `Queue` .

So now, `<T>` is appeared in stored property. Is it treated as type parameter of `Queue`? Or, implicitly become `Int`? How about `<U>`?

```Swift
struct Queue {
    let foo: <T> = 7
    let bar: <U>
}

```

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 4, 2021, 12:59pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/8 "2021-06-04T12:59:24Z")

</div>

This:

> [@ensan-hcl](#):
>
> ```swift
> struct Queue {
> let foo: <T> = 7
> let bar: <U>
> }
> 
> ```

desugars to this:

```swift
struct Queue <U> {
    typealias T = Int
    let foo: T = 7
    let bar: U
}

```

---

<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:** [June 4, 2021, 1:23pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/9 "2021-06-04T13:23:16Z")

</div>

I see. It's consistent in desugaring. How about this point?

> [@ensan-hcl](#):
>
> And though there is no type name, the similar feature to what you expected for the former can be already done.
> 
> ```swift
> let foo: some Numeric = 7
> 
> ```
> 
> Therefore, it is a feature that reverse generics should treat. I think it should be like this.
> 
> ```swift
> let foo: <some T> = 7
> 
> ```

If we don't use reverse generics for this, there would be two really similar way to do the same thing.

* * *

(EDIT)

What I want to say is, it is far more readable to use these things like this:

```Swift
// these two things are equal
let π: <T: ExpressibleByFloatLiteral> = 3.14
var π: <T: ExpressibleByFloatLiteral> {
    return 3.14
}

// these three things are equal
let π: <some T: ExpressibleByFloatLiteral> = 3.14
var π: <some T: ExpressibleByFloatLiteral> {
    return 3.14
}
var π: some ExpressibleByFloatLiteral {
    return 3.14
}

```

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 4, 2021, 3:45pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/10 "2021-06-04T15:45:14Z")

</div>

> [@Paul\_Cantrell](#):
>
> The `func f<T>` syntax is a confusing one for first-timers. I would be curious to see, in a little informal user study of people new to generics, whether `func f(x: <T>)` makes any more sense to them.

Another slightly more indirect way that this change might make generics more accessible to newcomers is that generic parameters will likely have more expressive names when they don't have to be repeated:

```swift
func receive (_ input: <Input>)

```

vs.

```swift
func receive <T> (_ input: T)

```

I remember that for at least the first year of my Swift journey my fleeting interactions with the concept of Generics in Swift left me with the notion that `T` was some built-in special type name that did... I didn't know. The moment that I understood that `T` was an arbitrarily chosen demo name and that the generic parameter name was mine to choose I began to understand more technically what generics were and how they worked. In the end I found it quite simple.

How absurd! One main barrier to entry for generics that kept me at arm's length for a time was simply the confusion that was caused for me by the ubiquity of the name `T` in the mainstream demonstration of generic code.

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [June 4, 2021, 3:55pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/11 "2021-06-04T15:55:28Z")

</div>

Yes, `T` is really confusing. There’s nothing that stops us from using better name now! In fact, IIRC, getting people to use meaningful names for type parameters has been a personal mission of someone on the Swift core team (Joe Groff, I think maybe?).

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 4, 2021, 3:56pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/12 "2021-06-04T15:56:36Z")

</div>

> [@ensan-hcl](#):
>
> I see. It's consistent in desugaring. How about this point?

> [@ensan-hcl](#):
>
> If we don't use reverse generics for this, there would be two really similar way to do the same thing.

I've thought a bit more about it, and I have some new understandings, but I still don't have it clear and I don't have time to get it totally clear at the moment.

One main piece of the answer I'm coming to though is that `<Name>` is not a tool for erasure. I'll give a quick example from current Swift:

```swift
struct A <T: Numeric> { }
func foo <T: AdditiveArithmetic> (a: A<T>) {
    // Inside the body of this function T is known to be Numeric
}

```

What this example demonstrates is that the generic signature of the function does force `T` to at least conform to `AdditiveArithmetic`, but it does not "erase" `T` down to the level of `AdditiveArithmetic` - `T` has the maximum level of detail that can be known about it.

Therefore, these two lines do different things:

```swift
let foo: <T: Numeric> = 7
let bar: some Numeric = 7

```

`foo` is known to be of type `Int` and has not been erased in any way, while `bar`, by way of the `some` keyword, has been meaningfully erased:

```swift
func takesInt (_ int: Int) { }
takesInt(foo) // 👍
takesInt(bar) // Error

```

#### Note:

In this case the `Numeric` constraint doesn't "do" anything:

```swift
let foo: <T: Numeric> = 7

```

but it is permitted the same way an explicit type is permitted:

```swift
let bar: Double = 1.5

```

Sometimes it is useful to be able to put an explicit type for the sake of guaranteeing a future compilation error if certain conditions change that you don't expect to change. For the same reason, we might want to add the `Numeric` constraint just to ensure that in the future we can freely change:

```swift
let foo: <T: Numeric> = 7

```

to:

```swift
let foo: <T: Numeric> = 7.1

```

but not:

```swift
let foo: <T: Numeric> = "will cause error"

```

---

<div class="post-metadata">

**Author:** ![jeremyabannister](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeremyabannister/32/10143_2.png) [@jeremyabannister](https://forums.swift.org/u/jeremyabannister)\
**Post date:** [June 4, 2021, 4:03pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/13 "2021-06-04T16:03:56Z")

</div>

> [@Paul\_Cantrell](#):
>
> There’s nothing that stops us from using better name now!

I personally lean toward meaningful type names despite heavier angle-bracket clutter in my own code. Nonetheless, the cost of adding additional characters to our generic function parameter names is higher when the name has to be forward declared:

```swift
func feed <Recipient: Eater> (_ recipient: Recipient)

```

vs:

```swift
func feed (_ recipient: <Recipient: Eater>)

```

The former might sadly tempt someone to write this instead:

```swift
func feed <Rcpt: Eater> (_ recipient: Rcpt)

```

---

<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:** [June 4, 2021, 4:40pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/14 "2021-06-04T16:40:06Z")

</div>

> [@jeremyabannister](#):
>
> Sometimes it is useful to be able to put an explicit type for the sake of guaranteeing a future compilation error if certain conditions change that you don't expect to change. For the same reason, we might want to add the `Numeric` constraint just to ensure that in the future we can freely change:

Yeah, but this is one of the initial motivations for opaque result type (reverse generics), isn't it?

> clients of `EightPointedStar` could end up relying on its exact return type, making it harder if the author of `EightPointedStar` wants to change how they implement its shape, such as if a future version of the library provides a generic `NPointedStar` primitive  
> (from: [SE-0244 Opaque Result Types](https://github.com/apple/swift-evolution/blob/main/proposals/0244-opaque-result-types.md#introduction))

Also, you said `takesInt(foo) // 👍 `, but it makes free change of type impossible. You can easily depends on the exact type, and so that change of exact type can break existing codes.

> [@jeremyabannister](#):
>
> Therefore, these two lines do different things:
> 
> ```swift
> let foo: <T: Numeric> = 7
> let bar: some Numeric = 7
> 
> ```
> 
> `foo` is known to be of type `Int` and has not been erased in any way, while `bar` , by way of the `some` keyword, has been meaningfully erased:

Yes, I agree with this. I'm sorry for my exaggeration of 'two really similar way to do the same thing'.

But I didn't find any really useful usage of this. Is there any reason to have shorthand for typealias using glorious `<T>`? Using it for normal generics makes much more sense and less confusing.

---

<div class="post-metadata">

**Author:** ![Syre](https://avatars.discourse-cdn.com/v4/letter/s/cdc98d/32.png) [@Syre](https://forums.swift.org/u/Syre)\
**Post date:** [June 4, 2021, 7:11pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/15 "2021-06-04T19:11:35Z")

</div>

> [@jeremyabannister](#):
>
> This:
> 
> > [@ensan-hcl](#):
> >
> > ````swift
> > > struct Queue {
> > let foo: <T> = 7
> > let bar: <U>
> > }
> > > ```
> > 
> > ````
> 
> desugars to this:
> 
> ```swift
> struct Queue <U> {
> typealias T = Int
> let foo: T = 7
> let bar: U
> }
> 
> ```

I think I would be strongly opposed to this, as it would remove the symmetry that we have right now between the actual type and the generic declaration.

If you inspect a variable and see that it's type is `Queue<Int>`, I think it makes perfect sense that the declaration be `struct Queue<T>`

That being said, the same symmetry concern doesn't apply to generic functions afaict, so I might be okay with that. However, I feel that there is a usability benefit both in function and type declarations in having a defined and single place to put the generic type declarations.

```swift
struct Queue {
    // ... stuff ...

    // Many, many lines into the declaration of Queue I now decide that Queue is generic?
    var elements: [<Element>]
}

```

This feels unintuitive to me, If I didn't write `Queue`, and was just examining it with fresh eyes, I think I would want to know up front that `Queue` is actually `Queue<Element>`.

---

<div class="post-metadata">

**Author:** ![bdriscoll](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bdriscoll/32/17821_2.png) [@bdriscoll](https://forums.swift.org/u/bdriscoll)\
**Post date:** [June 4, 2021, 8:12pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/16 "2021-06-04T20:12:15Z")

</div>

Personally, I am not a fan of this proposal. Among other things:

- If you can use a named generic parameter in a signature before introducing it, you lose the intuitive property of being able to understand your code and its lexical scoping rules top-to-bottom and left-to-right.
- As brought up earlier in the thread, things get particularly confusing w.r.t. desugaring generic parameters on struct declarations.
- It adds a lot of additional syntactic complexity in a way that diverges significantly from other popular imperative languages that feature generics (more for a beginner to learn) for what feels like relatively little convenience.

---

<div class="post-metadata">

**Author:** ![justinmilo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/justinmilo/32/5453_2.png) [@justinmilo](https://forums.swift.org/u/justinmilo)\
**Post date:** [June 4, 2021, 9:19pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/17 "2021-06-04T21:19:39Z")

</div>

I like this idea a lot.

I always get angle bracket blindness at the start of the generic signature. This really helps with that.

It reminds me of moving from a language where all variables had to be listed at the start of the scope to one where variables could be declared anywhere within the body.  
+1

---

<div class="post-metadata">

**Author:** ![jayton](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jayton/32/5592_2.png) [@jayton](https://forums.swift.org/u/jayton)\
**Post date:** [June 5, 2021, 6:56am UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/18 "2021-06-05T06:56:54Z")

</div>

> [@Syre](#):
>
> This feels unintuitive to me, If I didn't write `Queue` , and was just examining it with fresh eyes, I think I would want to know up front that `Queue` is actually `Queue<Element>` .

Generics are analogous to functions at the type level; this sounds like a function where arguments can be declared in the body.

```swift
func add5() -> Int {
    return <x> + 5 // x is an argument whose type is inferred. Yay?
}

```

---

<div class="post-metadata">

**Author:** ![sveinhal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sveinhal/32/3992_2.png) [@sveinhal](https://forums.swift.org/u/sveinhal)\
**Post date:** [June 5, 2021, 8:51am UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/19 "2021-06-05T08:51:36Z")

</div>

While I think this idea might have merit, I am strongly against it for the simple reason that we already have a generics syntax, and I do not want proliferation of new orthogonal syntax for existing features.

---

<div class="post-metadata">

**Author:** ![Finagolfin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/finagolfin/32/34388_2.png) [@Finagolfin](https://forums.swift.org/u/Finagolfin)\
**Post date:** [June 5, 2021, 5:01pm UTC](https://forums.swift.org/t/a-new-idea-about-generics/49251/20 "2021-06-05T17:01:43Z")

</div>

Thanks for raising the issue, I've always felt Swift made a mistake by adopting the hackneyed angle bracket syntax (does it have a way out of [the numerous issues caused by this in C++](https://blog.aaronballman.com/2011/05/semantic-whitespace/)? I haven't looked). In fact, [the Zig approach of just making generics a subset of compile-time meta-programming](https://ziglang.org/documentation/master/#comptime) (skip down to the section on generic data structures to see how it works) seems a much cleaner approach, unburdened by the past (I'm not a compiler engineer and don't know if that approach would limit generics in some way, would think not).

Of course, Swift has no compile-time meta-programming, even though [a limited version has been mooted](https://gist.github.com/marcrasi/b0da27a45bb9925b3387b916e2797789). I can understand why it has been delayed, as understandability and tooling of such metaprogramming in every other language is a mess, but at some point you have to buckle down and add it, as even C has a botched approach with its preprocessor.

I recommend [this 2019 cross-language overview](https://thume.ca/2019/07/14/a-tour-of-metaprogramming-models-for-generics/) to anyone interested in the topic.

[Next page](https://forums.swift.org/t/a-new-idea-about-generics/49251.md?page=2)
