> On Jun 2, 2016, at 10:49 AM, David Sweeris <daveswee...@mac.com> wrote:
> I’m not entirely sure what an “expr-collection” is.

Collection literals, e.g. [x,y,z] and [a: x, b: y].

> Does your proposal mean that in this code:
> func foo() -> Int {...}
> var w = 0
> var x = T(foo())
> var y = T(w)
> var z = T(0)
> different initializers would be used for `x`,`y`, and `z`?

z would be initialized using the literal initializer if T conforms to that 
protocol, yes.

> If so, that seems a potential source of much subtler problems.

Note that this is only an issue for types that conform to the literal protocols.

> I don’t disagree that you’ve identified a potential source of issues, but 
> it’s conceivable that there might be circumstances where the "semantically 
> very different results” are desired. I can’t think of any off the top of my 
> head, but I’m not convinced that means they don’t exist.

I do not think that anybody writes UInt64(0) and *wants* the 0 to be built as 
an Int and then coerced to UInt64.

John.

> 
> So… I’m tentatively -1
> 
> - Dave Sweeris
> 
>> On Jun 2, 2016, at 11:08 AM, John McCall via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> The official way to build a literal of a specific type is to write the 
>> literal in an explicitly-typed context, like so:
>>     let x: UInt16 = 7
>> or
>>     let x = 7 as UInt16
>> 
>> Nonetheless, programmers often try the following:
>>     UInt16(7)
>> 
>> Unfortunately, this does not attempt to construct the value using the 
>> appropriate literal protocol; it instead performs overload resolution using 
>> the standard rules, i.e. considering only single-argument unlabelled 
>> initializers of a type which conforms to IntegerLiteralConvertible.  Often 
>> this leads to static ambiguities or, worse, causes the literal to be built 
>> using a default type (such as Int); this may have semantically very 
>> different results which are only caught at runtime.
>> 
>> In my opinion, using this initializer-call syntax to build an 
>> explicitly-typed literal is an obvious and natural choice with several 
>> advantages over the "as" syntax.  However, even if you disagree, it's clear 
>> that programmers are going to continue to independently try to use it, so 
>> it's really unfortunate for it to be subtly wrong.
>> 
>> Therefore, I propose that we adopt the following typing rule:
>> 
>>   Given a function call expression of the form A(B) (that is, an expr-call 
>> with a single, unlabelled argument) where B is an expr-literal or 
>> expr-collection, if A has type T.Type for some type T and there is a 
>> declared conformance of T to an appropriate literal protocol for B, then the 
>> expression is always resolves as a literal construction of type T (as if the 
>> expression were written "B as A") rather than as a general initializer call.
>> 
>> Formally, this would be a special form of the argument conversion 
>> constraint, since the type of the expression A may not be immediately known.
>> 
>> Note that, as specified, it is possible to suppress this typing rule by 
>> wrapping the literal in parentheses.  This might seem distasteful; it would 
>> be easy enough to allow the form of B to include extra parentheses.  It's 
>> potentially useful to have a way to suppress this rule and get a normal 
>> construction, but there are several other ways of getting that effect, such 
>> as explicitly typing the literal argument (e.g. writing "A(Int(B))").
>> 
>> A conditional conformance counts as a declared conformance even if the 
>> generic arguments are known to not satisfy the conditional conformance.  
>> This permits the applicability of the rule to be decided without having to 
>> first decide the type arguments, which greatly simplifies the type-checking 
>> problem (and may be necessary for soundness; I didn't explore this in depth, 
>> but it certainly feels like a very nasty sort of dependence).  We could 
>> potentially weaken this for cases where A is a direct type reference with 
>> bound parameters, e.g. Foo<Int>([]) or the same with a typealias, but I 
>> think there's some benefit from having a simpler specification, both for the 
>> implementation and for the explicability of the model.
>> 
>> John.
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

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

Reply via email to