> On Jun 2, 2016, at 1:55 PM, Austin Zheng via swift-evolution 
> <swift-evolution@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.

I’m not sure.  I agree it would be bad style to use `as` here.  But I’m not 
sure if it should be banned or not.

> 
> If this proposal isn't accepted, disallow using literal values as the 
> argument to one-unlabeled-argument constructors.

I don’t know about this.  It says that if you want users to initialize your 
type with an unlabeled argument that has a type which has a corresponding 
literal you *must* conform to the corresponding literal convertible protocol.  
Do we really want to require that?  Maybe, but maybe not.  We definitely 
*should not* allow such an initializer to be written if it cannot be called 
with a literal.

For example, if I have:

`init(_ a: [String])`

users could call the initializer with an array variable but not a array 
literal.  That would be very bad IMO.  Either this initializer is banned 
altogether, or we allow it to be called with a literal. 

FWIW, there are types in the standard library with overlapping initializers in 
this new model:

public init(_ value: UInt8)
public init(integerLiteral value: UInt8)

I’m not sure whether they actually need to do different things or whether they 
are just provided so you can initialize the type with a variable and also use 
literals in a context expecting that type.

I think it’s important to understand whether overlap like this is necessary or 
not.  If behavior should always be identical I am in favor of refactoring the 
literal convertible protocols as part of this change.

> 
> 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 <austinzh...@gmail.com 
> <mailto:austinzh...@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@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 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> 
> _______________________________________________
> swift-evolution mailing list
> 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