<html><body><div>I think the name should be changed to NumberBox or something similar. A box is something very generic and should not have number related associated types.<br></div><div><br data-mce-bogus="1"></div><div>-Thorsten<br data-mce-bogus="1"></div><div><br>Am 06. Januar 2016 um 18:15 schrieb James Campbell <james@supmenow.com>:<br><br><div><blockquote type="cite"><div class="msg-quote"><div dir="ltr">I've managed to implement this already in the language with a few ugly corners due to the lack of generic protocols.<div><br></div><div>I created a protocol based on Box (<a href="https://github.com/robrix/Box/" data-mce-href="https://github.com/robrix/Box/">https://github.com/robrix/Box/</a>) which works really well. I have extended this to handle certain special protocols like Equatable so you can do SpecialType == SpecialType, and even literalConversion.</div><div><br></div><div>There is however a lot of boilerplate:</div><div><br></div><div>- You have to declare all of your Convertible protocols for converting from one type to another</div><div>- You have to define an empty init so the protocol extensions have something to chain to.</div><div>- You need to write the value property with type.</div><div><br></div><div>Due to the lack of protocol generics, you also need to have a protocol for every type you wish to box which sets the associated type. Of course I could have done this with classes but I wanted to keep this as a value type :).</div><div><br></div><div>With member-wise initializations and generic protocols this could be achievable just by adding a Box protocol to the standard library.</div><div><br></div><div>Here is my implementation of Box as a protocol:</div><div><br></div><div><p class=""><b><span class="">protocol</span><span class=""> Box: </span><span class="">CustomStringConvertible</span><span class="">, </span><span class="">CustomDebugStringConvertible</span><span class=""> {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">typealias</span><span class=""> FloatLiteralType = Double</span></b></p><p class=""><b><span class=""> </span><span class="">typealias</span><span class=""> IntegerLiteralType = Int</span></b></p><p class=""><b><span class=""> </span><span class="">typealias</span><span class=""> BoxType = Any</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">var</span><span class=""> value: </span><span class="">BoxType</span><span class=""> { </span><span class="">get</span><span class=""> </span><span class="">set</span><span class=""> }</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">()</span></b></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">BoxType</span><span class="">)</span></b></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">extension</span><span class=""> </span><span class="">Box</span><span class=""> </span><span class="">where</span><span class=""> BoxType: CustomStringConvertible {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">var</span><span class=""> description: </span><span class="">String</span><span class=""> {</span></b></p><p class=""><b><span class=""> </span><span class="">return</span><span class=""> </span><span class="">self</span><span class="">.</span><span class="">value</span><span class="">.</span><span class="">description</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">var</span><span class=""> debugDescription: </span><span class="">String</span><span class=""> {</span></b></p><p class=""><b><span class=""> </span><span class="">return</span><span class=""> </span><span class="">"</span><span class="">\</span><span class="">(</span><span class="">self</span><span class="">.</span><span class="">value</span><span class="">.</span><span class="">description</span><span class="">)</span><span class="">㎭</span><span class="">"</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><span class=""><b>//MARK: FloatingPointBox</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">protocol</span><span class=""> FloatingPointBox: </span><span class="">Box</span><span class="">, </span><span class="">FloatLiteralConvertible</span><span class="">, </span><span class="">IntegerLiteralConvertible</span><span class=""> {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">typealias</span><span class=""> BoxType = Double</span></b></p><p class=""><b><span class=""> </span><span class="">typealias</span><span class=""> FloatLiteralConvertible = Double</span></b></p><p class=""><b><span class=""> </span><span class="">typealias</span><span class=""> IntegerLiteralConvertible = Int</span></b></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">extension</span><span class=""> </span><span class="">Box</span><span class=""> </span><span class="">where</span><span class=""> </span><span class="">Self</span><span class="">.BoxType == Double {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Double</span><span class="">) {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">()</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = value</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Int</span><span class="">) {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">()</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = </span><span class="">Double</span><span class="">(value)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">extension</span><span class=""> </span><span class="">FloatLiteralType</span><span class=""> {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class=""><T: </span><span class="">Box</span><span class=""> </span><span class="">where</span><span class=""> </span><span class="">T</span><span class="">.</span><span class="">BoxType</span><span class=""> == </span><span class="">Double</span><span class=""> >(</span><span class="">_</span><span class=""> box: </span><span class="">T</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(box.</span><span class="">value</span><span class="">)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class=""><T: </span><span class="">Box</span><span class=""> </span><span class="">where</span><span class=""> </span><span class="">T</span><span class="">.</span><span class="">BoxType</span><span class=""> == </span><span class="">Int</span><span class=""> >(</span><span class="">_</span><span class=""> box: </span><span class="">T</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(box.</span><span class="">value</span><span class="">)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">extension</span><span class=""> </span><span class="">CGFloat</span><span class=""> {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class=""><T: </span><span class="">Box</span><span class=""> </span><span class="">where</span><span class=""> </span><span class="">T</span><span class="">.</span><span class="">BoxType</span><span class=""> == </span><span class="">Double</span><span class=""> >(</span><span class="">_</span><span class=""> box: </span><span class="">T</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(box.</span><span class="">value</span><span class="">)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class=""><T: </span><span class="">Box</span><span class=""> </span><span class="">where</span><span class=""> </span><span class="">T</span><span class="">.</span><span class="">BoxType</span><span class=""> == </span><span class="">Int</span><span class=""> >(</span><span class="">_</span><span class=""> box: </span><span class="">T</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(box.</span><span class="">value</span><span class="">)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><span class=""><b>//Adding FloatLiteralConvertible, IntegerLiteralConvertible</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">extension</span><span class=""> </span><span class="">FloatingPointBox</span><span class=""> </span><span class="">where</span><span class=""> </span><span class="">Self</span><span class="">.BoxType == Double, </span><span class="">Self</span><span class="">.FloatLiteralConvertible == Double {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(floatLiteral value: </span><span class="">Double</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(value)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(integerLiteral value: </span><span class="">Int</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(value)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class=""><T: </span><span class="">IntegerType</span><span class="">>(</span><span class="">_</span><span class=""> value: </span><span class="">T</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(value)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p></div><div><br></div><div>Here is my example of using the Box protocol:</div><div><p class=""><b><span class="">struct</span><span class=""> Degree: </span><span class="">FloatingPointBox</span><span class=""> {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">var</span><span class=""> value: </span><span class="">Double</span><span class=""> = </span><span class="">0</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">()</span></b></p><p class=""><span class=""><b> {</b></span></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">protocol</span><span class=""> DegreeConvertiable {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(degreeLiteral value: </span><span class="">Degree</span><span class="">)</span></b></p><p class=""><span class=""><b>}</b></span></p><p class=""><b><span class=""></span><br></b></p><p class=""><b><span class="">extension</span><span class=""> </span><span class="">Degree</span><span class="">: </span><span class="">RadianConvertiable</span><span class=""> {</span></b></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(radianLiteral value: </span><span class="">Radian</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">value</span><span class=""> = </span><span class="">Double</span><span class="">(value) * </span><span class="">180.0</span><span class=""> / </span><span class="">M_PI</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b> </b></span></p><p class=""><b><span class=""> </span><span class="">init</span><span class="">(</span><span class="">_</span><span class=""> value: </span><span class="">Radian</span><span class="">) {</span></b></p><p class=""><b><span class=""> </span><span class="">self</span><span class="">.</span><span class="">init</span><span class="">(radianLiteral: value)</span></b></p><p class=""><span class=""><b> }</b></span></p><p class=""><span class=""><b>}</b></span></p></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 5, 2016 at 5:24 PM, Matthew Johnson via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0 0 0 0.8ex; border-left: 1px #ccc solid; padding-left: 1ex;" data-mce-style="margin: 0 0 0 0.8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><span class=""><br> > On Jan 5, 2016, at 11:16 AM, Thorsten Seitz via swift-evolution <<a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br> ><br> ><br> >> Am 05.01.2016 um 17:11 schrieb Grzegorz Adam Hankiewicz via swift-evolution <<a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>:<br> >><br> >> The ideal would be for the compiler to pretend Euros or RefTablePk are different types, yet use their parent type at the binary level. This needs a specific syntax to teach the compiler which existing methods/operations are allowed on the new fake types and which aren’t. These new distinct types would *borrow* previous implementations.<br> ><br> > What about citing the relevant protocols in the newtype definition? This should include the ability to use my own protocols to which I have made the underlying type conform to by an extension.<br> <br> </span>This is how my forwarding proposal works. The newtype syntax I suggested as a possible extension looks like this:<br> <br> newtype Euro = Double forwarding Addable, Subtractable<br> <br> The keyword could be different, but I think `forwarding` is not bad. When I complete the second draft I think it will make even more sense. The forwarding facility has features to handle non-trivial cases (Self and associated type requirements, etc).<br><div class="HOEnZb"><div class="h5"><br> ><br> > Throwing some syntax into the discussion:<br> ><br> > newtype Euro = Double : Addable, Subtractable<br> ><br> > where I have defined the protocols Addable and Subtractable somewhere and made Double conform to them if all this is not provided by the standard library.<br> > The implementation of Euro then borrows the implementation of Double for these protocols.<br> ><br> > -Thorsten<br> > _______________________________________________<br> > swift-evolution mailing list<br> > <a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br> > <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" data-mce-href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br> <br> _______________________________________________<br> swift-evolution mailing list<br> <a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" data-mce-href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div><span style="font-size: 16px; line-height: 19.2px;" data-mce-style="font-size: 16px; line-height: 19.2px;"></span><span style="font-size: 12.8px;" data-mce-style="font-size: 12.8px;"> Wizard</span><br></div><div><a href="mailto:james@supmenow.com" data-mce-href="mailto:james@supmenow.com">james@supmenow.com</a><br data-mce-bogus="1"></div><div>+44 7523 279 698</div></div></div></div></div></div></div></div></blockquote></div></div></body></html>