medismailben
(Mohamed Ismail Bennani)
1
Hi,
I'm working on a project where I'd like use the parentheses as method identifier.
C++ equivalent: void operator()()
I've tried overloading it but it looks like the compiler doesn't allow it.
Am I doing it wrong or is this feature not implemented yet ?
Thanks,
Ismail
Can you elaborate a little bit more on what Swift code you wish to be able to write? () is not an operator in swift but an empty tuple aka typealias Void = ()
medismailben
(Mohamed Ismail Bennani)
3
Basically, I'd like to have a method in my class that use () as an identifier.
I'd like to be able to call my instantiated object this way:
let obj : Object()
let s = obj("test")
Would a subscript serve your needs here?
class MyObject {
subscript (_ value: String) -> SomeType { ... }
}
let object = MyObject()
let s = object["test"]
I don't think Swift will ever support parentheses in that way. It's kind of strange and it reads ambiguous.
medismailben
(Mohamed Ismail Bennani)
5
Yeah in my case I'd do the job perfectly, but what if my class is also a Collection.
It would be great to have the () option.
Your type can have as much subscripts as you'd like, the only limitation that you can reach is that some subscripts can become ambiguous at call-site but you can explicitly tell the compiler the types to resolve such collisions. In other situation you can add a view type to your class that will provide the functionality you need.
class MyObject {
struct DataView {
let object: MyObject
subscript (_ value: String) -> Data { ... }
}
var data: DataView { return DataView(object: self) }
}
let object = MyObject()
let s = object.data["test"]
2 Likes
Nevin
7
We literally just accepted SEā0216 āIntroduce user-defined dynamically "callable" typesā two days ago. It would be wildly incongruous to let people define wholly dynamic ācallableā behavior, but to somehow decide that *statically* callable types would not fit in the language.
Of course statically-callable types make sense, of course they fit in the language, and of course square-brackets are a poor substitute for round ones in this scenario. After all, if square brackets were good enough for ācallableā types, then we wouldāve demanded that SEā0216 use square brackets.
But we didnāt.
Because square brackets are the wrong symbol for ācallableā types.
The right symbol is a pair of parentheses, just like we use when calling any other function or method. When a user-defined type represents a function, it deserves and ought to be able to use parentheses when it is ācalledā.
For example:
class DifferentiableFunction<T: FloatingPoint> {
var f: (T) -> T
var df: DifferentiableFunction?
init(f: @escaping (T) -> T) { self.f = f }
// This should be ācallableā with parentheses not square brackets:
subscript(x: T) -> T { return f(x) }
}
5 Likes
Thx for mentioning it Nevin, when I replied I only had the dynamic lookup attribute in mind and to be honest I never looked that closely into that last proposal.
Btw. did you forget the attributes on your example type?
CTMacUser
(Daryle Walker)
9
That is the "functor", or function object, concept in C++. We haven't had that concept in Swift. The subscript suggestion from @DevAndArtist doesn't really match because a subscript access implies more of a sub-object, while a functor is more of a mapping (like conventional functions and closures).
But, as @Nevin said, we have taken steps that may lead to a Swift functor concept someday.
2 Likes
ibex10
11
This terser, anonymous function syntax, proposed by @davdroman
struct Foo () {
func (...)
}
feels much better than these verbose, supported alternatives:
struct Foo () {
func callAsFunction (...)
}
// Or
@dynamicCallable
struct Foo () {
func dynamicallyCall (withArguments: ...)
}
jrose
(Jordan Rose)
12
This was all discussed in the proposals for these features. That doesnāt mean itāll never change, but a four-year-old āUsing Swiftā thread isnāt the place to relitigate it.
3 Likes