> On Jun 2, 2016, at 6:08 PM, John McCall via swift-evolution
> <[email protected]> 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, ...
>
> 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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution