> On 8. Aug 2017, at 04:35, David Sweeris via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> 
>> On Aug 7, 2017, at 3:00 PM, Logan Shire via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> One of my longstanding frustrations with generic types and protocols has 
>> been how hard it is to work with them when their type is unspecified.
>> Often I find myself wishing that I could write a function that takes a 
>> generic type or protocol as a parameter, but doesn’t care what its generic 
>> type is.
>> 
>> For example, if I have a type:
>> 
>> struct Foo<T> {
>>     let name: String
>>     let value: T
>> }
>> 
>> or:
>> 
>> protocol Foo {
>>     associatedtype T
>>     var name: String { get }
>>     var value: T { get }
>> }
>> 
>> And I want to write a function that only cares about Foo.name, I’d like to 
>> be able to:
>> 
>> func sayHi(to foo: Foo) {
>>     print("hi \(foo.name)")
>> }
>> 
>> But instead I get the error, “Reference to generic type Foo requires 
>> arguments in <…>”
>> 
>> Also, when you want to have a polymorphic array of generic types, you can’t:
>> 
>> let foos: [Foo] = [Foo(name: "Int", value: 2), Foo(name: "Double", value: 
>> 2.0)]
>> 
>> And if you remove the explicit type coercion, you just get [Any]
>> 
>> let foos = [Foo(name: "Int", value: 2), Foo(name: "Double", value: 2.0)]
>> 
>> I wish that could be inferred to be [Foo].
> 
> What happens if you try to say "foos: [Foo<Any>] = ..."? 
> 

Foo<Int> and Foo<Any> are very different. Otherwise, you could take a Foo<Int>, 
cast it to a Foo<Any> and set a String as its value.

I think what he means are partial generics, e.g: Foo<_>.

> 
> 
>> I’d like to propose being able to use the non-generic interface of a type 
>> normally. 
>> I.e. if you have a type Foo<T>, it is implicitly of type Foo as well. The 
>> type Foo could be used like any other type.
>> It could be a parameter in a function, a variable, or even the generic type 
>> of another type (like a Dictionary<String, Foo>)
>> 
>> The only restriction is that if you want to call or access, directly or 
>> indirectly, a function or member that requires the generic type,
>> the generic type would have to be known at that point.
>> 
>> Foo<T> should be able to be implicitly casted to Foo wherever you want, and 
>> Foo could be cast to Foo<T> conditionally.
>> Initializers would still obviously have to know the generic type, but given 
>> the above example, you should be able to:
>> 
>> let names = foos.map { $0.name }
>> 
>> However, you could not do the following:
>> 
>> let foos = [Foo]()
>> 
>> Because the initializer would need to know the generic type in order to 
>> allocate the memory.
>> 
>> Let me know what you think!
> 
> 
> The idiomatic solution would be to create a `Named` protocol with a `var 
> name: String {get}` property, and write your function like `func sayHi(to 
> foo:Named) {...}`. However, this `Named`protocol is really pretty trivial -- 
> its purpose is simply to "degenericify" a generic type, not to provide any 
> semantic meaning. Perhaps an analogy could be drawn between such "trivial 
> protocols" and how we sometimes view tuples as "trivial structs"? Dunno, 
> maybe I'm just trying to turn two trees into a forest, but this kinda smells 
> like it might be part of a bigger issue, and if it is I'd rather tackle that 
> and then see if we still need to address anything here.
> 
> +1, either way, though.
> 
> - Dave Sweeris
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to