[proposal] Allow function argument type to be omitted when passing a default value from which it can be inferred


(Thorsten Seitz) #1

I propose that function argument types could be omitted in the same way as variable and property argument types are omitted when they are set at point of definition.
[...]

We have a pretty strict rule here: types are allowed to be inferred in implementations, but not interfaces. This is important for efficient compilation, encourages people to think about their API interfaces, and somewhat reduces the damage when they don’t.

+1

-Thorsten

···

Am 11. Mai 2016 um 05:33 schrieb Chris Lattner via swift-evolution <swift-evolution@swift.org>:

On May 10, 2016, at 3:02 AM, Sam Dods via swift-evolution <swift-evolution@swift.org> wrote:


(Vladimir) #2

Inline

I propose that function argument types could be omitted in the same way
as variable and property argument types are omitted when they are set at
point of definition.
[...]

We have a pretty strict rule here: types are allowed to be inferred in
implementations, but not interfaces. This is important for efficient
compilation, encourages people to think about their API interfaces, and
somewhat reduces the damage when they don’t.

+1

Sorry, but this("We have a pretty strict rule") seems just like not true. The rule is broken as you can see (so not such a 'strict') :

public class A {
   public var a = guessWhatTypeOfThisProperty()
}
// guessWhatTypeOfThisProperty is a global function defined far-far away

So, can't see any reason why Swift should not infer type of default parameter *currently*. This will not break any 'strict' rule.

Or, what I'll probably prefer, we should *actually* disallow type inference in interface part of type *if* assigned not simple 'raw' value like Int/Double/String..

I.e.
public var a = 10 // OK, all is clear here
public var a = "sdfsdf" // OK
public var a = someFunction() // not OK - add type of `a` explicitly

And in this case, yes, there is no place for type inference for default parameters.

···

On 11.05.2016 15:09, Thorsten Seitz via swift-evolution wrote:

Am 11. Mai 2016 um 05:33 schrieb Chris Lattner via swift-evolution > <swift-evolution@swift.org>:

On May 10, 2016, at 3:02 AM, Sam Dods via swift-evolution >> <swift-evolution@swift.org> wrote:

-Thorsten

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #3

Yes, I’m aware of that, that’s why I used the waffly word “pretty” :-)

-Chris

···

On May 11, 2016, at 5:49 AM, Vladimir.S via swift-evolution <swift-evolution@swift.org> wrote:

Inline

On 11.05.2016 15:09, Thorsten Seitz via swift-evolution wrote:

Am 11. Mai 2016 um 05:33 schrieb Chris Lattner via swift-evolution >> <swift-evolution@swift.org>:

On May 10, 2016, at 3:02 AM, Sam Dods via swift-evolution >>> <swift-evolution@swift.org> wrote:

I propose that function argument types could be omitted in the same way
as variable and property argument types are omitted when they are set at
point of definition.
[...]

We have a pretty strict rule here: types are allowed to be inferred in
implementations, but not interfaces. This is important for efficient
compilation, encourages people to think about their API interfaces, and
somewhat reduces the damage when they don’t.

+1

Sorry, but this("We have a pretty strict rule") seems just like not true. The rule is broken as you can see (so not such a 'strict') :


(Haravikk) #4

I’m not clear on why you think the third one isn’t okay; Xcode can tell you what the type was inferred to be, you can check the function signature (alt - click the name) which will tell the type that it returns, as well as call up any documentation about what it does.

The only reason you would need to set a type on the property is if you know you’ll need to assign something less specific in future, e.g- a parent type in a class hierarchy.

···

On 11 May 2016, at 13:49, Vladimir.S via swift-evolution <swift-evolution@swift.org> wrote:

public var a = 10 // OK, all is clear here
public var a = "sdfsdf" // OK
public var a = someFunction() // not OK - add type of `a` explicitly


(Vladimir) #5

Inline

public var a = 10 // OK, all is clear here
public var a = "sdfsdf" // OK
public var a = someFunction() // not OK - add type of `a` explicitly

I’m not clear on why you think the third one isn’t okay; Xcode can tell you
what the type was inferred to be, you can check the function signature (alt
- click the name) which will tell the type that it returns, as well as call
up any documentation about what it does.

Well.. First of all Swift != XCode, and the OSX is not the only system where Swift is used :wink:

