Generic `typealias`s


(Dapeng Gao) #1

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


(Chris Lattner) #2

It would be handy if Swift can support generic `typealias`s, which would probably look like this:

typealias Handler<Element> = [Element] -> Void

Yes, this is definitely something that I (at least) would like to see. Patches welcome :-)

-Chris

···

On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng@icloud.com> wrote:

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Joe Groff) #3

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.

-Joe

···

On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng@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


(Lily Ballard) #4

I've filed a ticket on bugs.swift.org to serve as a hint to any
interested party that this is something that is actively desired and
patches are welcome.

https://bugs.swift.org/browse/SR-64

I figure that's probably the right course of action for obvious
improvements that we know we want but aren't candidates for the full swift-
evolution process.

-Kevin Ballard

···

On Fri, Dec 4, 2015, at 04:08 PM, Joe Groff wrote:

On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng@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.

-Joe

_________________________________________________
swift-evolution mailing list swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Douglas Gregor) #5

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

···

Sent from my iPhone

On Dec 4, 2015, at 4:08 PM, Joe Groff <jgroff@apple.com> wrote:

On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng@icloud.com> wrote:


(TJ Usiyan) #6

I concur and I think that there is should be more to this idea. I, at
least, would want partial specialization as part of this. Consider Either
and Result:

`enum Either {
    case .Left
    case .Right
}

typealias Result<SuccessValue> = Either<NSError, SuccessValue>`

How (can I?) specify just one of the types or, possibly, constrain the left
side so as to avoid the need to provide a concrete type "NSError" there?

This next bit is probably another proposal. Assuming that that gets sorted
out, it would be useful to alias methods, properties, cases, etc for the
new name. `<Some keyword> case Result.Success = case Either.Left`

TJ

···

On Fri, Dec 4, 2015 at 12:04 PM, Dapeng Gao <gdapeng@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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Austin Zheng) #7

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@apple.com> wrote:

Sent from my iPhone

On Dec 4, 2015, at 4:08 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng@icloud.com <mailto:gdapeng@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Austin Zheng) #8

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@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@apple.com <mailto:dgregor@apple.com>> wrote:

Sent from my iPhone

On Dec 4, 2015, at 4:08 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

On Dec 4, 2015, at 3:04 AM, Dapeng Gao <gdapeng@icloud.com <mailto:gdapeng@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution