<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 22, 2017, at 2:01 AM, David Hart via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class="Apple-interchange-newline"><br class=""><blockquote type="cite" class=""><div class="">On 22 Nov 2017, at 07:48, David Hart via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="auto" class=""><br class=""><div class=""><br class="">On 22 Nov 2017, at 07:41, Douglas Gregor via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Nov 21, 2017, at 10:37 PM, Chris Lattner <<a href="mailto:clattner@nondot.org" class="">clattner@nondot.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;">On Nov 21, 2017, at 9:25 PM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> wrote:<br class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Or alternatively, one could decide to make the generics system *only and forever* work on nominal types, and make the syntactic sugar just be sugar for named types like Swift.Tuple, Function, and Optional. Either design could work.</div></div></blockquote><br class=""></div><div class="">We don’t have a way to make it work for function types, though, because of parameter-passing conventions. Well, assuming we don’t invent something that allows:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>Function<Double, inout String></div><div class=""><br class=""></div><div class="">to exist in the type system. Tuple labels have a similar problem.</div></div></div></blockquote><br class=""></div><div class="">I’m totally aware of that and mentioned it upthread.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Eh, sorry I missed it.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""> There are various encoding tricks that could make this work depending on how you want to stretch the current generics system…</div></div></div></blockquote><br class=""></div><div class="">I think it’s straightforward and less ugly to make structural types allow extensions and protocol conformances.</div></div></blockquote><div class=""><br class=""></div><div class="">Can somebody explain to me what is less ugly about that? I would have naturally thought that the language would be simpler as a whole if there only existed nominal types and all structural types were just sugar over them.</div></div></div></blockquote><div class=""><br class=""></div><div class="">What confuses me is that I always thought that T? was sugar for Optional<T> by design, and found that to be quite elegant. But now you’re telling me that its just a hack to allow conformance on Optionals until it can be made structural. I would have thought that it would be cleaner to have specific concepts (optionals, tuples, etc…) represented in terms of more general concepts (enum, struct) so that the compiler had less to reason about. I’m just trying to understand :-)</div></div></div></blockquote><br class=""></div><div>Don't worry too much about it. The people in this thread are conflating a lot of different things, including some people who ought to know better. Your way of looking at it is perfectly accurate.</div><div><br class=""></div><div>A fairly standard formalization of types is that you have these <i class="">type expressions</i>, which, in a simple system, are either <i class="">type constants</i> or <i class="">type applications</i>.</div><div><br class=""></div><div>A type constant is something like <b class="">Int</b>, <b class="">Float</b>, or <b class="">Array</b>. struct/enum/class declarations in Swift all introduce new type constants, where each declaration has its own identity as a type. Since we don't allow type names to be redeclared in a scope, the identity of such declared types can be uniquely determined by (1) the type's name in its scope and (2) the path to that scope. Hence the identity is "by name", or "nominal".</div><div><br class=""></div><div>A type application takes a generic type and applies it at some number of arguments. The general syntax for this in Swift is <b class=""><></b>. For example, <b class="">Array</b> is a generic type, and <b class="">Array<Int></b> is a type application of the generic type <b class="">Array</b> with the argument <b class="">Int</b>. The arguments can be arbitrary type expressions, e.g. <b class="">Dictionary<String, Array<Float>></b>. The identity of a type application is determined purely by its applicative structure: first, the identity of the generic type being applied, and second, the identity of the type arguments it is being applied to. That is, <b class="">A<B></b> is the same type as <b class="">C<D></b> as long as the type-expression <b class="">A</b> is the same generic type as <b class="">C</b> and <b class="">B</b> is the same type as <b class="">D</b>. Hence the identity is "structural".</div><div><br class=""></div><div>(Formal nitpick: we're making some assumptions about the nature of type expressions that generally work out until you get into really advanced type systems.)</div><div><br class=""></div><div>What is a tuple type in this formalization? Well, the rule we want is that <b class="">(A, B)</b> is the same type as <b class="">(C, D)</b> if <b class="">A</b> is identical to <b class="">C</b> and <b class="">B</b> is identical to <b class="">D</b>. We could add this as a special new rule to our definition of type expressions above, but we don't really need to, because it turns out that it's exactly the same as if we had some sort of tuple type constant — for sake of argument, let's call it <b class="">(...)</b> <span style="font-size: 11px;" class="">— <span style="font-size: 12px;" class="">and allowed </span><span style="font-size: 12px;" class="">it to be applied to an arbitrary number of types. Swift does not actually allow you to name this as an unapplied generic type — you cannot write <b class="">(...)<Int, Float></b> instead of <b class="">(Int, Float)</b> — but that's just a matter of syntax. The fact that <b class="">(...)</b> is built into the language rather than being declared in the standard library as <b class="">Tuple</b> is not fundamentally significant. Nor is it fundamentally significant for <b class="">Optional</b>, which <i class="">is</i> currently declared in the standard library instead of being built-in.</span></span></div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class=""><br class=""></span></span></div><div>(Function types in Swift are weird because, as covered previously in this thread, there's more to their structure than just component type identity. You could still stretch the formalization to make this work, but, well, they'd still be weird.)</div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class=""><br class=""></span></span></div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class="">Now, function, tuple, and optional types are special in the language in several ways: there are primitive declarations and expressions that introduce or manipulate these types, and there are special rules in the type system for them. (For example, optionals and tuples obey covariant subtyping.) But we could technically do the same for any type if we wanted to. We could even do it to arbitrary third-party types as long as we handled the possibility that they weren't imported into the current program.</span></span></div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class=""><br class=""></span></span></div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class="">We could absolutely allow tuples to conform to protocols without first introducing variadic generics. We'd have to solve some straightforward internal representation problems, and then we'd just need some way of spelling them (if we didn't just hard-code a few conformances as special).</span></span></div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class=""><br class=""></span></span></div><div><span style="font-size: 11px;" class=""><span style="font-size: 12px;" class="">John.</span></span></div></body></html>