<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="">Hi everyone,<div class=""><br class=""></div><div class="">I was wondering if there was a trick to get the following thing accomplished within the framework of Swift generics. I am using&nbsp;<a href="https://github.com/mattt/Surge" class="">Surge</a>, a very nice and useful wrapper for the Accelerate framework. The problem is that I would like to extend the functionality of Surge in my own graphics library to include geometric constructs and I’ve run into an issue.</div><div class=""><br class=""></div><div class="">In order to use the appropriate Accelerate function call, Surge duplicates each function on the parameter types, either Float or Double. Ideally, I think there should be a better way to accomplish this with Swift generics, but perhaps that is a separate discussion. As an example consider dot product of Arrays (Vectors).</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">public</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> dot(x: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Float</span>], y: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Float</span>]) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Float</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">precondition</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(x.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">count</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> == y.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">count</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">, </span>"Vectors must have equal count"<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> result: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Float</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0.0</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">vDSP_dotpr</span>(x, <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>, y, <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>, &amp;result, <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">vDSP_Length</span>(x.<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">count</span>))</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> result</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">public</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> dot(x: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span>], y: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span>]) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">precondition</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">(x.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">count</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> == y.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">count</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">, </span>"Vectors must have equal count"<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> result: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span> = <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">0.0</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">vDSP_dotprD</span>(x, <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>, y, <span style="font-variant-ligatures: no-common-ligatures; color: #272ad8" class="">1</span>, &amp;result, <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">vDSP_Length</span>(x.<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">count</span>))</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> result</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Helvetica; font-size: 12px;" class="">Consider, now, that I want to make a new function that uses one of these Surge functions. Am I correct in saying that I must define two functions, one for Float and one for Double?&nbsp;</div><div style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></div><div class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> normalized(x: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Float</span>]) -&gt; [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Float</span>] {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> x <span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">/</span> <span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">sum</span>(x)</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">}</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> normalized(x: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span>]) -&gt; [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Double</span>] {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span> x <span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">/</span> <span style="font-variant-ligatures: no-common-ligatures; color: #31595d" class="">sum</span>(x)</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">}</div><div style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px;" class="">Is there no way to get this done with generics? Writing the function with generic parameters yields the following error:</div><div style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> normalized&lt;T <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>: FloatingPointType, <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>: FloatLiteralConvertible&gt;(x: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>]) -&gt; [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>] {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> x / sum(x) </span>// Error: Cannot invoke 'sum' with an argument list of type '([T])'</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">}</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Let’s assume, however that I go ahead and create two ‘normalized’ functions. I then want to create a new struct type call Plane. I would like to be able to construct a Plane using a normal vector and a point. Like so:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">struct</span> Plane&lt;T <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> T: FloatingPointType, T: FloatLiteralConvertible&gt; {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> normal: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>]</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">let</span> distance: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span></div><p style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; min-height: 13px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></p><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">init</span>(normal: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>], point: [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">T</span>]) {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.normal = normalized(normal) </span>// Error: Ambiguous reference to member 'normalized'</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; color: rgb(0, 132, 0);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">.distance = dot(normal, y: point) </span>// Error: Cannot invoke 'dot' with an argument list of type '([T], y: [T])'</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp; }</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">}</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Yet as you can see there are still errors. In fact, as far as I can figure there is no way I can accomplish this last bit, no matter how much duplication I’m willing to tolerate.&nbsp;</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Any help that anyone can provide would be much appreciated.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Thanks!</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Tyler</div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><br class=""></div></div></div></div></div></body></html>