<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Jun 3, 2016, at 12:41 PM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 3, 2016, at 1:36 PM, John McCall &lt;<a href="mailto:rjmccall@apple.com" class="">rjmccall@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 2, 2016, at 6:48 PM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:</div><div class=""><div dir="auto" class=""><div class=""><div class="">On Jun 2, 2016, at 6:51 PM, John McCall via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 2, 2016, at 4:33 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" class="">xiaodi.wu@gmail.com</a>&gt; wrote:</div><div class=""><div style="white-space:pre-wrap" class="">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.<br class=""></div></div></blockquote><div class=""><br class=""></div>I think that's a very promising way of thinking about literals. &nbsp;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. &nbsp;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.</div></div></blockquote><div class=""><br class=""></div><div class="">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? &nbsp;</div><div class=""><br class=""></div><div class="">What if we do something like this:</div><div class=""><br class=""></div><div class=""><div class=""><div class="gmail_quote"><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">init(_ value: IntegerLiteralType, literal: IntegerLiteral = #literal)</span></font></div></div></div></div><div class=""><br class=""></div><div class="">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. &nbsp;There is nothing you can do with the value at all. &nbsp;</div><div class=""><br class=""></div><div class="">The trick is that by defaulting it to #literal we are indicating the compiler synthesizes the logical value, as with #file, #line, etc. &nbsp;The compiler would refuse to synthesize this value when a literal is not used. &nbsp;This means it is never selected when the user provides a variable to a converting initializer. &nbsp;If an independent initializer accepting a value of the same type also exists that would be selected. &nbsp;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.</div><div class=""><br class=""></div><div class="">Of course no runtime value would actually exist. &nbsp;This is just a logical value marking the fact that a literal was used to call the initializer. &nbsp;</div><div class=""><br class=""></div><div class="">This approach solves the same problem while retaining semantic consistency with the language (no label elision or short circuit of overload resolution). &nbsp;The magic is arguably a lot more restrained - types for which values can only be supplied by the compiler. &nbsp;We could artificially restrict usage of these types if we wanted to, but we wouldn't have to. &nbsp;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. &nbsp;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.</div><div class=""><br class=""></div><div class="">Any thoughts on this approach?</div></div></div></div></blockquote><div class=""><br class=""></div>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. &nbsp;I just don't understand the motivation here. &nbsp;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.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I understand that this is still a special case and also that the implementation is pretty much identical. &nbsp;But I think the way it is presented to users is important.&nbsp;</div><div class=""><br class=""></div><div class="">&nbsp;The motivation is to come up with a design that lets us implement your proposal without magically eliding a parameter label. &nbsp;There is no other case in Swift where you can directly call any function (initializer or otherwise) without including labels for all parameters that have external labels.</div></div></div></div></blockquote><div><br class=""></div><div>Don't think of it as omitting a parameter label. &nbsp;Constructing a value from a literal is a complex and well-defined process that happens to end by calling an initializer with a labeled argument. &nbsp;The proposal says that we follow that entire process as normal, not just that we silently rewrite the call to add a label, which is not how it works.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""> &nbsp;Creating a special case to allow that here is inconsistent. &nbsp;Why wouldn’t look for a way to do this that treats the signature consistently with the rest of the language and is more in line with how we handle other compiler magic (i.e. #file, #line, etc)?</div></div></div></div></blockquote><div><br class=""></div>It's not more consistent with the rest of the language. &nbsp;You're talking about introducing a default argument that only defaults when the compiler recognizes a special syntactic form in the call site. &nbsp;I don't understand why inventing novel and massively invasive language mechanisms like that is somehow clearer or more consistent than explaining that a particular syntactic form is recognized as performing the well-defined literal-construction process.</div><div><br class=""></div><div>There is simply no way that this is going to feel 100% consistent with the ordinary language while still prohibiting the literal initializer from being called as an unlabelled initializer in the ordinary language, which is explicitly something we do not want to allow. &nbsp;It will be a special case. &nbsp;It will not be consistent. &nbsp;Special cases are not consistent. &nbsp;You cannot thread this needle.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">I am not the only one who feels that way. &nbsp;Quoting Brent:</div><div class=""><br class=""></div><div class="">"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&nbsp;supposed to be significant; we don't want to lose that.”</div><div class=""><br class=""></div><div class="">I agree with this. &nbsp;That is the motivation for my suggestion. &nbsp;I think it’s at least worth discussing as an alternative to magically allowing an external parameter label to be omitted. &nbsp;Brent, what do you think of my suggestion?</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Literals are always going to involve some magic behind the scenes. &nbsp;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. &nbsp;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.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Understood. &nbsp;But Swift does a good job of making the magic feel consistent with the rest of the language. &nbsp;That’s a good thing. &nbsp;Allowing omission of a parameter label is a break from that IMO.</div><div class=""><br class=""></div><div class="">I believe this is an important problem to solve but I also think we should try to find a way to solve it that doesn’t violate rules that apply everywhere else in the language (specifically regarding parameter labels).</div><div class=""><br class=""></div><div class="">-Matthew</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">John.</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div><div class="">John.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Thu, Jun 2, 2016 at 18:22 Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">&gt; 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? :)<br class="">
<br class="">
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.<br class="">
<br class="">
&gt; 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.<br class="">
<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
--<br class="">
Brent Royal-Gordon<br class="">
Architechies<br class="">
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</blockquote></div>
</div></blockquote></div><br class=""></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></body></html>