Yes, XCode can help a lot - should we design the language with XCode help in mind? I think we should not even think about XCode when discussing Swift features.

Second, we were discussing type inference for default parameters. I said that if we have this type inference in property - IMO there is no reason to not allow the same for default parameters. I.e. you can also use XCode to check the type of default parameter.

BUT personally I prefer to not allow type inference for properties if the assigned value is not 'simple' raw value like 10, 1.5, "sdfsdf" or probably explicit type constructor(like MyEnum.someCase; can be discussed)

The only reason you would need to set a type on the property is if you know
you’ll need to assign something less specific in future, e.g- a parent type
in a class hierarchy.

I was replying to Chris Lattner's "We have a pretty strict rule here: types are allowed to be inferred in implementations, but not interfaces"
IMO we already has type inference in interfaces, this is why IMO Swift can have type inference in default parameters.

The reason you want to have explicit type declaration - is clarity and explicitness of the code, when you understand *interface* of type just by reading it. Not always Swift code will be reviewed in XCode and you can click the function to read its result type.

···

On 11.05.2016 16:03, Haravikk wrote:

On 11 May 2016, at 13:49, Vladimir.S via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:


(Jordan Rose) #6

Without commenting on the rest of it, there’s a difference to me between something that can be inferred based on local information and something that I have to look elsewhere to figure out. In the protocol case, I’d have to notice that this method satisfies a protocol requirement and know enough about the protocol to know what the type of the parameter is. In the default argument case, I only have to know about the type of the expression, which is very often a literal. (And even when it’s not, we generally assume the return type of most functions is inferrable from the name and arguments, or we’d be requiring types for locals too.)

(By the way, that’s also the history of inference for properties and globals: we knew we wanted it for locals and implemented it, and then it was immediately a little weird to have to write types elsewhere.)

Jordan

···

On May 11, 2016, at 08:19, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

It might be different if for example we could omit type when it can inferred by other means as well, for example:

  protocol FooType {
    func someMethod(value:String) -> Void
  }

  struct Foo : FooType {
    func someMethod(value) -> Void { … } // value is a String
  }

But I’m not sure if I’d want to do that or not. Generally I like things that shorten function signatures, but on its own I’d prefer consistency over inference in this case I think.


(Haravikk) #7

I don’t disagree, but nor is Xcode unique in helping to figure out what a type is; I think it’s okay to consider that any good modern IDE should be able to tell us what a type is if the compiler can. Besides, in the example, someFunction() could be buried somewhere hard to find, sure, or it could also be declared clearly earlier in the same file, or in a commonly used file for that module, in which case it’s probably very well known. I think it’s fine to infer the type in these cases because forcing the developer to supply it may not add anything, and in cases where it does it’s easy enough to just do this yourself; even if you’re maintaining unfamiliar code, it shouldn’t take long to look up the type and add it for others if you really feel you have to, but again, any good IDE should render it a non-issue.

As to the original issue (realised I hadn’t commented on it yet), I’m undecided; I like type inference for declarations as inference is very common for these, and I myself usually only supply a type if there’s ambiguity or I want something to become optional. My main concern is that default parameter values are relatively rare (compared to those without them), so it becomes an issue of consistency for me.
It might be different if for example we could omit type when it can inferred by other means as well, for example:

  protocol FooType {
    func someMethod(value:String) -> Void
  }

  struct Foo : FooType {
    func someMethod(value) -> Void { … } // value is a String
  }

But I’m not sure if I’d want to do that or not. Generally I like things that shorten function signatures, but on its own I’d prefer consistency over inference in this case I think.

···

On 11 May 2016, at 14:59, Vladimir.S <svabox@gmail.com> wrote:

On 11.05.2016 16:03, Haravikk wrote:

On 11 May 2016, at 13:49, Vladimir.S via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

public var a = 10 // OK, all is clear here
public var a = "sdfsdf" // OK
public var a = someFunction() // not OK - add type of `a` explicitly

I’m not clear on why you think the third one isn’t okay; Xcode can tell you
what the type was inferred to be, you can check the function signature (alt
- click the name) which will tell the type that it returns, as well as call
up any documentation about what it does.

Well.. First of all Swift != XCode, and the OSX is not the only system where Swift is used :wink: