<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="color: rgb(187, 44, 162);" class="">public</span>&nbsp;<span style="color: rgb(187, 44, 162);" class="">func</span>&nbsp;dot(x: [<span style="color: rgb(112, 61, 170);" class="">Float</span>], y: [<span style="color: rgb(112, 61, 170);" class="">Float</span>]) -&gt;&nbsp;<span style="color: rgb(112, 61, 170);" class="">Float</span>&nbsp;{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="color: rgb(0, 0, 0);" class="">&nbsp; &nbsp;&nbsp;</span><span style="color: rgb(61, 29, 129);" class="">precondition</span><span style="color: rgb(0, 0, 0);" class="">(x.</span><span style="color: rgb(112, 61, 170);" class="">count</span><span style="color: rgb(0, 0, 0);" class="">&nbsp;== y.</span><span style="color: rgb(112, 61, 170);" class="">count</span><span style="color: rgb(0, 0, 0);" class="">,&nbsp;</span>"Vectors must have equal count"<span style="color: rgb(0, 0, 0);" 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;&nbsp;<span style="color: rgb(187, 44, 162);" class="">var</span>&nbsp;result:&nbsp;<span style="color: rgb(112, 61, 170);" class="">Float</span>&nbsp;=&nbsp;<span style="color: rgb(39, 42, 216);" class="">0.0</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(61, 29, 129);" class="">vDSP_dotpr</span>(x,&nbsp;<span style="color: rgb(39, 42, 216);" class="">1</span>, y,&nbsp;<span style="color: rgb(39, 42, 216);" class="">1</span>, &amp;result,&nbsp;<span style="color: rgb(112, 61, 170);" class="">vDSP_Length</span>(x.<span style="color: rgb(112, 61, 170);" 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;&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span>&nbsp;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="color: rgb(187, 44, 162);" class="">public</span>&nbsp;<span style="color: rgb(187, 44, 162);" class="">func</span>&nbsp;dot(x: [<span style="color: rgb(112, 61, 170);" class="">Double</span>], y: [<span style="color: rgb(112, 61, 170);" class="">Double</span>]) -&gt;&nbsp;<span style="color: rgb(112, 61, 170);" class="">Double</span>&nbsp;{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);" class=""><span style="color: rgb(0, 0, 0);" class="">&nbsp; &nbsp;&nbsp;</span><span style="color: rgb(61, 29, 129);" class="">precondition</span><span style="color: rgb(0, 0, 0);" class="">(x.</span><span style="color: rgb(112, 61, 170);" class="">count</span><span style="color: rgb(0, 0, 0);" class="">&nbsp;== y.</span><span style="color: rgb(112, 61, 170);" class="">count</span><span style="color: rgb(0, 0, 0);" class="">,&nbsp;</span>"Vectors must have equal count"<span style="color: rgb(0, 0, 0);" 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;&nbsp;<span style="color: rgb(187, 44, 162);" class="">var</span>&nbsp;result:&nbsp;<span style="color: rgb(112, 61, 170);" class="">Double</span>&nbsp;=&nbsp;<span style="color: rgb(39, 42, 216);" class="">0.0</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(61, 29, 129);" class="">vDSP_dotprD</span>(x,&nbsp;<span style="color: rgb(39, 42, 216);" class="">1</span>, y,&nbsp;<span style="color: rgb(39, 42, 216);" class="">1</span>, &amp;result,&nbsp;<span style="color: rgb(112, 61, 170);" class="">vDSP_Length</span>(x.<span style="color: rgb(112, 61, 170);" 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;&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span>&nbsp;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 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 class=""><br class=""></div><div class=""><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class=""><span style="color: rgb(187, 44, 162);" class="">func</span>&nbsp;normalized(x: [<span style="color: rgb(112, 61, 170);" class="">Float</span>]) -&gt; [<span style="color: rgb(112, 61, 170);" class="">Float</span>] {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span>&nbsp;x&nbsp;<span style="color: rgb(49, 89, 93);" class="">/</span>&nbsp;<span style="color: rgb(49, 89, 93);" 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="color: rgb(187, 44, 162);" class="">func</span>&nbsp;normalized(x: [<span style="color: rgb(112, 61, 170);" class="">Double</span>]) -&gt; [<span style="color: rgb(112, 61, 170);" class="">Double</span>] {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">return</span>&nbsp;x&nbsp;<span style="color: rgb(49, 89, 93);" class="">/</span>&nbsp;<span style="color: rgb(49, 89, 93);" class="">sum</span>(x)</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">}</div><div class=""><br class=""></div><div class="">Is there no way to get this done with generics? Writing the function with generic parameters yields the following error:</div><div 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="color: rgb(187, 44, 162);" class="">func</span>&nbsp;normalized&lt;T&nbsp;<span style="color: rgb(187, 44, 162);" class="">where</span>&nbsp;<span style="color: rgb(112, 61, 170);" class="">T</span>: FloatingPointType,&nbsp;<span style="color: rgb(112, 61, 170);" class="">T</span>: FloatLiteralConvertible&gt;(x: [<span style="color: rgb(112, 61, 170);" class="">T</span>]) -&gt; [<span style="color: rgb(112, 61, 170);" 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="color: rgb(0, 0, 0);" class="">&nbsp; &nbsp;&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">return</span><span style="color: rgb(0, 0, 0);" class="">&nbsp;x / sum(x)&nbsp;</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="color: rgb(187, 44, 162);" class="">struct</span>&nbsp;Plane&lt;T&nbsp;<span style="color: rgb(187, 44, 162);" class="">where</span>&nbsp;T: FloatingPointType, T: FloatLiteralConvertible&gt; {</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">let</span>&nbsp;normal: [<span style="color: rgb(112, 61, 170);" class="">T</span>]</div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">let</span>&nbsp;distance:&nbsp;<span style="color: rgb(112, 61, 170);" class="">T</span></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal; min-height: 13px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="font-family: Menlo; font-size: 11px; margin: 0px; line-height: normal;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">init</span>(normal: [<span style="color: rgb(112, 61, 170);" class="">T</span>], point: [<span style="color: rgb(112, 61, 170);" 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="color: rgb(0, 0, 0);" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">self</span><span style="color: rgb(0, 0, 0);" class="">.normal = normalized(normal)&nbsp;</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="color: rgb(0, 0, 0);" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="color: rgb(187, 44, 162);" class="">self</span><span style="color: rgb(0, 0, 0);" class="">.distance = dot(normal, y: point)&nbsp;</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;&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. Sorry for the duplicate email, I was off-list before.</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></div></div></div></body></html>