[swift-evolution] Default Generic Arguments

Xiaodi Wu xiaodi.wu at gmail.com
Tue Jan 31 17:05:15 CST 2017

I have concerns about these revisions. It seems you've entirely rejected
all the options that Alexis has laid out very clearly, and instead you've
come up with your own rules which are backwards-incompatible with Swift 3.

For instance, the rule "No type inference will happen in type declarations"
is source-breaking, because type inference currently happens in type
declarations. You would break every instance of `let foo: Optional = 42`.

I would urge you to incorporate Alexis's very clear analysis and then adopt
one of the options he laid out, i.e., either "prefer user" or "do what I
mean." Alternatively, if you like none of his options, I believe that
requiring `<>` to be appended for entirely default arguments would avoid
the issue altogether. Or, if you don't even want to require that, you can
push the whole problem down the road by specifying that, for now, the first
generic type cannot have a default. We can then relax the rules later.

On Tue, Jan 31, 2017 at 3:15 PM, Srđan Rašić <srdan.rasic at gmail.com> wrote:

> I updated the proposal with the things we discussed so far. Have to do
> some more polishing, but feel free to throw your critique of what I have so
> far.
> On Sat, Jan 28, 2017 at 1:32 AM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>> Oh, it's precisely my confidence that a good error message can be devised
>> which makes me ponder whether "prefer user" is the ideal rule. Having a
>> stricter rule isn't necessarily bad if the error message makes it easy to
>> remedy.
>> In your example, "prefer user" would object at the line where you make
>> your Something. I think that makes for a much cleaner error. By contrast,
>> DWIM necessitates the acrobatics you show above, where the compiler will
>> have to keep track of a defaulted type for each variable as long as it's in
>> scope and propose remote fix-its at the declaration site based on how it's
>> later used. Now what happens if there's an action() that takes only
>> Something<Int> arguments and an action2() that takes only Something<Int64>
>> arguments? Will you have an alternating cycle of fix-its that don't fix the
>> problem?
>> On Fri, Jan 27, 2017 at 18:07 Karl Wagner <razielim at gmail.com> wrote:
>>> On 27 Jan 2017, at 01:30, Xiaodi Wu via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>> Cool, thanks--that makes sense.
>>> Personally, although DWIM is appealing, I think if we are to go all-out
>>> on your stance that "adding a default to an existing type parameter should
>>> be a strict source-breaking change," then "prefer user" is the one rule
>>> that maximally clarifies the scenario. With that rule, in the evolution
>>> scenarios that I brought up, either the user-specified default and the
>>> inferred literal type line up perfectly or it is guaranteed to be
>>> source-breaking. IMO, that consistency would bring more clarity than DWIM,
>>> which might prompt a user to be confused why sometimes the compiler "gets
>>> it" and other times it doesn’t.
>>> I’m not sure, I think it will be easy enough for users to figure out
>>> where the problem is because it will create a type-mismatch.
>>> When type mismatches occur, the only place to look is the variable
>>> definition, because that is where the type is defined.
>>> This is such a narrow case that I’m sure we can provide good diagnostics
>>> for it. The pattern could be:
>>> - A generic parameter mismatch (i.e. trying to use a value of type
>>> MyType<X> where type MyType<Y> is expected), and
>>> - X and Y are both {Whatever}LiteralConvertible, and
>>> - X is the default type bound to that parameter, and
>>> - the value was initialised using a {Whatever} literal, where an
>>> instance of the parameter was expected
>>> In that case, we could introduce a simple fix-it: replacing one of the
>>> literal values with "(literal as Y)”
>>> for example:
>>> struct Something<T=Int64> { let value: T }
>>> func action(_: Something<Int>) { … } // Expects a specific kind of
>>> Something<T>
>>> let myThing = Something(value: 42) // Fix-it: Did you
>>> mean ‘Something(value: 42 as Int)’?
>>> action(myThing)                    // Error: No overload for ‘action’
>>> which takes a Something<Int64>.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170131/bb3e6f89/attachment.html>

More information about the swift-evolution mailing list