Method and variable with the same base name

I can't have a variable and a method with the same base name. Look at the example below, I can have "foo" but not "bar", yet at the call site both would be looking the same. Is this by design, or a bug worth looking at?

Note that error says about redeclaration of bar() as if compiler made a function called bar, but that's not the case as i can't call bar(), so the error message looks somewhat strange.

struct S {
    var foo: Int = 0
    func foo(_ x: Int = 0) {} // ok
    var bar: Int = 0
    func bar() {} // Invalid redeclaration of 'bar()'

func test() {
    var s = S() = 1 = 0
1 Like

I presume that this is because you can use the compound name to refer to a function without calling itβ€”e.g., var f = foo(_:). For a function that takes no arguments, however, there is no such compound name; that is, the function bar cannot be referred to in any other way than bar without invoking the function. The lack of such a spelling is tracked in SR-3550.


Presumably you could do bar as () -> () if this sort of overloading were allowed.

1 Like

We could, by the same token, allow var foo: Int to be followed by var foo: String, then have the user disambiguate with foo as Int and foo as String. We choose not to allow such overloading. My point is that (at least as far as the user-facing language is concerned), foo is not a redeclaration of foo(_:), but bar is a redeclaration of bar.


Just adding a point to the benefit of allowing overloading variable bar and function bar():

Since we now allow effectful read-only properties, some users might want to change

func bar() throws -> Foo


var bar: Foo {
    get throws { ... }

Allowing the overload allows users to deprecate the bar function for the bar variable without having to immediately remove the function.


Adding my upvote here, I also find myself regularly frustrated by this. I usually end up having to prefix properties with an underscore which doesn't really feel at home in Swift.