Nested (non-capturing) type aliases
This is an issue to discuss nested (non-capturing) type aliases. The current full text of the proposal can be found here.
Right now type aliases can only be used at the top level. The goal of this document is to propose a design to allow them within other classifiers, in case they do not capture any type parameters of the enclosing declaration.
I personally think this proposal is trivial and nothing to discuss(in design)(I support it, certainly). Btw, sorry for the off-topic, @serras now that you mentioned them and you are in Jetbrains Kotlin team,
Going even further than capture, it is a non-goal of this KEEP to provide abstraction capabilities over type aliases, like abstract type members in Scala or associated type synonyms in Haskell. Roughly speaking, this would entail declaring a type alias without its right-hand side in an interface or abstract class, and "overriding" it in an implementing class.
interface Collection { typealias Element } interface List<T>: Collection { typealias Element = T } interface IntArray: Collection { typealias Element = Int }
Will kotlin support these language features(i.e. capturing type alias, abstract type members, associated type synonyms, or let's say further, dependent functions) in future?
Will kotlin support these language features?
I cannot say for sure, although I highly doubt that anything resembling type-level computation would make it into the language. The only exception is many capturing type aliases (you can even see that the first iterations of the proposal in the Git history had those), but there are interesting questions like how would instantiation work for things like:
class Example<T> {
inner typealias A = List<T>
}
Should one require an instance of A to call the List constructor? How does it relate to things like listOf? Because of those questions we've decided to go first with the obviously useful feature (non-capturing type aliases) and then move to capturing type aliases if needed.
This feature will appear as experimental in Kotlin 2.2.0. This PR will remain open for discussion for some time after the initial release, to gather any feedback.
I understand why nested type aliases are not allowed to capture type parameters. However, why can't local type aliases capture them? A local type alias can't really "escape" in such a way as to leak its parameter (outside of some strange compiler bugs). Like I don't see how this can be problematic:
fun <T> foo() {
typealias ListT = List<T>
...
}
There are two main reasons for not allowing them (yet):
- Whatever the design, it should be uniform with nested type aliases. We don't want to end in a situation in which you may need a modifier to capture on nested aliases, but not on local ones.
- Even thought local type aliases seem "easier", there are some things that may happen in local contexts that may not happen in declaration contexts. For example, you may define an object that captures a value from outside (does it count as capturing?), or you may define an anonymous type (from an object). If we alias them, how should we proceed?
Since this feature is already released (nested type aliases are stable in 2.3.0, local ones are experimental), this KEEP discussion is being closed.