I'm -1 on this idea, because I suspect it will add extra pitfalls for projects when evolving their APIs. You've called this out already in the "source breaking change" note, and I think that's reason enough to not go down this road.
One reason this can happen in real projects is as part of library API evolution. As an API grows, you will likely grow new methods that enable extra flexibility. This flexibility will manifest, at least some of the time, in being able to pass new arguments to existing functions. Right now it is always possible to avoid the ambiguity while adding Optional parameters by refusing to give them a default value. With this change, evolved parameters may never have an Optional type, even when that type is semantically meaningful, as they will encounter this ambiguity.
I'm disinclined to introduce ambiguity of this form, so I'm -1 on the proposal. If it were accepted, I'd want to argue for warning at the call site, not at the compile site, as the call site should take action to disambiguate which call they want.
My point, not clearly made, was any language where it’s not an error to omit a an optional parameter (or not initialize an optional variable) will assign it to nil (or sometimes 0, which was the poor man’s placeholder for nil not long ago) if it’s not manually given a value.
And you can, in fact, put optionals with defaults at the beginning of the properties right now. It would be processed by the compiler the same way if those optionals didn’t have explicit defaults but were instead assigned nil.
My earlier comment was from my phone earlier, so I didn't have an opportunity to test it, but it looks like the following is a completely valid Swift signature (much to my chagrin), and Xcode presents autocompletion options both with and without bar:
func myFunc(foo: Int, bar: Int = 3, baz: Int)
Since that behavior is already supported, I don't think my original point is valid.
A lot of times, it's nice for the consumer to explicitly consider whether they want to pass nil or a value. However this proposal would automatically enable a default behaviour that I won't be able to opt out of.
If you’re talking about “automatic behaviour” as in Xcode autocomplete, it’d autocomplete with all variants of a method, just as it does today when = nil is specified on an optional parameter.
I think the point @rounak is making is that if the behavior is to omit the default value and have = nil be implicit in the function signature, there would be no way for an API author to specify an Optional parameter which may not be omitted.
Yes me too, it seems like a very small win at the cost of an entirely alien concept, variables that automatically defined. Are there any other examples of that in Swift.
I guess my point is that in the vast majority of cases this is the default behavior I’d want, so I’d rather there be an annotation for the rare case that the API designer would require an optional than have all the Obj-C APIs stay ugly.
But I understand your point and that your priorities are different.
I was more commenting on the fact that your pitch as written offers no suggestion for how to recover the current behavior if an API designer wishes. The current behavior offers the ability to offer Optional parameters which may be omitted or required based on the designer's use case, but the new behavior would take away that option. What sort of syntax would you expect for a required Optional parameter?
I think the current behavior is a left over from when Implicit unwrapped optional were a different construct than regular optional. I filed this bug report: https://bugs.swift.org/browse/SR-10931
Oh interesting. Let me throw out another variation to consider: maybe only __nullable arguments in c functions should get the "default to nil" treatment in the clang importer? This has several nice features: it doesn't make keyword arguments magically vanish (because they don't exist for c functions) and the c functions are the least likely to be audited.
Disadvantage/tuning required on this: if the argument isn't the last argument, then this gets really weird. Maybe this should only apply to nullable arguments at the end of the arg list?
I don't think fixing a relatively minor issue with some apparently-neglected APIs would justify this sort of extremely broad importer change. As you said yourself, UTTypeCreatedPreferredIdentifierForTag is a bad API from a Swift perspective on more dimensions than just the final argument, and that's true of most CF-style APIs. If you want to work with a Swiftier API for this framework, you should probably write a tiny wrapper library around it.
A default-argument attribute / apinote is an interesting idea, though of course it doesn't solve your specific problem of working with other people's APIs.
I certainly don't think we want a general rule that optional arguments implicitly default to nil.
I’d love to see someone pitch and drive a proposal to remove that behavior, by the way. Optionals are the only type in Swift that can be default initialized in this manner, and it feels like an unnecessary bit of magic to me.
Well, it seems like most people on here don’t like the idea of optionals defaulting to nil in general, which I disagree with but also I’m not willing to die on that hill. (For the record I think it’s not ‘magic’ because for an optional there really is one default value that completely makes sense, always.)
So I'll reverse course and support adding some kind of attribute to clang (let’s call it __null_by_nature for argument’s sake) that could be put in C and Obj-C APIs, in the same form as the nullable properties (eg, one could turn it on for an entire file but call out exceptions, but the default would be to have it off and add __null_by_nature per-method / function).
Thanks for your feedback on this issue! Hopefully my next pitch will do better.
Giving a default value auto-magically is so not swift-y. It's ambiguous and could lead onto hard to find bugs. It should be the function author's responsibility whether to give it a nil default value or not.