# .init\<Subject: CustomStringConvertible\>(xxx instance: Subject) vs. .init(xxx instance: CustomStringConvertible)

**URL:** <https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219>\
**Category:** Using Swift\
**Created:** [October 15, 2020, 6:07pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219 "2020-10-15T18:07:37Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [October 15, 2020, 6:07pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/1 "2020-10-15T18:07:37Z")

</div>

From [my previous post asked why there are four versions of String.init(describing:) when the most general one can suffice](https://forums.swift.org/t/question-re-string-init-describing-overloads-why-there-are-four/41172/18), learned a revelation to me:

> Value of protocol type 'CustomStringConvertible' cannot conform to 'CustomStringConvertible'; only struct/enum/class types can conform to protocols

so because of above, this:

```swift
String.init(describing: Foo() as CustomStringConvertible)

```

does not match to the `<Subject: CustomStringConvertible>` version, it match to the most general `<Subject>` version.

but I find that it can be written this way instead:

```swift
String.init(describing instance: CustomStringConvertible) { ... }

```

and when written this way, it would call the matching version and do not have the "Value of protocol type 'CustomStringConvertible' cannot conform to 'CustomStringConvertible'" problem.

So, why are the `String.init(describing:)` written with generic? Why not just protocol type as parameter type like above? So passing protocol parameter calls the specific version.

With the way `String.init(describing:)`'s are written now, when you only have a protocol type value, it will call the most general and cannot call the specific one.

> **My playground:**
>
> ```swift
> //: [Previous](@previous)
> 
> extension String {
> // declaring this way with generic, protocol parameter match to the 4th call
> init<Subject: TextOutputStreamable>(xxx instance: Subject) {
> print("xxx11111")
> self.init(describing: instance)
> }
> init<Subject: CustomStringConvertible>(xxx instance: Subject) {
> print("xxx2222")
> self.init(describing: instance)
> }
> init<Subject: CustomStringConvertible & TextOutputStreamable>(xxx instance: Subject) {
> print("xxx3333")
> self.init(describing: instance)
> }
> init<Subject>(xxx instance: Subject) {
> print("xxx4444")
> self.init(describing: instance)
> }
> 
> // but declaring this way, protocol is match to exact protocol param type call!
> init(yyy instance: TextOutputStreamable) {
> print("yyy11111")
> self.init(describing: instance)
> }
> init(yyy instance: CustomStringConvertible) {
> print("yyy2222")
> self.init(describing: instance)
> }
> init(yyy instance: CustomStringConvertible & TextOutputStreamable) {
> print("yyy3333")
> self.init(describing: instance)
> }
> init<Subject>(yyy instance: Subject) {
> print("yyy4444")
> self.init(describing: instance)
> }
> }
> 
> extension String.StringInterpolation {
> mutating func appendInterpolation(_ instance: TextOutputStreamable?, default defaultValue: @autoclosure () -> String) {
> print("-a1-")
> // this only match to 4th generic one
> appendLiteral(instance.map(String.init(xxx:)) ?? defaultValue())
> // but this match to specific one
> appendLiteral(instance.map(String.init(yyy:)) ?? defaultValue())
> }
> 
> mutating func appendInterpolation(_ instance: CustomStringConvertible?, default defaultValue: @autoclosure () -> String) {
> print("-a2-")
> appendLiteral(instance.map(String.init(xxx:)) ?? defaultValue())
> appendLiteral(instance.map(String.init(yyy:)) ?? defaultValue())
> }
> 
> mutating func appendInterpolation(_ instance: (CustomStringConvertible & TextOutputStreamable)?, default defaultValue: @autoclosure () -> String) {
> print("-a3-")
> appendLiteral(instance.map(String.init(xxx:)) ?? defaultValue())
> appendLiteral(instance.map(String.init(yyy:)) ?? defaultValue())
> }
> 
> mutating func appendInterpolation<Subject>(_ instance: Subject?, default defaultValue: @autoclosure () -> String) {
> print("-a4-")
> appendLiteral(instance.map(String.init(xxx:)) ?? defaultValue())
> appendLiteral(instance.map(String.init(yyy:)) ?? defaultValue())
> }
> }
> 
> struct Foo: CustomStringConvertible, TextOutputStreamable {
> func write<Target>(to target: inout Target) where Target : TextOutputStream {
> target.write("Text Output Streamable")
> }
> 
> var description: String { "Custom String Convertible" }
> }
> 
> print("Interpolation", "let s1 = Foo() as CustomStringConvertible")
> let s1 = Foo() as CustomStringConvertible
> print("\(s1, default: "s1 is nil")")
> // print out:
> //-a2-
> //xxx4444
> //yyy2222
> //Text Output StreamableText Output Streamable
> 
> print("Interpolation", "let s2 = Foo()")
> let s2 = Foo()
> print("\(s2, default: "s2 is nil")")
> //print out:
> //Interpolation let s2 = Foo()
> //-a3-
> //xxx4444
> //yyy3333
> //Text Output StreamableText Output Streamable
> 
> //: [Next](@next)
> 
> ```

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [October 15, 2020, 7:26pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/2 "2020-10-15T19:26:33Z")

</div>

You may want to checkout this thread–([Why does String's "init\<T\>(\_ value: T) where T : LosslessStringConvertible" use a generic constraint?](https://forums.swift.org/t/why-does-strings-init-t-value-t-where-t-losslessstringconvertible-use-a-generic-constraint/39603))

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [October 16, 2020, 12:29am UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/3 "2020-10-16T00:29:41Z")

</div>

"box", "existential": is there somewhere I can read up on these to get some understanding how these work? Is "existential" short for "existential container"?

So struct when referred to by the protocol it implements, it turns into an "existential"?

And so both of these work:

```swift
// 1
String.init<Subject: CustomStringConvertible>(describing instance: Subject) { ... } 
// 2
String.init(describing instance: CustomStringConvertible) { ... }

```

but 1 call to the `instance` param's methods/properties are faster because direct call vs. 2 might be indirect but `ExistentialSpecializer` can make the calls direct, too?

But with the generic version, this:

```swift
String.init(describing: Foo() as CustomStringConvertible)

```

end up calling the most generic overloaded version with the slowest internals.

Instead of letting the compiler resolve the call, is there anyway to "specify" the version I want, something like:

```swift
String.init< CustomStringConvertible>(describing: Foo() as CustomStringConvertible)

```

(Edit: maybe since the argument is an existential, it just cannot call this)

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [October 16, 2020, 1:45am UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/4 "2020-10-16T01:45:22Z")

</div>

> [@young](#):
>
> "box", "existential": is there somewhere I can read up on these to get some understanding how these work? Is "existential" short for "existential container"?

These are existential types. [SO–What is an existential type?](https://stackoverflow.com/questions/292274/what-is-an-existential-type).

I think Rust uses `impl T` for an existential that implements/conforms to `T`. Swift uses `T` for both. I saw it somewhere on this forum that the point is to make it easier to grasp for the beginner, but ends up causing some other _unpleasant_ confusion instead.

---

<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:** [October 16, 2020, 11:06am UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/5 "2020-10-16T11:06:38Z")

</div>

> [@young](#):
>
> So, why are the `String.init(describing:)` written with generic? Why not just protocol type as parameter type like above? So passing protocol parameter calls the specific version.

Basically, when you want to write generic code, use the language’s generics feature.

The only time you should really care about existentials is when you want to erase a type (e.g. because it’s a return type and you might return different types along different paths, or you want to keep the type secret, or you need a type-flexible stored property/local variable).

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [October 16, 2020, 4:35pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/6 "2020-10-16T16:35:04Z")

</div>

@young After digging for the post I mentioned in the previous comment, I stumble upon an old post that you might be interested in–[Improving the UI of generics](https://forums.swift.org/t/improving-the-ui-of-generics/22814).

---

<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:** [October 16, 2020, 9:24pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/7 "2020-10-16T21:24:10Z")

</div>

> [@Lantua](#):
>
> I think Rust uses `impl T` for an existential that implements/conforms to `T` . Swift uses `T` for both. I saw it somewhere on this forum that the point is to make it easier to grasp for the beginner, but ends up causing some other _unpleasant_ confusion instead.

I read around here that Rust used to do it the way we do. But the confusion was too much. I guess we should do it too, like a "`any MyProtocol`," and as soon as possible (like Swift 6).

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [October 17, 2020, 3:49am UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/8 "2020-10-17T03:49:46Z")

</div>

So I wonder: why not overload for both generic type and "existential" type parameter? and let the compiler choose whichever is best:

```swift
extension String {
    // 1
    init<Subject>(xxx instance: Subject) where Subject : CustomStringConvertible { ... }
    // 2
    init(xxx instance: CustomStringConvertible) { ... }
}

```

but unfortunately the compiler do not choose 1:

```swift
struct Foo: CustomStringConvertible {
    var description: String { "Custom String Convertible" }
}

// these both call 2
// case 1
_ = String.init(xxx: Foo()) // why the compiler not choose 1 here?
// case 2
_ = String.init(xxx: Foo() as CustomStringConvertible)

```

If the compiler can choose 1 if a Foo is passed, then we can have both.

---

<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:** [October 17, 2020, 1:34pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/10 "2020-10-17T13:34:56Z")

</div>

> [@young](#):
>
> ```swift
> // these both call 2
> // case 1
> _ = String.init(xxx: Foo()) // why the compiler not choose 1 here?
> // case 2
> _ = String.init(xxx: Foo() as CustomStringConvertible)
> 
> ```

That's a very interesting question, and I'm actually not clear as to the answer. What's more interesting, this behavior isn't the same for a custom protocol:

```swift
protocol P { }
struct S: P { }
extension String {
    init<T: P>(xxx t: T) { fatalError("C") }
    init(xxx p: P) { fatalError("D") }
}
String(xxx: S()) // error: Ambiguous use of 'init(xxx:)'

```

I wonder if the behavior observed is unintentional. I actually don't recall this particular question coming up before, at least in the context of initializers. @dabrahams @jrose @Douglas_Gregor?

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [October 17, 2020, 5:00pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/11 "2020-10-17T17:00:13Z")

</div>

> [@xwu](#):
>
> ```swift
> extension String {
> init<T: P>(xxx t: T) { fatalError("C") }
> init(xxx p: P) { fatalError("D") }
> }
> 
> ```

Since these two ( and also my two `init`'s) compile fine without ambiguity, it means the compiler definitely know the parameter types are different and the code is treated as correct. The fact the compiler is not able to call the correct overload or "ambiguous" compile error indicate something is wrong with the compiler.

I tried calling this in my playground:

> `String(xxx: S() as P)`

It compiled without ambiguity! and ran

---

<div class="post-metadata">

**Author:** ![young](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/young/32/7878_2.png) [@young](https://forums.swift.org/u/young)\
**Post date:** [October 31, 2020, 9:36pm UTC](https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/12 "2020-10-31T21:36:41Z")

</div>

So just now learned of [`@_disfavoredOverload`](https://forums.swift.org/t/how-to-determine-if-a-passed-argument-is-a-string-literal/41651/3) which solve the problem:

```swift
extension String {
    init<T: P>(xxx t: T) { fatalError("C") }
    @_disfavoredOverload
    init(xxx p: P) { fatalError("D") }
}

String(xxx: S()) // now calls "C"
String(xxx: S() as P) // now calls "D"

```

So back to my original wondering, String now has these four `init`'s:

```swift
init<Subject>(describing instance: Subject) where Subject : TextOutputStreamable
init<Subject>(describing instance: Subject) where Subject : CustomStringConvertible
init<Subject>(describing instance: Subject) where Subject : CustomStringConvertible, Subject : TextOutputStreamable
@_disfavoredOverload // need this to favor the "existential" overload proposed below
init<Subject>(describing instance: Subject)

```

the first three are fast but only called with exact generic type match, when call with "existential" (is this the correct term?), [the last one is called which is slow because it use reflection inside.](https://forums.swift.org/t/question-re-string-init-describing-overloads-why-there-are-four/41172/5)  
I think they should add these three overloads for efficiency to avoid calling the last generic version when called with "existential":

```swift
@_disfavoredOverload
init(describing instance: TextOutputStreamable) { ... }
@_disfavoredOverload
init(describing instance: CustomStringConvertible) { ... }
@_disfavoredOverload
init(describing instance: CustomStringConvertible & TextOutputStreamable) { ... }

```

> <https://github.com/apple/swift/issues/56261>
>
> | | |
> |------------------|-----------------|…
> |Previous ID | SR-13863 |
> |Radar | rdar://problem/71492268 |
> |Original Reporter | @mattyoung |
> |Type | New Feature |
> |Status | Closed |
> |Resolution | Won't Do |
>         
> \<details\>
> \<summary\>Additional Detail from JIRA\</summary\>
> 
> | | |
> |------------------|-----------------|
> |Votes | 0 |
> |Component/s | Standard Library |
> |Labels | New Feature |
> |Assignee | None |
> |Priority | Medium |
> 
>    
> 
> md5: 14b8acdeba460c8d67aaaa8f59f10bf3
> 
> \</details\>
> 
> 
> 
> 
> 
> \*\*Issue Description:\*\*
> 
> 
> Four overload currently:
> 
> init\\\<Subject\\\>(describing instance: Subject) where Subject : TextOutputStreamable  
> init\\\<Subject\\\>(describing instance: Subject) where Subject : CustomStringConvertible  
> init\\\<Subject\\\>(describing instance: Subject) where Subject : CustomStringConvertible, Subject : TextOutputStreamable  
> @\\\_disfavoredOverload // need this if the new overload are added  
> init\\\<Subject\\\>(describing instance: Subject)
> 
> First three are fast, last one slow and should be avoided if possible, but the fourth is called even when type is known:
> 
> String(describing: x as CustomStringConvertible)
> 
> this end up calling the last one which is slow. So to avoid calling this slow one, add these three for fast:
> 
> @\\\_disfavoredOverload  
> init(describing instance: TextOutputStreamable) { ... }  
> @\\\_disfavoredOverload  
> init(describing instance: CustomStringConvertible) { ... }  
> @\\\_disfavoredOverload  
> init(describing instance: CustomStringConvertible & TextOutputStreamable) { ... }
> 
> See:  
> \<https://forums.swift.org/t/question-re-string-init-describing-overloads-why-there-are-four/41172\>  
> \<https://forums.swift.org/t/init-subject-customstringconvertible-xxx-instance-subject-vs-init-xxx-instance-customstringconvertible/41219/12\>
