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

I'm not enamoured by the design direction but grateful that the opportunity to bikeshed callFunction was offered as that name is just aesthetically terrible. func functionCall(...) is nicer although the repetition of 'func' right after is a little awkward. func callAsFunction(...) is grammatically sound, descriptive, and looks decent.

(Minor win: there's also less chance that callAsFunction will clash with user code simply because it is longer and not a 'noun'; functionCall is perhaps in the realm of DSL territory.)

2 Likes

"func _ (arg1: Type1)" - Google Search has one hit and it is this discussion thread. So Googleability seems to be no real issue.

3 Likes

The fact that it needs quotes to be understood by Google is reason enough to not be very Googleable, IMHO

The weird about this whole thing IMO is that we're trying to name a thing and then never use said thing's name. This is why I prefer the _ since in Swift it signals the omission of a name. All other names look like somewhat poorly named functions to me and they don't make their special behaviour clear because I can still invoke them like obj.performCall() for instance. _ would not really let me do that (or should obj._() work? IDK)

3 Likes

This thread is so confusing, because there's so much to like of the many proposed names.

My favorites, at one point or another:

  • func callSelf() because that's what's happening.
  • func callAsFunction() because it's so clear, and searchable, and everything.
  • call() (treated like init()) for many obvious reasons.
5 Likes

Like many others here, I would prefer not to have a magical function name that looks just like everything else but results in special behavior. My order of preference from what has been mentioned:

  1. A new call keyword (similar to subscript or init)
  2. func _ or a completely unnamed func
  3. func callSelf

I don't like callFunction or callAsFunction since that's what happens with all functions anyways...callSelfAsFunction would be more technically correct but that is far too long for my liking.

Since I doubt 1 or 2 would be accepted by the core team I would much prefer callSelf over the alternatives suggested.

36 Likes

+1

5 Likes

This is essentially what I wanted to say as well. I've reached the limited of magical behavior in Swift: a strangely named function that enables niche functionality through nothing more than its name.

21 Likes

I've stayed out of this other than liking (which I know isn't very helpful). But this is my preferred naming of this functionality as well.

2 Likes

+1
Except that I like selfCall better than callSelf.

1 Like

Overall, the task is close to an impossible one:

We want an ordinary function name, and we want a ā€œgoodā€ one, but we want to avoid one that could conflict with existing names.

If the name didn’t need to be that of an ordinary function (i.e., if it could be a special keyword call as originally proposed, like init) then there’s no possible conflict, and the task would be straightforward.

If the name didn’t need to avoid conflicts, then we could pick func call as in the revised proposal.

The core team now wants to find a compound name. One major problem with this is: Suppose we choose the name frobnicateCall. If I type frobnicateCall, then I opt into a powerful new feature. If I type forbnicateCall, then there is nothing that can help me find the error. If there were a protocol or attribute I could opt into, then the diagnostics would tell me I’m missing a requirement. If it were a special keyword, then the parser would complain. If it were spelled call—well, how many ways can you misspell call?

All of this is to say that, if we’re going to make certain ordinary members have particular significance without protocol conformances, attributes, or keywords, then it ought to stand out in some way to avoid conflicts or unintentional use and also be difficult to misspell.

So I’ll put forward a simple suggestion: copy Python and name this __call or __call__.

13 Likes

__call or __call__ has been my preferred alternative. __ is a good candidate in my mind for, "hey this is something special, you should learn what this is." I'd probably also redesign @dynamicCallable to __dynamicCall__.

3 Likes

I think that looks incredible ugly and is actually one reason why I donā€˜t like Python...
My feelings about a single underscore are similar, and I really donā€˜t think that is a good fit either:
There are situations where we need ā€žsomething thatā€˜s nothingā€œ, but that is not the case here, as func () is not ambiguous.
After all, we don’t want to write unnamed tuples like (_: Int, _: Int), do we?

6 Likes

That's part of the reason _ is used in these type of method definitions. They aren't meant to be called or used directly, which is what static callable is all about anyway. So there's no reason for it to look read/look like a normal method, it's just a known hook into a type to expose/support some functionality. Which is something normally done via protocols. But you can dig into the background of the dynamicMemberLookup and callable proposals to see why real protocols don't work well for these kinds of features.

Yes, __call__ at least would be clearly special/magical and easy to know what it does (search it on Google and you already can find what it does on Python). Also we would create a new Swift convention: all magic names should be marked with a double underscore prefix and suffix.

1 Like

So we should have __init__ soon? Python has that, right?

6 Likes

Surrounding method names with double underscores is one of the worst conventions in Python, let's please not adopt it in Swift.

16 Likes

If the Core Team stated that the special syntax init() could not be used (as in this case) that would be a good alternative function name, I think.

2 Likes

Why?

I've always found it extremely ugly, and using it for something as common as __init__ makes me sad.

In the __call__ case, half the characters in the identifier are underscores, which is excessive IMO.