# \[Pitch 2\] Light-weight same-type requirement syntax

**URL:** <https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081>\
**Category:** Pitches\
**Created:** [February 3, 2022, 5:20pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081 "2022-02-03T17:20:44Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [February 4, 2022, 3:24am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/41 "2022-02-04T03:24:58Z")

</div>

Well, if that's doable it changes the calculus considerably. This is the first time I've even heard of the possibility of multi-self protocols. Would both a `Convertible(from: A, to: B)` and a `Convertible(from: B, to: A)` conformance be possible under this model?

---

<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:** [February 4, 2022, 3:43am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/42 "2022-02-04T03:43:38Z")

</div>

> [@Michael\_Ilseman](#):
>
> If it means we can have opaque return values with specified associated types, this is absolutely a much-needed feature.

> [@Michael\_Ilseman](#):
>
> while the fundamental limitation of not allowing multiple conformances is still present, allowing these types to be opaque return values could alleviate some of the bloat associated with these kinds of workarounds.

> [@Michael\_Ilseman](#):
>
> I've also hit this same issue in multiple different API I wanted to add to System. Without opaque return values with associated types, I couldn't justify shipping them.

This illustrates a greater point that I'd like to raise.

On the syntax, I'm personally unsure and a bit sceptical, but there is one part of this proposal that I'm very, very unhappy with: that it is actually two, very big features, bundled in to one proposal. That's generally considered bad form, as it means we can't fairly evaluate either of them in isolation.

Perhaps we'd accept the sugar anyway, or perhaps we wouldn't, but we're sort of "held hostage" (no malice implied) because it seems we can only get constrained opaque types if we also take the sugar. It's like meeting a lost traveller in the desert and offering them Coca Cola or nothing - they'll take it if there's no alternative, but you can't walk away from that and claim "people dying of thirst prefer Coca Cola!"

Moreover, the available constraints on opaque types are severely limited. You'd only be able to use them with protocols whose authors have declared one associated type to be more important than the others, and you'd only be able to constrain that particular type, and only with a same-type constraint (possibly subtypes too? But that's speculative and not formally part of the proposal). Those are _limitations of the sugar_, but because they come together, it applies to the (IMO more important) functional enhancements around constrained opaque types as well.

I'll consider Joe's response tomorrow because I'm unfamiliar with Haskell and it's too late to look in to it in depth, but I wanted to briefly touch on this point. This thing should be 2 proposals, and combining them does each feature, the language, and the community a disservice by unfairly shielding them from proper and balanced scrutiny.

---

<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:** [February 4, 2022, 3:53am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/43 "2022-02-04T03:53:57Z")

</div>

> [@Karl](#):
>
> On the syntax, I'm personally unsure and a bit sceptical, but there is one part of this proposal that I'm very, very unhappy with: that it is actually two, very big features, bundled in to one proposal. That's generally considered bad form, as it means we can't fairly evaluate either of them in isolation.

I'm not sure it would make sense to consider one without the other. If we allow one to write `func foo<T : Sequence<Int>>()` as shorthand for `func foo<T : Sequence>() where T.Element == Int`, why would we not also allow `func foo() -> some Sequence<Int>`, and vice versa?

The sugar applies in any position where the right-hand side of a protocol conformance requirement can appear; this happens to include inheritance clauses, where clauses, extensions, and opaque result types. I don't think there's much value in separating out into two or more proposals.

More general constraints on opaque result types can be accomplished with _named_ opaque result types; something like this for example:

```swift
func foo() -> <T, U> where T : Sequence, U : Sequence, T.Element == U.Element

```

This pitch does not foreclose the possibility of introduced named opaque result types.

> [@Karl](#):
>
> Moreover, the available constraints on opaque types are severely limited. You'd only be able to use them with protocols whose authors have declared one associated type to be more important than the others, and you'd only be able to constrain that particular type,

It's true that a protocol has to be designed with this usage in mind, but at the very least I'm pretty certain we can safely generalize to multiple generic arguments with the same syntax:

```swift
protocol DictionaryProtocol<Key, Value> { ... }

```

I plan on implementing that next week to experiment with.

---

<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:** [February 4, 2022, 4:00am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/44 "2022-02-04T04:00:46Z")

</div>

I'm not suggesting we take the sugar before opaque type constraints: I'm suggesting we need constraints on opaque types _before_ we consider sugaring them. Which means the sugar coming later.

> [@Slava\_Pestov](#):
>
> This pitch does not foreclose the possibility of introduced named opaque result types.

That's not the concern. The concern is that we have evaluations of the proposal like this:

> "If it means we can have opaque return values with specified associated types, this is absolutely a much-needed feature."

If I may rephrase to how I interpret that, it's saying "if I need to accept the sugar to get the feature I _really_ want, I'll take the sugar". Which is not as glowing an endorsement as it might seem on first reading. It also means _the order_ in which these features are added to the language affects how they are perceived. By combining the sugar with the functional enhancement it sugars, we lose the ability to fairly consider each of them separately on their individual merits.

---

<div class="post-metadata">

**Author:** ![ExFalsoQuodlibet](https://avatars.discourse-cdn.com/v4/letter/e/bbce88/32.png) [@ExFalsoQuodlibet](https://forums.swift.org/u/ExFalsoQuodlibet)\
**Post date:** [February 4, 2022, 8:11am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/45 "2022-02-04T08:11:45Z")

</div>

> [@Slava\_Pestov](#):
>
> At this point several people have pushed back. There's no real motivation for this restriction, except that it made my prototype implementation with the `@_primaryAssociatedType` attribute simpler. In principle I'm not opposed to generalizing it to allow multiple associated types (but at that point I'd like us to come up with a better term than "primary associated type").

Do you think that it could be confusing to have 2 or more primary associated typeS? Maybe. Ideally, it would be nice if we could come up with a name in which we replace `associated_` with something else, so an `associatedtype` would remain the same as it is right now, and the proposal would introduce some that's, conceptually, entirely new.

Here's some ideas:  
`primarytype`  
`requiredtype`  
`parameterizedtype`  
`characterizingtype`  
`constrainedtype`  
`identifyingtype`  
`definingtype`

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 4, 2022, 9:53am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/46 "2022-02-04T09:53:55Z")

</div>

I cannot believe how hard this syntax is being pushed. It makes me really sad actually. The evolution of Swift isn't a democracy, yet the whole process is being very well "selective" as authors of the proposals often times skip and ignore messages from the community which collide with their ideas outlined in the proposals.

I use Swift on nearly a daily basis and I care about the expressiveness of the language a lot, especially on the generics front. This syntax is not generic and should not allude to be generic. The pitched syntax is jumping over way too many hoops at once, but at what cost?

(A) The language already made a partial promise on the ability to create constraints using the `where` clause inside a `typealais` declaration, but it still hasn't delivered that feature to us.

(B) A fair while ago we already extensively discussed the problems in that area and pitched an alternative syntax which should provide some improvements while also maintaining the flexibility on the users side. That syntax was `Collection<.Index == Whatever>`.

Now this pitch (C):

- It tries to make it look like either (A) or (B) were mistakes and we need further improvements, although I as a Swift user never seen the daylight of any of those. You cannot judge on issues on something that never was delivered.
- It completely removes the flexibility which we could have with (A) and (B). What do you want me the developer to write when for instance `Collection` has only a single primary associated type being `Element` but I still want to constrain `Index` as well?

```swift
// How is this
Collection<Foo> where Index == Bar
// better than this (other than it being a few character shorter)
Collection<.Element == Foo, .Index == Bar>

```

- The pitched syntax is only focusing on "same-type" constraints while it isn't the only thing that is actually useful:

```swift
Collection<any P> // .Element == any P
// what if I want `Element` to actually conform to `P`?
Collection<.Element: P>

```

- The limitation of having a single primary associated type is artificial and just highlights how unsure this whole pitched syntax is.
- I don't even want to touch the discussion around generic protocols, because it seems there is a huge fear or other strong feelings against that feature which often times kills the whole conversation.

Long story short, I'm strongly against the currently pitched form of this proposal. So -1 for me. The last part of the alternative consideration is something that I personally would rather support as it builds on the integrity of the language rather than trying very hard to write a few less characters with some sugar code!

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [February 4, 2022, 10:21am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/47 "2022-02-04T10:21:37Z")

</div>

I very much agree with points raised against this, it's -1 from me against the pitch in its current form. I like the intention to help with the use cases, but the solution doesn't feel right to me because:

1. By reusing generics syntax, while not actually being a "generic protocol" it introduces more confusion.
2. If this is pitched sugar for a more general feature, I feel it would be more appropriate to pitch this more general feature first before introducing any sugar for it.
3. I don't think that the prior art of generic protocols (traits or type classes etc) has been sufficiently explored here. I see them being dismissed as "we don't need them", but that doesn't seem like a good justification. Rust and Haskell apparently did need them after all, and I would like to see how code using this feature in Rust and/or Haskell would translate to Swift without generic protocols. Or some other more detailed and more convincing explanation that addresses this point.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [February 4, 2022, 10:33am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/48 "2022-02-04T10:33:05Z")

</div>

One more thing:

> [@Michael\_Ilseman](#):
>
> If it means we can have opaque return values with specified associated types, this is absolutely a much-needed feature.

The alternative syntax can still drive this: `some Collection<.Element == some P>` or `some Collection<.Element: P>` which essentially means the same thing and on top of that, it actually provides more context on what is being constrained as often times protocols have a great set of hard discoverable associated types. IMO the currently pitched syntax adds more cognitive load to the protocol user. The user has to instinctively know the names of the associated types at the generic parameter type's position and their order.

```swift
protocol P<Element, Index> {}

// when reading the following:
// - I don't know the names of the associated types (if `P` is not my creation)
// - the ORDER of the associated types becomes important 
some P<String, Int> 

// even though this is a bit longer:
// - there is no need to remember the order of the associated types
// - IDEs with autocompletion can help discover the associated types after typing a leading dot
some P<.Index == Int, .Element == String> // same as `some P<.Element == String, .Index == Int>`

```

It also becomes impossible to skip associated types unless we want to mix this with placeholder type syntax:

```swift
some P<_, Int> 
some P<String, _> 
// vs.
some P<.Index == Int>
some P<.Element == String>

```

At least the shorter syntax adds cognitive load to my brain.

---

<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:** [February 4, 2022, 10:36am UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/49 "2022-02-04T10:36:13Z")

</div>

Also worth remembering:

In order for _library users_ to take advantage of this using protocols they import from a dependency, changes are needed at the declaration site. That means, initially, some protocols will support this feature (probably Apple's ones), and no other protocols will work. That's likely to be very confusing for users, and it will require a transition period before users can just take that support for granted.

What's more, they're then going to report those failures as bugs to the _library authors_, who are going to be pressured to duplicate their protocols behind `#if swift` guards because these declarations are incompatible with all prior versions of Swift:

```swift
#if swift(>=5.7)

public protocol MyProtocol<Thing> {
// ...
// some long protocol, including all of its:
// - other associated types
// - requirements
// - documentation for those associated types and requirements
// ...
}

#else

public protocol MyProtocol {
  associatedtype Thing
// ...
// some long protocol, including all of its:
// - other associated types
// - requirements
// - documentation for those associated types and requirements
// ...
}

#endif

```

So it's going to look like that, multiplied by _every protocol in your library_. Also, because it needs to be specified at the definition site, this isn't really just sugar -- this is the new way you're going to have to write every protocol from now on, because users are going to expect this syntax to work.

On the other hand, something which is purely use-site sugar (like `MyProtocol<.Thing: Numeric>`) would work with all protocols on day one. No transition period. No code duplication for library authors. It has a number of other benefits as well (such as a much smoother migration once you reach the limits of the sugar and need full generics syntax), but I want to focus on the above points.

---

<div class="post-metadata">

**Author:** ![regexident](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/regexident/32/1907_2.png) [@regexident](https://forums.swift.org/u/regexident)\
**Post date:** [February 4, 2022, 12:05pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/50 "2022-02-04T12:05:30Z")

</div>

Big "agree" on everything @Karl, @DevAndArtist and @Max_Desiatov said so far.

This part:

> [@DevAndArtist](#):
>
> I cannot believe how hard this syntax is being pushed. It makes me really sad actually. The evolution of Swift isn't a democracy, yet the whole process is being very well "selective" as authors of the proposals often times skip and ignore messages from the community which collide with their ideas outlined in the proposals.

and this part in particular:

> [@Max\_Desiatov](#):
>
> I don't think that the prior art of generic protocols (traits or type classes etc) has been sufficiently explored here. I see them being dismissed as "we don't need them", but that doesn't seem like a good justification. Rust and Haskell apparently did need them after all, and I would like to see how code using this feature in Rust and/or Haskell would translate to Swift without generic protocols. Or some other more detailed and more convincing explanation that addresses this point.

Even the [Swift Generics Manifesto](https://github.com/apple/swift/blob/main/docs/GenericsManifesto.md#generic-protocols) addresses "generic protocols" in the very same dismissive tone and in the same hand-wavy manner based on the weird straw-man argument that "people misuse the term" and thus the real thing is of no use to Swift:

> One of the most commonly requested features is the ability to parameterize protocols themselves. […] Implicit in this feature is the ability for a given type to conform to the protocol in two different ways. […] Most of the requests for this feature actually want a different feature.

Not only is the last part evidently wrong (i.e. none of the request to "please consider generic protocols as future addition to the language" in this or the previous pitch discussion were "actually asking for a different feature" afaict), but it also fails to provide any proper argument against generic protocols in Swift whatsoever.

How does the Swift team plan to fill the gaps that I outlined further up in the discussion if not by some kind of generic protocols (name them however you want)?

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [February 4, 2022, 12:11pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/51 "2022-02-04T12:11:34Z")

</div>

I do like the parens syntax suggested above. While it is floated as some potential future syntax for "generic protocols", what if it's used for the syntax sugar proposed in the pitch?

```swift
protocol Sequence(Element) {
  // ...
}

func concatenate<S : Sequence(String)>(_ lhs: S, _ rhs: S) -> S {
  // ...
}

```

This also could resolve the issue with throwing associated type of `AsyncSequence` by reusing the familiar syntax for default arguments:

```swift
protocol AsyncSequence(Element, Failure = Never) {
    associatedtype Iterator : AsyncIteratorProtocol
      where Element == Iterator.Element
  // ...
}

```

This way `some AsyncSequence(Int)` is equivalent to `some AsyncSequence(Int, Never)`, while still allowing a more explicit `some AsyncSequence(Int, Error)` form for throwing async sequences.

One other benefit is that this still leaves the possibility for some future "generic protocols" open without introducing any confusion with existing features related to generics.

---

<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:** [February 4, 2022, 4:02pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/52 "2022-02-04T16:02:34Z")

</div>

A few thoughts:

I think that "normal" protocols with associated types are uncontroversially far more useful than generic protocols. Indeed, we have made it (nearly) to Swift 6 without significant outcry for true generic protocols—I don't believe they represent a dire expressivity gap in the language as would be felt without `associatedtype`. (Granted, perhaps this is a lack of imagination on my part due to the fact that we _have_ PATs and we don't have generic protocols, but I don't think so.)

At the point of use of protocols with associated types, I think the angle bracket syntax matches what most Swift programmers (especially new Swift programmers) expect to "just work". An `Array` of `String`s is spelled `Array<String>`, it seems natural to me that "some `Collection` which contains `String`s" be spelled `some Collection<String>`. I view this alignment as highly desirable—the status quo of having to drop down to `where` clauses is a clear design gap, and the `Collection<.Element == String>` variants still introduce a significant departure from the fundamental 'thing' that people are trying to express. There really _is_, conceptually, a 'primary' associated type for `Collection`, with other associated types being secondary.

Is there a fundamental issue on the _use_ side where same-type constraints differs in behavior from generic protocols? The best example I've seen in this thread is the confusion that may arise from attempting to conform to, e.g., `Collection<String>`, but I expect such situations will be vastly rarer than trying to _use_ `some Collection<String>`, so I'm not convinced that it alone justifies disadvantaging the point-of-use syntax. It seems likely that we could offer a straightforward diagnostic to turn `struct Lines : Collection<String> { ... }` from the proposal into the likely-intended `typealias` version.

Particularly if there's another reasonable formulation of generic protocols (such as "multi-`Self` protocols" as mentioned by Joe) that covers all the use cases while still being markedly different than 'normal' generic types, I think it is justifiable to give same-type constraints the 'privileged' angle bracket syntax and leave this other feature for potential future consideration. Perhaps a loss for perfect purity of Swift's angle-brackets-as-generics syntax, but IMO it is a pragmatic choice that will make the language more usable in the vast majority of cases.

Of course, I'm making a lot of broad claims here based on gut instinct. It would be great if we had some empirical data that could help inform this proposal, but I'm not sure exactly what form that would take. We don't exactly incorporate scientific user studies into the evolution process. 😅

---

<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:** [February 4, 2022, 5:22pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/53 "2022-02-04T17:22:50Z")

</div>

> [@Jumhyn](#):
>
> It seems likely that we could offer a straightforward diagnostic to turn `struct Lines : Collection<String> { ... }` from the proposal into the likely-intended `typealias` version.

Or, better, we accept this shorthand spelling as-is also.

---

<div class="post-metadata">

**Author:** ![bzamayo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bzamayo/32/764_2.png) [@bzamayo](https://forums.swift.org/u/bzamayo)\
**Post date:** [February 4, 2022, 5:28pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/54 "2022-02-04T17:28:35Z")

</div>

I like the shorthand as proposed, even though I know it is overloading the syntax with generics it's compelling to me. `Collection<String>` feels very natural if I just want to map a collection of strings, and I think there is sufficient leeway for evolution like `Collection<String, .Index == Foo>` or whatever down the road.

---

<div class="post-metadata">

**Author:** ![Nickolas\_Pohilets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nickolas_pohilets/32/10659_2.png) [@Nickolas\_Pohilets](https://forums.swift.org/u/Nickolas_Pohilets)\
**Post date:** [February 4, 2022, 5:33pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/55 "2022-02-04T17:33:46Z")

</div>

-1, from me, mostly because of prioritization. As @Karl wrote earlier, this proposal tries to address both expressiveness and light-weight syntax for common cases.

I think we should address expressiveness first, and return to discussion of light-weight syntax after gaining practical experience with constrained protocols in opaque types, existentials and typealiases in production.

If we can express constrained protocols in typealiases, then we may not need lightweight syntax at all:

```swift
/// SequenceOf is a constraint
/// Constraints are generalization of protocols
/// Constraints are reusable pieces of where clause
/// Constraints can be generic
typealias SequenceOf<T> = Sequence where Element == T
func concatenate<S : SequenceOf<String>>(_ lhs: S, _ rhs: S) -> S {
   ...
}

```

---

<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:** [February 4, 2022, 6:35pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/56 "2022-02-04T18:35:06Z")

</div>

> [@Karl](#):
>
> What's more, they're then going to report those failures as bugs to the _library authors_ , who are going to be pressured to duplicate their protocols behind `#if swift` guards because these declarations are incompatible with all prior versions of Swift:

Is this not a concern with every new hypothetical language feature though?

---

<div class="post-metadata">

**Author:** ![pyrtsa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pyrtsa/32/740_2.png) [@pyrtsa](https://forums.swift.org/u/pyrtsa)\
**Post date:** [February 4, 2022, 6:40pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/57 "2022-02-04T18:40:17Z")

</div>

> [@Slava\_Pestov](#):
>
> Is this not a concern with every new hypothetical language feature though?

In this case it wouldn't be as bad if you could retroactively add the primary associated type to the protocol; then only that extension part would go between the `#if`.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [February 4, 2022, 7:18pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/58 "2022-02-04T19:18:22Z")

</div>

Yes, users either need to wait to adopt features or add conditionals to adopt them while still supporting other version. For instance, I needed to add some `swift(>=5.5)` blocks to Alamofire to support the new static member capabilities. However, this case, as Karl pointed out, is especially egregious, as, due to Swift's limited `#if` syntax, it requires duplicating the entire protocol definition to just to support some small bit of new syntax. That's basically the worst case scenario. Community adoption of the feature will be very low until they reasonably require the right version of Swift, which usually occurs once Apple stops accepting App Store submission with older versions of Xcode, and sometimes not even then. So any feature which can't be easily adopted with `swift` blocks will necessarily lag in adoption, which is bad for the language.

Of course, there are a lot of things Apple could do to help this case that aren't related to the language it self, but...

---

<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:** [February 4, 2022, 7:59pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/59 "2022-02-04T19:59:19Z")

</div>

> [@DevAndArtist](#):
>
> (A) The language already made a partial promise on the ability to create constraints using the `where` clause inside a `typealais` declaration, but it still hasn't delivered that feature to us.

This feature would need a detailed pitch outlining the precise semantics. Typealiases can appear in many places; if we're introducing a new kind of typealias we can to spell out where they're allowed and where they're forbidden, and what the behavior is in each case.

Another consideration is that a hypothetical typealias for where clauses would also not be as ergonomic as the concise syntax I'm promising in many instances because you'd have to _name_ the alias.

> [@DevAndArtist](#):
>
> It completely removes the flexibility which we could have with (A) and (B). What do you want me the developer to write when for instance `Collection` has only a single primary associated type being `Element` but I still want to constrain `Index` as well?

The syntax is not meant to replace where clauses entirely. You can still write a where clause.

> [@DevAndArtist](#):
>
> I don't even want to touch the discussion around generic protocols, because it seems there is a huge fear or other strong feelings against that feature which often times kills the whole conversation.

I think we need to articulate what we mean by generic protocols. A protocol type constructor instantiated on a set of concrete types doesn't seem like what you want; I think rather folks are asking for multi-parameter type classes. Today a protocol conceptually has a single 'Self' generic parameter; a multi-parameter type class would have multiple 'Self' types, none of them more privileged over another; where any conformance stated in a requirement or extension to such a protocol involves multiple 'Self' types. I'm not sure `Self1 : Proto<Self2>` syntax is the one that you want here.

---

<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:** [February 4, 2022, 8:01pm UTC](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081/60 "2022-02-04T20:01:50Z")

</div>

> [@Nickolas\_Pohilets](#):
>
> `typealias SequenceOf<T> = Sequence where Element == T`

This syntax is ambiguous because you just defined a protocol where the underlying type is the existential type `any Sequence`. The parameter `T` that you instantiate the type constructor with doesn't appear in the underlying type, so it doesn't play a role here.

However note that you can already express something like this via requirement inference in parameter position, just slightly awkwardly:

```swift
typealias SequenceOf<S, E> = S where S : Sequence, S.Element == E

func contains<S, E>(_ seq: SequenceOf<S, E>, _ elt: E) -> Bool {}

```

[Previous page](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081.md?page=2)

[Next page](https://forums.swift.org/t/pitch-2-light-weight-same-type-requirement-syntax/55081.md?page=4)
