<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: <a href="http://codereview.stackexchange.com/q/124797/54297" class="">http://codereview.stackexchange.com/q/124797/54297</a> <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=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c8ace5" class="">let</span> v = Vector<<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">__</span><<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>>,<span style="font-variant-ligatures: no-common-ligatures; color: #49a2d2" class="">Int</span>>(<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=""> <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=""> <span style="font-variant-ligatures: no-common-ligatures; color: #c8ace5" class="">let</span> w = Vector<<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>>(<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=""> <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=""> <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=""> <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=""> x </span>// 0, 0, 5</div><div style="margin: 0px; font-size: 12px; line-height: normal; font-family: 'Source Code Pro';" class=""> }</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 <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> 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<T, let Dimensions: Int> { // specify the number of dimensions to the array
subscript (indices: Int...) -> 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>
> To better support interfacing with lower level systems, like graphics<br class="">> libraries for example, it would be helpful to support the concept of<br class="">> contiguous variables. The most common use case for this would be to create<br class="">> a Matrix struct that can be passed as data into something like Metal. This<br class="">> can be accomplished now, using something like the following:<br class="">> <br class="">> Current Option 1:<br class="">> <br class="">> struct Matrix2x2 {<br class="">> var m00: Float<br class="">> var m01: Float<br class="">> var m10: Float<br class="">> var m11: Float<br class="">> }<br class="">> <br class="">> OR<br class="">> Current Option 2:<br class="">> <br class="">> struct Matrix2x2 {<br class="">> var m: (Float, Float, Float, Float)<br class="">> }<br class="">> <br class="">> OR<br class="">> Current Option 3:<br class="">> <br class="">> struct Matrix2x2 {<br class="">> var m: [Float]<br class="">> }<br class="">> <br class="">> Options 1&2 allow for the compiler to enforce the fixed number of<br class="">> elements and also for the data to be easily passed into graphics libraries<br class="">> as their memory layout is somewhat predictable using sizeof, strideof, and<br class="">> alignof. The downside is that you lose the ability to easily subscript or<br class="">> iterate the elements.<br class="">> <br class="">> Option 3 does allow subscripting and iteration, but does not at compile<br class="">> time enforce a fixed number of elements and is not as easily passed into a<br class="">> library that expects to receive the raw data of the matrix.<br class="">> <br class="">> <br class="">> Contiguous Variables:<br class="">> <br class="">> struct Matrix2x2 {<br class="">> var m: Float:2*2<br class="">> }<br class="">> <br class="">> The variable `m` represents a series of 4 contiguous Float values. The<br class="">> specific number of values must be a compile time constant. The only needed<br class="">> functionality includes `count`, `subscript`, and iteration. To make things<br class="">> easier to implement and to help avoid confusion and more complex<br class="">> documentation, multiple dimensions are not allowed. To define multiple<br class="">> dimensions you must provide your own ordering by wrapping this type in<br class="">> another type and providing a custom subscript implementation. For example:<br class="">> <br class="">> struct RowMajorMatrix2x2 {<br class="">> var m: Float:2*2<br class="">> <br class="">> static let rows = 2<br class="">> static let columns = 2<br class="">> <br class="">> subscript(row: Int, column: Int) ->Float {<br class="">> return m[column * Matrix2x2.rows + row]<br class="">> }<br class="">> }<br class="">> <br class="">> sizeof(Matrix2x2) is 16<br class="">> strideof(Matrix2x2) is 16<br class="">> <br class="">> m.count is essentially a compile time constant and is not stored with the<br class="">> rest of the data but is available and can also be used to do runtime bounds<br class="">> checking.<br class="">> <br class="">> struct Vector3 {<br class="">> var v: Float:3<br class="">> }<br class="">> <br class="">> sizeof(Vector3) is 12<br class="">> strideof(Vector3) is 12<br class="">> <br class="">> C code should also now be able to expose data types that contain fixed<br class="">> sized arrays within them.<br class="">> <br class="">> <br class="">><span class="Apple-converted-space"> </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>