SE-0253: Callable values of user-defined nominal types

Does that even matter, though? They can continue to use call(...) as a normal method if they wish, just like you can refer to .init(...) explicitly.

I'm a little surprised about the criticism here. This is how operators work in Swift - they are basically functions with magic names which require different syntax. For example:

struct A {
  let val: Int
  static func + (lhs: A, rhs: Int) -> A { return A(val: lhs.val + rhs) }
}

func a(inst: A) {
  // if "+" was a normal method, you would expect to call it like this:
  let n = A.+(lhs: inst, rhs: 42)
  // but that doesn't actually typecheck (on my machine, at least).
  // But both of these incantations work:
  let n2 = inst + 42
  let n3 = [1, 2].reduce(inst, +)
}

The magic name "+" is defined in the standard library as an operator, but it's not discoverable at all. You basically have to know that it already has this funky behaviour. I didn't opt-in to this weird syntax with an attribute or protocol conformance - all I did was add a method! What if I really wanted to write A.+(...) and not use the infix operator syntax? Tough luck! Swift has reserved that name.

I don't see much difference with the magic name call(...). True, it's a little bit further removed from the function-call operator (), but the intended behaviour is just as obvious as + IMO.

Alternatively, we could make it more directly mirror the function-call syntax and expand what we consider an "operator" to be. That was basically my feedback during the last round of review. Perhaps I didn't express it very clearly.

EDIT: wrong link. There were a couple of posts on the topic.

3 Likes