Here's a quick pitch. If someone would like spin off a formal proposal and possibly implement it, feel free to take over.
Similarly how we allow certain parts of our language to re-use language reserved keywords by surrounding them with back-ticks:
enum E {
case `default`
}
we should permit the usage of custom nested types named Type when its also surrounded by back-ticks.
struct S {
struct `Type` {
init() {}
}
}
// before: error - Type 'S.Type' has no member 'init'
// after: okay
S.`Type`.init()
This should also apply to the todays reserved singleton metatype namespace Protocol.
protocol P {}
extension P {
typealias `Protocol` = S.`Type`
}
P.`Protocol`.init()
3 Likes
xwu
(Xiaodi Wu)
2
Sure, this is consistent, but what use case do you have in mind for this?
I would like to use the Type as a nested nominal types where the term type fits better than kind for example.
1 Like
xwu
(Xiaodi Wu)
4
Evidently, but my question is: what use case do you have in mind for a nested nominal type named Type?
From the top of my head I could imagine having something like this:
protocol Interface {
var type: `Type` { get }
}
enum InterfaceType {
case …
}
extension Interface {
typealias `Type` = InterfaceType
}
This example isn‘t perfect as nesting inside protocols is a different topic, so as a workaround I had to use a typealias here.
If I still missed to answer your question, could you please re-phrase it?
xwu
(Xiaodi Wu)
6
Is this an actual use case that you have?
1 Like
I do not have a concrete use case at my hands, as I just tried if this wasn‘t already a feature and found out that it‘s not. I can try to look up our code base later and search for .Kind types which I probably used because the .Type namespace was taken by the language.
6 Likes
In our code base we have at least 30+ nested enum Kind types. In some cases the term is okay, but I still would probably have used Type instead.
xwu
(Xiaodi Wu)
9
Can you share some examples?
extension Firmware {
public struct Version: Hashable, Comparable {
public enum Kind: Hashable {
case release
case beta(UInt)
}
}
}
public struct Permission: Equatable {
public enum Kind {
case notSupported
case readOnly
case readWrite
}
}
extension Transition.Context {
public enum Kind {
case push
case pop
}
}
// etc.
Nothing truly groundbreaking.
Well it might be that this pitch is doomed as I kinda proposed to introduce the ability to shadow over metatype namespaces.
Counter example would be the fact that back ticks cannot overload:
enum Foo {
case a
case `a` // error - Invalid redeclaration of 'a'
}
struct `Foo` {} // error - Invalid redeclaration of 'Foo'
2 Likes
mrwerdo
(Andrew Thompson)
11
It seems what's suggested already works in Swift 5. For example, I managed to get the following to compile using Xcode 13.1:
class GameObjectNode {
enum `Type`: String, Codable {
case ship
case player
case asteroid
case spaceStation
}
class var metatype: GameObjectNode.`Type`? {
return nil
}
}
In such context you're shadowing the .Type namespace, I think this is why it works there. Try using the type from a standalone function, it will likely fail the expectation.