# Require parameter names when referencing to functions

**URL:** <https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048>\
**Category:** Pitches\
**Tags:** collection\
**Created:** [July 17, 2019, 2:35am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048 "2019-07-17T02:35:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![soroush](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soroush/32/859_2.png) [@soroush](https://forums.swift.org/u/soroush)\
**Post date:** [July 17, 2019, 2:35am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/1 "2019-07-17T02:35:40Z")

</div>

Hi everyone,

Some of you may remember [SE-0220](https://github.com/apple/swift-evolution/blob/master/proposals/0220-count-where.md), my proposal that added the `count(where:)` function to sequences. This proposal was ultimately accepted in time for Swift 5, but sadly [had to be reverted](https://github.com/apple/swift/pull/22289) because it was causing issues with the type checker.

The issue was that when you reference `count`, in an expression like `myArray.count * 5`, you could be referring to the `count` property, with type `Int`, or the `count(where:)` function, which has type `((Element) -> Bool) -> Int`, which you can refer to in shorthand as `count`. When Swift tries to resolve what version of the `*` function to use, it has to run through a lot more potential implementations, which explode combinatorially as you increase the number of operators in the expression.

I've thought about this problem for a while and chatted with a few folks about the issue, and I think the simplest path forward to solve this is to require parameter names when referencing functions.

In other words, you wouldn't be able to refer to functions with their shorthand anymore (i.e., `count`), you'd have to refer to them by their full name (i.e., `count(where:)`).

This change has the added benefit of making Swift a more precise language as well. There are currently other method resolution problems with situations like `myArray.map(Int.init)`, where the compiler has to do a lot of work to determine which implementation to use. In addition, `Int.init` isn't particularly specific, and therefore when new initializers get added, the meaning of this code can change or become ambiguous — which has actually already happened — causing an unintended source breakage. Requiring a more complete name would help in these situations as well.

If people like this solution, I'm happy to write up the proposal, and perhaps me and someone else can implement it together?

---

<div class="post-metadata">

**Author:** ![royhsu](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/royhsu/32/4589_2.png) [@royhsu](https://forums.swift.org/u/royhsu)\
**Post date:** [July 17, 2019, 2:47am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/2 "2019-07-17T02:47:44Z")

</div>

What's the impact to existing code if this requirement was added?  
The compiler pops up some warnings or errors for those functions don't use full name?

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [July 17, 2019, 2:53am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/3 "2019-07-17T02:53:42Z")

</div>

Could we revert it back once we can (theoretically) improve type-checker to the point that this doesn't pose a problem?

---

<div class="post-metadata">

**Author:** ![soroush](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soroush/32/859_2.png) [@soroush](https://forums.swift.org/u/soroush)\
**Post date:** [July 17, 2019, 2:53am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/4 "2019-07-17T02:53:58Z")

</div>

> [@Lantua](#):
>
> Could we revert it back once we can (theoretically) improve type-checker to the point that this doesn't pose a problem?

I was imagining we would deprecate "the old way" for a single Swift version (~a year) and then get rid of it, but I imagine people that are more involved and those that work at Apple have stronger feelings about that exact process.

---

<div class="post-metadata">

**Author:** ![soroush](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/soroush/32/859_2.png) [@soroush](https://forums.swift.org/u/soroush)\
**Post date:** [July 17, 2019, 3:04am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/5 "2019-07-17T03:04:18Z")

</div>

> [@Lantua](#):
>
> Could we revert it back once we can (theoretically) improve type-checker to the point that this doesn't pose a problem?

We could, and it would be easier, since it wouldn't require any deprecations. But I also think that this is a better state for Swift to be in in the long term, too, because it's more explicit.

---

<div class="post-metadata">

**Author:** ![beccadax](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/beccadax/32/34217_2.png) [@beccadax](https://forums.swift.org/u/beccadax)\
**Post date:** [July 17, 2019, 3:26am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/6 "2019-07-17T03:26:38Z")

</div>

We should make this change and we should not undo it later. This misfeature causes source compatibility breaks left and right, complicates type checking, and makes code counterproductively vague. It's a vector for users to accidentally use underscored initializers and unsafe APIs. And it runs counter to the direction of the language towards treating parameter labels as part of a function's name. Kill it with fire.

(Specifically, `name` without parentheses should only ever match _nullary_ (zero-parameter) functions/methods/initializers called `name`. If they have any parameters, you should need to specify the parameter labels.)

**Edit** : It's worth noting that we can deprecate this kind of matching in any release, but we can only make it an error in a release with a new language version. (For example, Swift 5.1 promises full source compatibility with 5.0, so in 5.1 we could have added this as a warning but not as an error.)

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [July 17, 2019, 3:33am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/7 "2019-07-17T03:33:13Z")

</div>

A fix for these kinds of problems would be great, but I don't know how possible it is due to compatibility constraints. One other idea in this general area that has been discussed in the past is to have a keypath syntax for methods, which theoretically could replace the current problematic syntax and give you a nicer source compatibility story.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [July 17, 2019, 3:52am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/8 "2019-07-17T03:52:28Z")

</div>

Yes please! Could this also fix the spurious “value used in its own initial value” errors? e.g. `let expectation = expectation(“this doesn’t compile”)`

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [July 17, 2019, 5:37am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/9 "2019-07-17T05:37:46Z")

</div>

I’m all for this, certainly for `count(where:)`, and for [all the reasons Brent mentioned](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/6).

How should it handle no-args functions? In other word, consider:

```
struct Foo {
  func noArgsFunc() { }
}
let foo = Foo()

```

…how should we get a reference to `noArgsFunc`? The obvious answer is to keep the current precedent:

```
foo.noArgsFunc

```

…but the non-uniformity is troubling:

```
foo.noArgsFunc // no parens
foo.oneArgFunc(x:) // parens
foo.unlabeledArgsFunc(_:_:_:) // parens

```

Following the pattern of other function refs, the syntax should be `foo.noArgsFunc()` … which is of course indistinguishable from a function call.

I think the approach above is probably good enough despite the inconsistency, but I thought I’d throw it out there.

**Addendum:** do the problems Brent mentions about source compatibility breaks etc. not apply to no-args / nullary funcs? If not, why not?

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [July 17, 2019, 6:25am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/10 "2019-07-17T06:25:27Z")

</div>

> [@Paul\_Cantrell](#):
>
> Following the pattern of other function refs, the syntax should be `foo.noArgsFunc()` … which is of course indistinguishable from a function call.

This is one area where a keypath syntax for methods could help out a lot.

---

<div class="post-metadata">

**Author:** ![sjavora](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sjavora/32/9323_2.png) [@sjavora](https://forums.swift.org/u/sjavora)\
**Post date:** [July 17, 2019, 6:31am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/11 "2019-07-17T06:31:51Z")

</div>

If it gets us `count(where:)`, I want it yesterday.

---

<div class="post-metadata">

**Author:** ![cukr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cukr/32/889_2.png) [@cukr](https://forums.swift.org/u/cukr)\
**Post date:** [July 17, 2019, 7:52am UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/12 "2019-07-17T07:52:33Z")

</div>

It will be very annoying to write `.init(_:)` instead of `.init`. Could we require writing the full name if there is at least one named parameter, or when the parameters aren't known from context?  
It would solve the problems with `count` and `myArray.map(Int.init) ` being ambigous, while not not forcing you to write the full name in most cases.

```swift
func foo() -> Int { return 0 }
func foo(_ a: String) -> Int { return 0 }
func foo(namedParam: String) -> Int { return 0 }
func foo(_ a: String, b: String) -> Int { return 0 }

let a = foo // error: ambiguous, can be first or second
let b: () -> Int = foo // Good, clearly it's the first one
let c: (String) -> Int = foo // Good, there are two that match the signature, but only second has no named parameters
let d: (String) -> Int = foo(namedParam:) // we have to write full name if we want to use the third function
let e: (String, String) -> Int = foo(_:b:) // we have to write full name even if only some parameters are named

```

---

<div class="post-metadata">

**Author:** ![Bryan\_Irace](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bryan_irace/32/8463_2.png) [@Bryan\_Irace](https://forums.swift.org/u/Bryan_Irace)\
**Post date:** [July 17, 2019, 2:13pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/13 "2019-07-17T14:13:19Z")

</div>

This proposal gets a +1 from me. In addition to improving typechecker performance, this change will make Swift code more explicit and legible. Thank you @soroush!

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [July 17, 2019, 3:04pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/14 "2019-07-17T15:04:49Z")

</div>

I am leery of unintended consequences from this change.

The intentions behind it are good, but so were the intentions behind [SE–111 “Remove type system significance of function argument labels”](https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md). That proposal was part of Swift 3, and the proposal text made no mention of the fact that it would outright prohibit parameters of function type from being called with argument labels.

It has been more than 3 years since that change was accepted. The problem was identified almost immediately thereafter, the core team quickly laid out [a plan for restoring the lost functionality](https://lists.swift.org/pipermail/swift-evolution-announce/2016-July/000233.html), and yet we _still_ cannot provide argument labels to parameters of function type.

I do not want to see another regression in the convenience and usability of the language.

---

<div class="post-metadata">

**Author:** ![Ponyboy47](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ponyboy47/32/2605_2.png) [@Ponyboy47](https://forums.swift.org/u/Ponyboy47)\
**Post date:** [July 17, 2019, 3:16pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/15 "2019-07-17T15:16:25Z")

</div>

You raise a valid concern, but I do think the requirement that proposals must have an implementation before being put up for review would mitigate this risk. Any issues like this _should_ discovered during the review and would _hopefully_ be required to be fixed or mitigated before full acceptance.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [July 17, 2019, 3:22pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/16 "2019-07-17T15:22:29Z")

</div>

I'm not sure it'd help in the place where it's really needed.  
`+` operators for example is leered upon with `+(_:, _:)` or `+(lhs:,rhs:)` with which this rule dosn't help.

It also hurts where there's little-to-no ambiguity like when the function name is unique.

---

<div class="post-metadata">

**Author:** ![toph42](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/toph42/32/7807_2.png) [@toph42](https://forums.swift.org/u/toph42)\
**Post date:** [July 17, 2019, 3:31pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/17 "2019-07-17T15:31:04Z")

</div>

Is there a best of both worlds situation where we can add specificity when needed for disambiguation (emit a warning when there is an ambiguity) yet allow the status quo when it is already 100% clear?

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [July 17, 2019, 4:07pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/18 "2019-07-17T16:07:30Z")

</div>

Does autocomplete favor the named version or non named?

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [July 17, 2019, 4:21pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/19 "2019-07-17T16:21:01Z")

</div>

First, those would be `+(_:_:)` or `+(lhs:rhs)`, without any comma in between. Second, just judging by the name of this thread, the first variant wouldn't apply, because that function does not have parameter names, therefore `+` should be fine. Third, I think we can keep operator functions as is, because full parameter names does not give the compiler any new information about which overload it should pick. To solve that particular area we need someone implement the parsing part to allow explicitly refer to static operator functions like `Int.+` or `String.+`.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [July 17, 2019, 4:29pm UTC](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048/20 "2019-07-17T16:29:01Z")

</div>

> [@DevAndArtist](#):
>
> First, those would be `+(_:_:)` or `+(lhs:rhs)` , without any comma in between.

Huh, It seems I used too much autocomplete 😛.

> [@DevAndArtist](#):
>
> Third, I think we can keep operator functions as is, because full parameter names does not give the compiler any new information about which overload it should pick.

That's exactly my point.

My other point still stands that it'd hurt when there's no ambiguity, esp. for those with long function names.

[Next page](https://forums.swift.org/t/require-parameter-names-when-referencing-to-functions/27048.md?page=2)
