<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="">Yes, something like this would be handy! Even the ability to coerce from one type to another, if that destination type has a keyless initialiser for the source type.</div><div class=""><br class=""></div><div class="">Here’s some imaginary syntax for with Erica’s array example. I would prefer a way to not have a separate type for ‘DoubleSource’ if possible.</div><div class=""><br class=""></div><div class="">let foo: [Double] = Double[int32, int8, double, cgfloat, float] // As if you had written Double(…) around each item</div><div class=""><br class=""></div><div class="">or</div><div class=""><br class=""></div><div class="">let foo: [Double] = [int32, int8, double, cgfloat, float](Double.init) // // As if you had written Double(…) around each item</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Here’s another use case I’ve had:</div><div class=""><br class=""></div><div class="">enum Deferred<Result> {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>typealias UseResult = () throws -> Result<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case unit(UseResult)<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case future(((UseResult) -> ()) -> ())</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>init(_ subroutine: UseResult) {<br class=""><span class="Apple-tab-span" style="white-space:pre">                </span>self = .unit(subroutine)<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class="">}</div><div class=""><br class=""></div><div class=""><div class="">Instead of this:</div><div class=""><br class=""></div><div class=""><div class="">struct Example {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>func next() -> Deferred<Int> {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>return Deferred{ 42 }</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div class="">}</div></div></div><div class=""><br class=""></div><div class="">It would be nice to be able to do this:</div><div class=""><br class=""></div><div class=""><div class="">struct Example {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>func next() -> Deferred<Int> {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>return { 42 }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div></div><div class=""><br class=""></div><div class="">I don’t know if that’s playing with fire, but it would be seemingly nice for Swift to automatically infer what I want.</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On 17 May 2016, at 12:15 AM, Erica Sadun 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=""><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="">The following situation has come up for me now and then: I want to work with groups of types that share a common behavior, but that behavior is not sourced in the implementation of the Self type but rather in a secondary type. Specifically, could Swift be extended to introduce a protocol requirement that discusses how a type is used by a secondary type and not the kind of member provided directly by the type. For example:<div class=""><div class=""><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">// These are all numbers</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> int32: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int32</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1; </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> int8: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">Int8</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);" class="">1</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> double: </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1.0; </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> cgfloat: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">CGFloat</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);" class="">1.0; </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> float: </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">Float</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> = </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(39, 42, 216);" class="">1</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; min-height: 21px;" class="">// They can all be converted to Double using Double.init</div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">int32</span><span style="font-variant-ligatures: no-common-ligatures;" class="">); </span><span style="font-variant-ligatures: no-common-ligatures;" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">int8</span><span style="font-variant-ligatures: no-common-ligatures;" class="">); </span><span style="font-variant-ligatures: no-common-ligatures;" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">); </span><span style="font-variant-ligatures: no-common-ligatures;" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="color: rgb(79, 129, 135); font-variant-ligatures: no-common-ligatures;" class="">cgfloat</span><span style="font-variant-ligatures: no-common-ligatures;" class="">); </span><span style="font-variant-ligatures: no-common-ligatures;" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">float</span><span style="font-variant-ligatures: no-common-ligatures;" class="">)</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; min-height: 21px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; min-height: 21px;" class="">// A heterogeneous collection cannot be unified into a single protocol</div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> foo: [</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Any</span><span style="font-variant-ligatures: no-common-ligatures;" class="">] = [</span><span style="font-variant-ligatures: no-common-ligatures" class="">int32</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures" class="">int8</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures" class="">double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures" class="">cgfloat</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures" class="">float</span><span style="font-variant-ligatures: no-common-ligatures;" class="">]</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">foo</span><span style="font-variant-ligatures: no-common-ligatures" class="">.map{ </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures" class="">($0) } // Can't work, Any doesn't make any sense here</span></div><div class=""><br class=""></div><div class="">The kind of thing I am looking for is something like this:</div></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> DoubleSource {</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> Double.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">Self</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class="">In other words, the functionality constraint is not provided by the base type but by a second type to which the base type is a parameter.</div><div class=""><br class=""></div><div class="">My use case is for unrelated types (that is, there's no inheritance relationship like you'd find in `UISwitch` and `UISlider`, for example -- both of which are `UIView` and `UIControl`), where there is a secondary type that implements behavior with the same signature for these separate types, such as the Double initializer. Where this pops up the most is in working with Sprite/SceneKit, GamePlayKit, QuartzCore, Accelerate, unifying my numeric values so I can mix and match calls and clean up the flow where some calls require CGPoint, others need float2, etc. Ideally I would be able to </div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures" class="">DoubleSource</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> {</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> bar() -> </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> value = </span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span><span style="font-variant-ligatures: no-common-ligatures;" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures;" class="">)</span></div><div style="margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> // do something with value; return T of some type</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 18px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);" class="">let</span><span style="font-variant-ligatures: no-common-ligatures;" class=""> foo: [</span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">DoubleSource</span><span style="font-variant-ligatures: no-common-ligatures;" class="">] = [</span><span style="font-variant-ligatures: no-common-ligatures;" class="">int32</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures;" class="">int8</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures;" class="">double</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures;" class="">cgfloat</span><span style="font-variant-ligatures: no-common-ligatures;" class="">, </span><span style="font-variant-ligatures: no-common-ligatures;" class="">float</span><span style="font-variant-ligatures: no-common-ligatures;" class="">]</span></div><div style="margin: 0px; font-size: 15px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);" class="">foo</span><span style="font-variant-ligatures: no-common-ligatures;" class="">.map{ </span><span style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);" class="">bar</span><span style="font-variant-ligatures: no-common-ligatures;" class="">($0) } // would work</span></div></div><div class=""><br class=""></div><div class="">Would something like this be a valuable direction to extend Swift? Is it something found in other languages? Does this kind of requirement have a name? Is it *pragmatically* possible to introduce it in Swift?</div></div><div class=""><br class=""></div><div class="">Thanks in advance for your thoughts and insights.</div><div class=""><br class=""></div><div class="">-- E</div><div class=""><br class=""></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>