I agree Brent's proposal is workable in Ruby. Moving the type signature out of the compiler and decoupling it from the labels is interesting because it gets very close to transparently permitting the "and also pass a trailing closure [ruby block]" syntax I wrote about during the pitch thread.
So this compiles OK:
struct S {
subscript(dynamicMember name: String, argumentLabels labels: String...) -> (Int..., (Int) -> String) -> String {
get {
return { (args: Int..., clo: (Int) -> String) in
"a"
}
}
}
}
let s = S()
s[dynamicMember: "m", argumentLabels: "O", "T"](1, 2) { anInt in
"b"
}
// ruby: s.m(1, 2) { 'b' }
But providing a further overload to take just the closure [pleasantly surprised this worked at all]:
extension S {
subscript(dynamicMember name: String, argumentLabels labels: String...) -> ((Int) -> String) -> String {
get {
return { (clo: (Int) -> String) in
"c"
}
}
}
}
...requires parens at the point of use to avoid treating the closure as a subscript arg:
s[dynamicMember: "m2"] ({ anInt in
"d"
})
// ruby: s.m2 { 'd' }
A potential evolution of @dynamicMemberCallable wouldn't have this tiny problem but would need a chunk of proposal and compiler work.
(fwiw I have a Ruby client)