<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="">This could potentially convert to Swift many library developers whose sanity depends on type guaranteed sequence sizes. I was just playing with Swift 2.2 along these lines, and got surprised how far I could get towards that ideal, see:&nbsp;<a href="http://codereview.stackexchange.com/q/124797/54297" class="">http://codereview.stackexchange.com/q/124797/54297</a>&nbsp;<div class=""><br class=""></div><div class="">For example, I got this to compile:<div class=""><br class=""></div><div class=""><div class=""><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #c8ace5" class="">let</span> v = Vector&lt;<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">__</span>&lt;<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">_4</span>,<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">_2</span>&gt;,<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">Int</span>&gt;(<span style="font-variant-ligatures: no-common-ligatures; color: #ff2600" class="">0</span>)</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #8f793a" class="">v</span>.elements.count <span style="font-variant-ligatures: no-common-ligatures; color: #cbcbcb" class="">// 42</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro'; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #c8ace5" class="">let</span> w = Vector&lt;<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">_3</span>,<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">Int</span>&gt;(<span style="font-variant-ligatures: no-common-ligatures; color: #ff2600" class="">0</span>)</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #8f793a" class="">w</span>.elements <span style="font-variant-ligatures: no-common-ligatures; color: #cbcbcb" class="">// [0, 0, 0]</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #8f793a" class="">w</span>[<span style="font-variant-ligatures: no-common-ligatures; color: #ff2600" class="">2</span>].value = <span style="font-variant-ligatures: no-common-ligatures; color: #ff2600" class="">5</span></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro'; min-height: 15px;" class=""><br class=""></div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #c8ace5" class="">for</span> x <span style="font-variant-ligatures: no-common-ligatures; color: #c8ace5" class="">in</span> w {</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro'; color: rgb(203, 203, 203);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">&nbsp; &nbsp; &nbsp; &nbsp; x </span>// 0, 0, 5</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class="">&nbsp; &nbsp; }</div></div><div class=""><br class=""></div><div class="">Once created, `v` and `w` here can never change size, not even from within the implementation.</div><div class=""><br class=""></div><div class="">milos</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 4 Apr 2016, at 21:10, Brad Hilton via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div 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>

</div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></div></body></html>