<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=""><div class="">The Completing Generics Manifesto suggests a more universal solution with generic value parameters which is my vote:</div><div class=""><pre style="white-space: pre-wrap; font-variant-ligatures: normal; font-variant-position: normal; font-variant-numeric: normal; font-variant-alternates: normal; font-variant-east-asian: normal; line-height: normal; widows: 1;" class="">Generic value parameters

Currently, Swift’s generic parameters are always types. One could imagine allowing generic parameters that are values, e.g.,

struct MultiArray&lt;T, let Dimensions: Int&gt; { // specify the number of dimensions to the array
  subscript (indices: Int...) -&gt; T {
    get {
      require(indices.count == Dimensions)
      // ...
    }
}

A suitably general feature might allow us to express fixed-length array or vector types as a standard library component, and perhaps also allow one to implement a useful dimensional analysis library. Tackling this feature potentially means determining what it is for an expression to be a “constant expression” and diving into dependent-typing, hence the “maybe”.</pre></div><div class=""><br class=""></div>
&gt; To better support interfacing with lower level systems, like graphics<br class="">&gt; libraries for example, it would be helpful to support the concept of<br class="">&gt; contiguous variables. The most common use case for this would be to create<br class="">&gt; a Matrix struct that can be passed as data into something like Metal. This<br class="">&gt; can be accomplished now, using something like the following:<br class="">&gt; <br class="">&gt; Current Option 1:<br class="">&gt; <br class="">&gt; struct Matrix2x2 {<br class="">&gt; var m00: Float<br class="">&gt; var m01: Float<br class="">&gt; var m10: Float<br class="">&gt; var m11: Float<br class="">&gt; }<br class="">&gt; <br class="">&gt; OR<br class="">&gt; Current Option 2:<br class="">&gt; <br class="">&gt; struct Matrix2x2 {<br class="">&gt; var m: (Float, Float, Float, Float)<br class="">&gt; }<br class="">&gt; <br class="">&gt; OR<br class="">&gt; Current Option 3:<br class="">&gt; <br class="">&gt; struct Matrix2x2 {<br class="">&gt; var m: [Float]<br class="">&gt; }<br class="">&gt; <br class="">&gt; Options 1&amp;2 allow for the compiler to enforce the fixed number of<br class="">&gt; elements and also for the data to be easily passed into graphics libraries<br class="">&gt; as their memory layout is somewhat predictable using sizeof, strideof, and<br class="">&gt; alignof. The downside is that you lose the ability to easily subscript or<br class="">&gt; iterate the elements.<br class="">&gt; <br class="">&gt; Option 3 does allow subscripting and iteration, but does not at compile<br class="">&gt; time enforce a fixed number of elements and is not as easily passed into a<br class="">&gt; library that expects to receive the raw data of the matrix.<br class="">&gt; <br class="">&gt; <br class="">&gt; Contiguous Variables:<br class="">&gt; <br class="">&gt; struct Matrix2x2 {<br class="">&gt; var m: Float:2*2<br class="">&gt; }<br class="">&gt; <br class="">&gt; The variable `m` represents a series of 4 contiguous Float values. The<br class="">&gt; specific number of values must be a compile time constant. The only needed<br class="">&gt; functionality includes `count`, `subscript`, and iteration. To make things<br class="">&gt; easier to implement and to help avoid confusion and more complex<br class="">&gt; documentation, multiple dimensions are not allowed. To define multiple<br class="">&gt; dimensions you must provide your own ordering by wrapping this type in<br class="">&gt; another type and providing a custom subscript implementation. For example:<br class="">&gt; <br class="">&gt; struct RowMajorMatrix2x2 {<br class="">&gt; var m: Float:2*2<br class="">&gt; <br class="">&gt; static let rows = 2<br class="">&gt; static let columns = 2<br class="">&gt; <br class="">&gt; subscript(row: Int, column: Int) -&gt;Float {<br class="">&gt; return m[column * Matrix2x2.rows + row]<br class="">&gt; }<br class="">&gt; }<br class="">&gt; <br class="">&gt; sizeof(Matrix2x2) is 16<br class="">&gt; strideof(Matrix2x2) is 16<br class="">&gt; <br class="">&gt; m.count is essentially a compile time constant and is not stored with the<br class="">&gt; rest of the data but is available and can also be used to do runtime bounds<br class="">&gt; checking.<br class="">&gt; <br class="">&gt; struct Vector3 {<br class="">&gt; var v: Float:3<br class="">&gt; }<br class="">&gt; <br class="">&gt; sizeof(Vector3) is 12<br class="">&gt; strideof(Vector3) is 12<br class="">&gt; <br class="">&gt; C code should also now be able to expose data types that contain fixed<br class="">&gt; sized arrays within them.<br class="">&gt; <br class="">&gt; <br class="">&gt;<span class="Apple-converted-space">&nbsp;</span>

</body></html>