> 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