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

Austin Zheng austinzheng at gmail.com
Thu Jun 2 14:14:33 CDT 2016

On Thu, Jun 2, 2016 at 12:11 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

> +1 to the proposal. I can also see the argument for disallowing multiple
> ways of doing the same thing, though disallowing the use of `as` in this
> way might be introducing another special case.
The "as", "as?" and "as!" operators in Swift are already surprisingly
overloaded.  Joe Groff's proposal lists 9 (!!!) different things "as?" does

"as" is also overloaded in this sense. It performs bridging casts (soon to
go away?), upcasts that can never fail (e.g. subclass to superclass), and
defining the concrete type of a literal expression. It wouldn't be a big
loss for "as" to lose the last meaning.

> If the proposal is accepted, I'd also advocate for the suggestion in the
> initial proposal to apply the rule regardless of the number of parentheses,
> so that `A((B))` behaves the same way as `A(B)`.

+1. Yes please.

> On Thu, Jun 2, 2016 at 1:55 PM, Austin Zheng via swift-evolution <
> swift-evolution at swift.org> wrote:
>> I think we should actually go further.
>> If this proposal is accepted, disallow "as" as a way of specifying the
>> type to construct from a literal.
>> If this proposal isn't accepted, disallow using literal values as the
>> argument to one-unlabeled-argument constructors.
>> In either case we should disabuse users of the notion that A(literal) is
>> an initializer that behaves exactly the same as other initializers.
>> Austin
>> On Thu, Jun 2, 2016 at 11:46 AM, Austin Zheng <austinzheng at gmail.com>
>> wrote:
>>> +1.
>>> The primary advantage is that it aligns the language semantics with how
>>> most programmers expect this common C-language-family idiom to behave and
>>> removes a potential source of silently wrong code.
>>> The primary disadvantage is that it introduces special-case behavior to
>>> certain types of initializers (although, to be fair, this special-case
>>> behavior is easily recognizable: unlabeled one-argument initializer with a
>>> literal as the argument).
>>> I think the advantage outweighs the disadvantage.
>>> This problem should be addressed one way or another. I prefer this
>>> solution, but if it is rejected for whatever reason we should at least
>>> explicitly outlaw A(literal) syntax in favor of "literal as A".
>>> Austin
>>> On Thu, Jun 2, 2016 at 9:08 AM, John McCall via swift-evolution <
>>> 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.
>>>> 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 at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160602/80d3bd1a/attachment.html>

More information about the swift-evolution mailing list