[swift-users] Swift Initializer Generics

David Turnbull dturnbull at gmail.com
Mon Jan 18 19:06:13 CST 2016


How about this...

public func dot<genType:FloatingPointVectorType>(x:genType, _ y:genType) ->
genType.Element {

    let a = genType(x, y, *)

    return a.reduce(genType.Element(0)) { $0 + ($1 as! genType.Element) }

}


and this...


public func normalize<genType:FloatingPointVectorType>(x:genType) -> genType
{

    return x / length(x)

}


These are the actual implementations from SwiftGL. Here's what your Plane
looks like in SwiftGL:

struct Plane<T:FloatingPointScalarType> {

    let normal: Vector3<T>

    let distance: T


    init(normal: Vector3<T>, point: Vector3<T>) {

        self.normal = normalize(normal)

        self.distance = dot(normal, point)

    }

}

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.

https://github.com/AE9RB/SwiftGL

-david

On Mon, Jan 18, 2016 at 4:23 PM, Tyler Fleming Cloutier via swift-users <
swift-users at swift.org> wrote:

> Hi everyone,
>
> I was wondering if there was a trick to get the following thing
> accomplished within the framework of Swift generics. I am using Surge
> <https://github.com/mattt/Surge>, 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.
>
> 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).
>
> public func dot(x: [Float], y: [Float]) -> Float {
>     precondition(x.count == y.count, "Vectors must have equal count")
>
>     var result: Float = 0.0
>     vDSP_dotpr(x, 1, y, 1, &result, vDSP_Length(x.count))
>
>     return result
> }
>
>
> public func dot(x: [Double], y: [Double]) -> Double {
>     precondition(x.count == y.count, "Vectors must have equal count")
>
>     var result: Double = 0.0
>     vDSP_dotprD(x, 1, y, 1, &result, vDSP_Length(x.count))
>
>     return result
> }
>
> 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?
>
> func normalized(x: [Float]) -> [Float] {
>     return x / sum(x)
> }
>
> func normalized(x: [Double]) -> [Double] {
>     return x / sum(x)
> }
>
> Is there no way to get this done with generics? Writing the function with
> generic parameters yields the following error:
>
> func normalized<T where T: FloatingPointType, T:
> FloatLiteralConvertible>(x: [T]) -> [T] {
>     return x / sum(x) // Error: Cannot invoke 'sum' with an argument list
> of type '([T])'
> }
>
> 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:
>
> struct Plane<T where T: FloatingPointType, T: FloatLiteralConvertible> {
>     let normal: [T]
>     let distance: T
>
>     init(normal: [T], point: [T]) {
>         self.normal = normalized(normal) // Error: Ambiguous reference to
> member 'normalized'
>         self.distance = dot(normal, y: point) // Error: Cannot invoke
> 'dot' with an argument list of type '([T], y: [T])'
>     }
> }
>
> 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.
>
> Any help that anyone can provide would be much appreciated. Sorry for the
> duplicate email, I was off-list before.
>
> Thanks!
>
> Tyler
>
>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160118/ee9e97bd/attachment.html>


More information about the swift-users mailing list