<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 class="">In one of my earlier fixed-size array proposals, I had two kinds of array types: a compound type and a nominal type. I dropped the latter because there wasn’t too much of a value-add, especially once I copied its unique features to the compound type. It would be like a compound array property wrapped by a struct, except that member wouldn’t have a proper name so you would have to use “super” to refer to the inner object.</div><div class=""><br class=""></div><div class="">I have been looking up on how Rust handles its array/vector types, and I saw an issue on adding complex numbers. I then recalled that “long” ago I read up on C++’s complex numbers and how that class isn’t supposed to have any padding so you can alias a large array of double into a large-ish array of complex. That could have been resolved another way if we had a strong “typedef” so a new type would have the EXACT layout as another type without wrapping it in a struct and risking padding.</div><div class=""><br class=""></div><div class="">Over the past few weeks, I seen requests here for a strong type-alias. And requests for “I know that tuples are supposed to be protocol-less, but I want to (automatically) slap SuperReallyPeachyKeenProtocol on them anyway”. Now I think I can put all of these together.</div><div class=""><br class=""></div><div style="font-size: 13px;" class=""><b class="">Name a New Type Based on an Existing One:</b></div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">“retype” IDENTIFIER “:” ORIGINAL-TYPE (“,” PROTOCOL )* “{“</font></div><div class=""><font face="Monaco" class="">&nbsp; &nbsp; // Whatever, including exports…</font></div><div class=""><font face="Monaco" class="">“}”</font></div></blockquote><div class=""><br class=""></div><div class="">If there is nothing in the braces, then the new type doesn’t any operations (besides the default assignment and “&amp;” for function in-out parameters). You can get a reference to the object as the original type as “myNewObject.super”; it will have the same let/var status as the outer object’s declaration. Access to “super” lets you implement whatever new interface you want. Of course, you can implement new protocols added to the type list. The new type is implemented as the original one; no wrapping structs added; the same size, stride, and alignment.</div><div class=""><br class=""></div><div class="">You can republish parts of the old type’s interface. You use an “export OLD-NAME” declaration. There is also an “export default” declaration, which does:</div><div class=""><br class=""></div><div class="">* The application operator (i.e. “(whatever)”) for a function type</div><div class="">* The “.0”, “.1”, etc. member access for a tuple type</div><div class="">* All the original cases for an enumeration type</div><div class="">* Nothing for any other type</div><div class=""><br class=""></div><div class="">The default-export is optional for tuple and enumeration types, since you can export individual members or cases. Since there is no way to express the application operator in Swift, a function type’s retype has to use the default-export if it wants to export anything. All of the original type’s implementation of one of its direct or indirect protocols can be exported with “export TheOldProtocol”; but the new type won’t officially support the protocol unless it’s (directly or indirectly) in the new type's protocol list.</div><div class=""><br class=""></div><div class="">How do you initialize objects of this type? Besides using another object of the same type, you can use an object of the original type or of a retype that shares the implementation type as an initializer. If the initialization happens after the object’s declaration, then “expressionOfOtherType as MyReType” syntax has to be used. (Post-declaration initialization can use “myObject.super” instead.)</div><div class=""><br class=""></div><div class="">Now, I can do something like (assuming fixed-size arrays are added):</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">retype Complex&lt;T: SomeNumericProtocol&gt;: [2: T], Equatable /*, etc.*/ {</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">var re: T {</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">get { return super[0] }</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">set { super[0] = newValue }</font></div></blockquote></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">}</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">var im: T {</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">get { return super[1] }</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">set { super[1] = newValue }</font></div></blockquote></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">}</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class=""><br class=""></font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">init(_: UninitializedFlag) { &nbsp;//&nbsp;“UninitializedFlag” is a library enum type with case&nbsp;“.uninitialized"</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">super = [] &nbsp;// Leave&nbsp;</font><span style="font-family: Monaco;" class="">uninitialized</span></div></blockquote></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">}</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">init(real: T = 0, imaginary: T = 0) {</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">super = [real, imaginary]</font></div></blockquote></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">}</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">//…</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">}</font></div><div class=""><font face="Monaco" class=""><br class=""></font></div><div class=""><font face="Monaco" class="">func someFunc() {</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">let scalars: [_: Double] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">let rawComplexes = scalars as [5: [2: Double]] &nbsp;// Reshape command</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">let firstComplex = rawComplexes[0] as Complex &nbsp;// May have to use “Complex&lt;Double&gt;” if the “as” is too indirect.</font></div></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">//...</font></div></blockquote></blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">}</font></div></blockquote><div class=""><br class=""></div><div style="font-size: 13px;" class=""><b class="">Object Aliasing</b></div><div class=""><br class=""></div><div class="">But what if I want to work on those scalars directly? What if I want to mutate my complex number objects and update the scalars too? What if we add a “pose” declaration, at the same level as “let” and “var”?</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Monaco" class="">var scalars: [_: Double] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</font></div><div class=""><font face="Monaco" class="">pose rawComplexes: [5: [2: Double]] = scalars &nbsp;// OK as they have the same stride and inner non-array type</font></div><div class=""><font face="Monaco" class="">pose complexes: [5: Complex] = rawComplexes</font></div><div class=""><font face="Monaco" class=""><br class=""></font></div><div class=""><font face="Monaco" class="">complexes[0].re = -11</font></div><div class=""><font face="Monaco" class="">assert(scalars[0] == -11)</font></div></blockquote><div class=""><br class=""></div><div class="">The source of a pose has to have an equal or greater scope (and lifetime) than the alias. (Instance- and type-level properties of a type definition are considered separately. An instance-level property can pose over a type-level one. A function-scope object can pose over a function argument, as long as it doesn’t try to persist after function-end.) A pose has the same let/var status as its source. (The source may not be directly marked as “let” or “var,” it may be a “pose” itself.) A pose always has to be initialized at declaration time with its source.</div><div class=""><br class=""></div><div class="">[Note: the “pose” idea sprang into my head while writing the “retype” one. So you can ignore “pose” if you want to focus on “retype” first.]</div><br class=""><div class="">
<div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">—&nbsp;</div><div class="">Daryle Walker<br class="">Mac, Internet, and Video Game Junkie<br class="">darylew AT mac DOT com&nbsp;</div></div>
</div>
<br class=""></body></html>