[swift-evolution] Proposal: 'T(literal)' should construct T using the appropriate literal protocol if possible

John McCall rjmccall at apple.com
Fri Jun 3 13:51:51 CDT 2016

> On Jun 2, 2016, at 10:31 PM, L. Mihalkovic <laurent.mihalkovic at gmail.com> wrote:
> On Jun 2, 2016, at 6:08 PM, John McCall via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at 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.
> Looking transversally at all literal protocols as this proposes to operates reminds me that the knowledge that a protocol has the right semantic is based on a convention, rather than on conformance. Would it be conceibable to look into something like the following, that all others would specialize.
> protocol LiteralConvertible {}
> This might offer a stronger identification than the name. It might also be interesting to define an associated type, but that would exclude NilLiteralConvertible.
> Note: as compiler expert, I would appreciate your thinking on the notion of formally expressing what might otherwise be a known strong semantic relationship. Is there any incentive to pursue, known disavantages, ...

I don't know what you're saying here.  Literal types already do explicitly conform to a protocol that's specific to the literal; it's not just convention.  There's nothing linking those protocols because there's no useful operation in common: there is no useful generic code that you can write that works for an arbitrary type that allows some unknown kind of literal.  We intentionally do not add protocols that do not serve some useful purpose in generic programming.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160603/b9ad8386/attachment.html>

More information about the swift-evolution mailing list