[Accepted with Modification] SE-0253 - Callable values of user-defined nominal types

Actually, perhaps the least surprising option would be

func _(someArg: Int) -> Int

It parallels other use of _, it is googleable and the behaviour is not at all unexpected.

5 Likes

"_" is the first thing that came to my mind as well, but i wonder if using it isn't going to come back to bite us in the future.

PS : for what it's worth, i also don't like the idea of giving exceptional meaning for special user-defined values. I couldn't think of anything more confusing. At least "_" makes it look that something you would expect the language to give some kind of special meaning.

1 Like

The Core Team discussed this and has decided to further revise the proposal to name the operator function func callAsFunction(). We are comfortable with enabling this functionality purely based on nothing more than the name of a function, and we are not persuaded that init and subscript (which both have substantially different semantic and syntactic rules and are not simply functions) provide important precedents here requiring a new declaration introducer.

Thank you all for the discussion.

John McCall
Bikeshed Manager

39 Likes

heh, but at least we now have a verdict, thank you. :slight_smile:

8 Likes

Thank you all! Proposal updated: Final revision of SE-0253 callable. by rxwei ยท Pull Request #1043 ยท apple/swift-evolution ยท GitHub.

3 Likes

Thank you for wrapping this up for me John, I applaud your efforts as bikeshed manager!!

-Chris

14 Likes

A majority of the original feedback was against magic handling of methods spelled a particular way

This seems like a huge failure in the Swift evolution process. What is the purpose of the community's participation if the core committee is going to disregard it (and choose a really suboptimal solution nonetheless, spelling-based behavior, inconsistency across dynamic and static).

3 Likes

What is the purpose of the community's participation

Pitch a non-existent language feature, publicly present it, debate it, create an entire proposal, publicly present it, debate it, incorporate the feedback and implement the entire feature, break Swift, fix it, break it again, fix it, then witness Swift being shipped with your ideas and your code inside of it.

The great philosopher Sir Michael Jagger once said "You can't always get what you wa-a-nt; but if you try sometime, you'll find, you get what you need."

10 Likes

I think call made the most sense given the existence of init and subscript, these things as keywords are so aesthetic.

3 Likes

I was really looking forward to this feature, @dan-zheng can you give us an update on the issue(s) of implementation?

Is there is any chance we can see this feature in a release post swift 5.1?

Thanks for the ping! I'm sorry about the long wait for this feature.

The current status is (implementation PR):

  • func callAsFunction is implemented and fairly well-tested.
  • @xedin requested some implementation detail changes (regarding the constraint system) which I haven't investigated yet: this is the main reason why the PR hasn't landed.
  • Diagnostics regarding sugared func callAsFunction applications are not ideal, but can be improved as a follow-up to the initial feature.
  • There's at least one known type-checking issue regarding sugared func callAsFunction applications (TF-516). Perhaps this will be fixed after I address @xedin's comments.

I'll try to investigate @xedin's comments this weekend - thanks for your patience :slightly_smiling_face:

6 Likes

func callAsFunction has been merged and is available in latest development snapsnots from Swift.org - Download Swift.

I just tested swift-DEVELOPMENT-SNAPSHOT-2019-08-27-a:

struct Adder {
  var base: Int
  func callAsFunction(_ x: Int) -> Int {
    return x + base
  }
}
var adder = Adder(base: 3)
print(adder(10)) // 13

Thanks for your patience!

14 Likes

I assume it won't be cherry picked into 5.1?

Also, does it support throwing implementations? The discussed feature doesn't, just wondered if it was implemented along the way.

I'm not sure who can make that decision, sorry.

Yes, it does. Here's a changelog PR with a short callAsFunction feature list:

  • func callAsFunction argument labels are required at call sites.
  • Multiple func callAsFunction methods on a single type are supported.
  • mutating func callAsFunction is supported.
  • func callAsFunction works with throws and rethrows.
  • func callAsFunction works with trailing closures.

Check out this test file for general func callAsFunction functionality tests. There are also other tests for generics, protocols, cross-module support, and edge cases.

If you find bugs or unsupported behavior, please file a bug. Here are currently known issues:

  • SR-11378: improve callAsFunction diagnostics. Ideally, diagnostics should match those from direct callAsFunction calls.
  • SR-11386: crasher regarding conditionally available callAsFunction methods.
3 Likes

Correct.

But since this is solely a compiler feature/syntax sugar (i.e not requiring runtime changes), am I correct in thinking that once the next version of the compiler is released, we will be able to use this feature without backwards deployment concerns?

2 Likes

Correct as well.

11 Likes