Actually, I do think @nuclearace's suggestion is somewhat better than the manual case, only because if you pass an invalid type when creating an instance of Uniforms, you get a compiler error which tells you the proper type, which you can then copy and use as a typealias, for example:
typealias Weights = (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float)
let t = weights.withUnsafeBytes {
return $0.bindMemory(to: Weights.self )[0]
}
This is still not great, or even good, but it at least saves me from typing out the tuple manually 