<div dir="ltr">How about this...<div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> dot<genType:<span style="color:rgb(79,129,135)">FloatingPointVectorType</span>>(x:<span style="color:rgb(112,61,170)">genType</span>, <span style="color:rgb(187,44,162)">_</span> y:<span style="color:rgb(112,61,170)">genType</span>) -> <span style="color:rgb(112,61,170)">genType</span>.<span style="color:rgb(112,61,170)">Element</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">let</span> a = <span style="color:rgb(112,61,170)">genType</span>(x, y, <span style="color:rgb(49,89,93)">*</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> a.<span style="color:rgb(61,29,129)">reduce</span>(<span style="color:rgb(112,61,170)">genType</span>.<span style="color:rgb(79,129,135)">Element</span>(<span style="color:rgb(39,42,216)">0</span>)) { $0 <span style="color:rgb(49,89,93)">+</span> ($1 <span style="color:rgb(187,44,162)">as</span>! <span style="color:rgb(112,61,170)">genType</span>.<span style="color:rgb(112,61,170)">Element</span>) }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p>and this...<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> normalize<genType:<span style="color:rgb(79,129,135)">FloatingPointVectorType</span>>(x:<span style="color:rgb(112,61,170)">genType</span>) -> <span style="color:rgb(112,61,170)">genType</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> x <span style="color:rgb(49,89,93)">/</span> <span style="color:rgb(49,89,93)">length</span>(x)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p>These are the actual implementations from SwiftGL. Here's what your Plane looks like in SwiftGL:</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">struct</span> Plane<T:FloatingPointScalarType> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">let</span> normal: <span style="color:rgb(79,129,135)">Vector3</span><<span style="color:rgb(112,61,170)">T</span>></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">let</span> distance: <span style="color:rgb(112,61,170)">T</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">init</span>(normal: <span style="color:rgb(79,129,135)">Vector3</span><<span style="color:rgb(112,61,170)">T</span>>, point: <span style="color:rgb(79,129,135)">Vector3</span><<span style="color:rgb(112,61,170)">T</span>>) {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">normal</span> = <span style="color:rgb(49,89,93)">normalize</span>(normal)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">distance</span> = <span style="color:rgb(49,89,93)">dot</span>(normal, point)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</p></div><div><br></div><div>So not only is it possible, it's been done. There's no "trick" to this. It works because I put a lot of time into making it work.</div><div><br></div><div><a href="https://github.com/AE9RB/SwiftGL">https://github.com/AE9RB/SwiftGL</a><br></div><div><br></div><div>-david </div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 18, 2016 at 4:23 PM, Tyler Fleming Cloutier via swift-users <span dir="ltr"><<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi everyone,<div><br></div><div>I was wondering if there was a trick to get the following thing accomplished within the framework of Swift generics. I am using <a href="https://github.com/mattt/Surge" target="_blank">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><br></div><div>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><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> dot(x: [<span style="color:rgb(112,61,170)">Float</span>], y: [<span style="color:rgb(112,61,170)">Float</span>]) -> <span style="color:rgb(112,61,170)">Float</span> {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(61,29,129)">precondition</span><span style="color:rgb(0,0,0)">(x.</span><span style="color:rgb(112,61,170)">count</span><span style="color:rgb(0,0,0)"> == y.</span><span style="color:rgb(112,61,170)">count</span><span style="color:rgb(0,0,0)">, </span>"Vectors must have equal count"<span style="color:rgb(0,0,0)">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> result: <span style="color:rgb(112,61,170)">Float</span> = <span style="color:rgb(39,42,216)">0.0</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(61,29,129)">vDSP_dotpr</span>(x, <span style="color:rgb(39,42,216)">1</span>, y, <span style="color:rgb(39,42,216)">1</span>, &result, <span style="color:rgb(112,61,170)">vDSP_Length</span>(x.<span style="color:rgb(112,61,170)">count</span>))</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> result</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">public</span> <span style="color:rgb(187,44,162)">func</span> dot(x: [<span style="color:rgb(112,61,170)">Double</span>], y: [<span style="color:rgb(112,61,170)">Double</span>]) -> <span style="color:rgb(112,61,170)">Double</span> {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(61,29,129)">precondition</span><span style="color:rgb(0,0,0)">(x.</span><span style="color:rgb(112,61,170)">count</span><span style="color:rgb(0,0,0)"> == y.</span><span style="color:rgb(112,61,170)">count</span><span style="color:rgb(0,0,0)">, </span>"Vectors must have equal count"<span style="color:rgb(0,0,0)">)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">var</span> result: <span style="color:rgb(112,61,170)">Double</span> = <span style="color:rgb(39,42,216)">0.0</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(61,29,129)">vDSP_dotprD</span>(x, <span style="color:rgb(39,42,216)">1</span>, y, <span style="color:rgb(39,42,216)">1</span>, &result, <span style="color:rgb(112,61,170)">vDSP_Length</span>(x.<span style="color:rgb(112,61,170)">count</span>))</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> result</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;line-height:normal"><div>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? </div><div><br></div><div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:rgb(187,44,162)">func</span> normalized(x: [<span style="color:rgb(112,61,170)">Float</span>]) -> [<span style="color:rgb(112,61,170)">Float</span>] {</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"> <span style="color:rgb(187,44,162)">return</span> x <span style="color:rgb(49,89,93)">/</span> <span style="color:rgb(49,89,93)">sum</span>(x)</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal">}</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;min-height:13px"><br></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:rgb(187,44,162)">func</span> normalized(x: [<span style="color:rgb(112,61,170)">Double</span>]) -> [<span style="color:rgb(112,61,170)">Double</span>] {</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"> <span style="color:rgb(187,44,162)">return</span> x <span style="color:rgb(49,89,93)">/</span> <span style="color:rgb(49,89,93)">sum</span>(x)</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal">}</div><div><br></div><div>Is there no way to get this done with generics? Writing the function with generic parameters yields the following error:</div><div><br></div><div><div style="margin:0px;line-height:normal"><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:rgb(187,44,162)">func</span> normalized<T <span style="color:rgb(187,44,162)">where</span> <span style="color:rgb(112,61,170)">T</span>: FloatingPointType, <span style="color:rgb(112,61,170)">T</span>: FloatLiteralConvertible>(x: [<span style="color:rgb(112,61,170)">T</span>]) -> [<span style="color:rgb(112,61,170)">T</span>] {</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(187,44,162)">return</span><span style="color:rgb(0,0,0)"> 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">}</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal">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"><br></div><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><span style="color:rgb(187,44,162)">struct</span> Plane<T <span style="color:rgb(187,44,162)">where</span> T: FloatingPointType, T: FloatLiteralConvertible> {</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"> <span style="color:rgb(187,44,162)">let</span> normal: [<span style="color:rgb(112,61,170)">T</span>]</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"> <span style="color:rgb(187,44,162)">let</span> distance: <span style="color:rgb(112,61,170)">T</span></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;min-height:13px"> <br></div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"> <span style="color:rgb(187,44,162)">init</span>(normal: [<span style="color:rgb(112,61,170)">T</span>], point: [<span style="color:rgb(112,61,170)">T</span>]) {</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(187,44,162)">self</span><span style="color:rgb(0,0,0)">.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)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(187,44,162)">self</span><span style="color:rgb(0,0,0)">.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"> }</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal">}</div><div style="font-family:Menlo;font-size:11px;margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal">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. </div><div style="margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal">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"><br></div><div style="margin:0px;line-height:normal">Thanks!</div><span class="HOEnZb"><font color="#888888"><div style="margin:0px;line-height:normal"><br></div><div style="margin:0px;line-height:normal">Tyler</div></font></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div></div></div></div></div></div></div><br>_______________________________________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org">swift-users@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-users</a><br>
<br></blockquote></div><br></div></div>