> On Jun 2, 2016, at 6:48 PM, Matthew Johnson <matt...@anandabits.com> wrote: > On Jun 2, 2016, at 6:51 PM, John McCall via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: > >>> On Jun 2, 2016, at 4:33 PM, Xiaodi Wu <xiaodi...@gmail.com >>> <mailto:xiaodi...@gmail.com>> wrote: >>> The IntegerLiteral type idea might be worth exploring. It does seem to >>> provide some additional consistency. For example, wasn't it clarified on >>> this list just recently that literals don't have a type and adopt one based >>> on context? It'd be nice to point out that 42 is an IntegerLiteral when >>> explaining that it's not an Int. >> >> I think that's a very promising way of thinking about literals. Writing a >> literal creates a notional value whose type is the informal, >> infinite-precise type of all integer/FP/collection/etc. literals, which (1) >> can be implicitly converted to any type that implements the appropriate >> protocol and (2) in fact *must* be converted to some such type (possibly the >> default type for that literal) in order for the code to be executable. You >> can then think about this proposal as saying that an explicit conversion >> from that informal type to a literal-convertible type follows the same path >> as an implicit conversion would have. > > It sounds like the reason you don't want to remove the label is because it > distinguishes the literal initializer and you don't want it called with a > variable accidentally right? > > What if we do something like this: > > init(_ value: IntegerLiteralType, literal: IntegerLiteral = #literal) > > The idea here is that the IntegerLiteral type and friends are special types > that have no members and cannot be used except by the literal convertible > protocols and their conformances. There is nothing you can do with the value > at all. > > The trick is that by defaulting it to #literal we are indicating the compiler > synthesizes the logical value, as with #file, #line, etc. The compiler would > refuse to synthesize this value when a literal is not used. This means it is > never selected when the user provides a variable to a converting initializer. > If an independent initializer accepting a value of the same type also exists > that would be selected. However, when a literal *is* used and the type > conforms to the relevant literal convertible protocol the compiler always > synthesized the value making it always the most specific overload. > > Of course no runtime value would actually exist. This is just a logical > value marking the fact that a literal was used to call the initializer. > > This approach solves the same problem while retaining semantic consistency > with the language (no label elision or short circuit of overload resolution). > The magic is arguably a lot more restrained - types for which values can > only be supplied by the compiler. We could artificially restrict usage of > these types if we wanted to, but we wouldn't have to. Nothing could be > accomplished by using the types anywhere else so nobody do so and it wouldn't > be actively harmful to allow them to be used anywhere other types can be > used. Only the ability to create values of the type needs to be restricted > and we can already write types like that by marking the initializers private. > > Any thoughts on this approach?
This is still a special-case type-checking rule, which means that it's still basically my proposal except, instead of just rewriting the call to use a labeled literal initializer, it rewrites the call to use a magic initializer which cannot be used by users because it requires arguments that users cannot create. I just don't understand the motivation here. It's not a simpler language model to use, explain, or implement; it purports to be conceptually simpler and less magical while actually inventing two magic new language concepts (IntegerLiteral and #literal) on top of the same special cases. Literals are always going to involve some magic behind the scenes. The non-trivial literals, for example, all actually traffic through some sort of builtin protocol (e.g. BuiltinIntegerLiteralConvertible) which cannot be implemented by users and whose construction necessarily involves a private API contract between the standard library and compiler that we reserve the right to change at will without bringing in swift-evolution. All of the supposedly simple explanations eventually reach, "okay, but if Int isn't a special type, how does the literal turn into an Int in the first place", and that is just unanswerable, because it turns out that standard library types *are* actually special in the sense that they get to conform to BuiltinIntegerLiteralConvertible and nobody else does. John. > >> >> John. >> >>> >>> On Thu, Jun 2, 2016 at 18:22 Brent Royal-Gordon via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>> > So, you think that this syntax is enticing to new developers who >>> > naturally think that the feature works the way that I'm proposing it >>> > should work, and you think that the right solution is to make the syntax >>> > illegal so that you can more conveniently tell them it doesn't work that >>> > way? :) >>> >>> I think the difference between a cast (which merely reinterprets a value as >>> a compatible type) and a fullwidth conversion (which creates a similar >>> instance of an incompatible type) is very important to understanding how to >>> write Swift, and we shouldn't muddy the waters by creating a magic syntax. >>> >>> > You can still tell them that it's a struct and you're calling an >>> > initializer on it; it's just that the initializer chosen is the special >>> > literal initializer because the argument is a literal. >>> >>> If you're planning to change `IntegerLiteralConvertible` and friends to >>> require a fullwidth conversion initializer like `init(_ value: >>> IntegerLiteralType)`, then this is simply an overload resolution rule. In >>> that case, I think your proposal is fine. >>> >>> But if you're going to call `init(integerLiteral:)` like it's `init(_:)`, I >>> don't think that's a good idea. Parameter labels are supposed to be >>> significant; we don't want to lose that. >>> >>> -- >>> Brent Royal-Gordon >>> Architechies >>> >>> _______________________________________________ >>> 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 <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