Hello, new to the Swift community here and coming from Julia language background. On my little adventure with the Swift Programming Language official book I have been going through Protocols, Generics, Extensions, and finally Opaque Types. I stumbled upon the interesting example from the book where it defines a brand new protocol (if I understand correctly) called Container and then it extends the known Array type to conform to that protocol.
protocol Container {
associatedtype Item
var count: Int { get }
subscript(i: Int) -> Item { get }
}
extension Array: Container { }
The example then proceeds to demonstrate some interesting aspects of opaque types. Something like (after some edits by me)
extension Container {
var isContainer: Bool { true }
}
func makeOpaqueContainer<T>(item: T) -> some Container {
return [item]
}
let opaqueContainer = makeOpaqueContainer(item: 12)
print(type(of: opaqueContainer)) // Array<Int>
let twelve = opaqueContainer[0]
print(opaqueContainer.isContainer) // true
print(type(of: twelve)) // Int
At this point, again coming from Julia language background, a question came to mind: how can we tell at run-time which function exactly is being called. In Julia there exists a popular macro @which that can be placed on the same line with a function call to print out which method is being dispatched, and that can greatly help with debugging and with understanding how the compiler is reasoning about the code. Is there a Swift equivalent of such @which functionality? My quick search led me to this thread which is discussing some topics way over my head for a beginner, yet this particular comment helped me explore more:
extension Container {
func whatAmI() { print("Container") }
}
extension Array {
func whatAmI() { print("Array") }
}
func whatIsIt<C: Container>(_ value: C) {
value.whatAmI()
}
let x = [1, 2, 3]
x.whatAmI() // Array
whatIsIt(x) // Container
let y: some Container = [1, 2, 3]
y.whatAmI() // Container
print(type(of: y)) // Array<Int>
print(y[1]) // 2
I'm particularly curious about the very last line. Is there a way to annotate that line with @which-similar construct to let us know what subscript function exactly is being called for that some Container, together with the exact concrete type that is being resolved by the compiler? For example
print(@which y[1]) // Array<Int>.subscript
Having such feature in the Julia language was really helpful and I'd very much like to have a similar feature to help me validate my reasoning about Swift code! Thanks in advance!