[swift-evolution] Generic `typealias`s
Austin Zheng
austinzheng at gmail.com
Sat Dec 5 00:03:18 CST 2015
A few clarifying addenda:
1. the comment "// identical to x : Dictionary<String : Int> = ..." should be "// identical to x : Dictionary<String, Int> = ..."
2. For proposal #2, the compiler should require that all type parameter aliases declared on the LHS of the "=" be used when declaring the underlying type on the RHS of the "=".
3. For proposal #2, the only valid values for the type arguments when declaring the underlying type on the RHS of the "=" are type parameter aliases declared on the LHS, and valid concrete types.
Best,
Austin
> On Dec 4, 2015, at 9:57 PM, Austin Zheng <austinzheng at gmail.com> wrote:
>
> Perhaps we should "formalize" a proposal as a starting point for further discussion/development.
>
> Currently, Swift supports defining an alias for an existing non-generic or fully bound generic type using the 'typealias' keyword:
>
> typealias Foo = Int
> typealias Bar = Dictionary<String : Int>
>
> In this example, the type referred to by the identifier 'Foo' is exactly equivalent to the existing type Int. Any occurrence of the type identifier "Int" can be replaced in a Swift source code text by the typealias identifier "Foo" without changing the behavior of the program.
>
> When a typealias is defined, the underlying type can be the underlying type of another typealias:
>
> typealias Baz = Foo // Baz is typealias of Int now
>
> However, the typealias mechanism does not allow an unbound generic type to be typealiased:
>
> // This fails
> typealias MyArray = Array
> // as does this
> typealias MyArray<T> = Array<T>
>
> There are at least two potential ways to extend the typealias mechanism to support typealiasing unbound generic types.
>
> 1. Allow an unbound generic type to be directly typealiased to a different identifier. The alias can then be used in place of the original generic type identifier anywhere where the latter would have been valid, in such a way that a direct textual substitution of the original identifier for the new identifier (or vice versa) would not change the meaning of a Swift program.
>
> typealias HashMap = Dictionary
> let x : HashMap<String, Int> = ["hello" : 1234] // identical to x : Dictionary<String : Int> = ...
>
> 2. Allow an identifier to serve as a typealias to a partially specialized or fully unspecialized generic type. When declaring the typealias identifier, type parameter aliases can be declared as well within a generic type signature, akin to the "<>" generic type signature supported by type decls and function decls. When declaring the underlying type, unbound generic type parameters can then be bound to the type parameter aliases defined alongside the typealias identifier. Instead of an type parameter identifier, a concrete type can be used to partially specialize the type referred to by the typealias. For example:
>
> typealias HomogenousDict<T> = Dictionary<T, T>
> // A declaration of HomogenousDict<Int> is exactly equivalent to a declaration of Dictionary<Int, Int>.
> typealias DontDoThis<U, T> = Dictionary<T, U>
> // A declaration of DontDoThis<String, Int> is exactly equivalent to a declaration of Dictionary<Int, String>.
> // This might be a potential issue.
> typealias IntKeyDicts<Value> = Dictionary<Int, Value>
> // A declaration of IntKeyDicts<String> is then exactly equivalent to a declaration of Dictionary<Int, String>
>
> I hope this can serve as a starting point for discussion of the design of this feature, as well as identification of potential semantic and implementation issues.
>
> Best,
> Austin
>
>
>> On Dec 4, 2015, at 8:35 PM, Douglas Gregor <dgregor at apple.com <mailto:dgregor at apple.com>> wrote:
>>
>>
>>
>> Sent from my iPhone
>>
>> On Dec 4, 2015, at 4:08 PM, Joe Groff <jgroff at apple.com <mailto:jgroff at apple.com>> wrote:
>>
>>>
>>>> On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng at icloud.com <mailto:gdapeng at icloud.com>> wrote:
>>>>
>>>> It would be handy if Swift can support generic `typealias`s, which would probably look like this:
>>>>
>>>> typealias Handler<Element> = [Element] -> Void
>>>>
>>>> One common way to achieve this is to define a generic `struct` and use a nested `typealias`:
>>>>
>>>> struct HandlerWrapper<Element> {
>>>> typealias Hander = [Element] -> Void
>>>> }
>>>>
>>>> HandlerWrapper<SomeType>.Hander
>>>
>>> Definitely. I'd say this falls under the (totally arbitrary) umbrella of "obvious things that we didn't get around to implementing yet" instead of formal changes to the language. If you (or anyone else!) were to implement this, we'd consider the pull request immediately.
>>
>> I would rather not have such an umbrella, because how would one know what's in it and who gets to decide? Even "obvious" things need design, and some things that might sound like obvious goodness can benefit from review. ++ sounded like obvious goodness at one point in time, too.
>>
>> - Doug
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151204/d8743261/attachment-0001.html>
More information about the swift-evolution
mailing list