[swift-evolution] Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type)

Brad Hilton brad.hilton.nw at gmail.com
Mon Apr 4 15:10:16 CDT 2016


The Completing Generics Manifesto suggests a more universal solution with generic value parameters which is my vote:
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”.

> To better support interfacing with lower level systems, like graphics
> libraries for example, it would be helpful to support the concept of
> contiguous variables. The most common use case for this would be to create
> a Matrix struct that can be passed as data into something like Metal. This
> can be accomplished now, using something like the following:
> 
> Current Option 1:
> 
> struct Matrix2x2 {
> var m00: Float
> var m01: Float
> var m10: Float
> var m11: Float
> }
> 
> OR
> Current Option 2:
> 
> struct Matrix2x2 {
> var m: (Float, Float, Float, Float)
> }
> 
> OR
> Current Option 3:
> 
> struct Matrix2x2 {
> var m: [Float]
> }
> 
> Options 1&2 allow for the compiler to enforce the fixed number of
> elements and also for the data to be easily passed into graphics libraries
> as their memory layout is somewhat predictable using sizeof, strideof, and
> alignof. The downside is that you lose the ability to easily subscript or
> iterate the elements.
> 
> Option 3 does allow subscripting and iteration, but does not at compile
> time enforce a fixed number of elements and is not as easily passed into a
> library that expects to receive the raw data of the matrix.
> 
> 
> Contiguous Variables:
> 
> struct Matrix2x2 {
> var m: Float:2*2
> }
> 
> The variable `m` represents a series of 4 contiguous Float values. The
> specific number of values must be a compile time constant. The only needed
> functionality includes `count`, `subscript`, and iteration. To make things
> easier to implement and to help avoid confusion and more complex
> documentation, multiple dimensions are not allowed. To define multiple
> dimensions you must provide your own ordering by wrapping this type in
> another type and providing a custom subscript implementation. For example:
> 
> struct RowMajorMatrix2x2 {
> var m: Float:2*2
> 
> static let rows = 2
> static let columns = 2
> 
> subscript(row: Int, column: Int) ->Float {
> return m[column * Matrix2x2.rows + row]
> }
> }
> 
> sizeof(Matrix2x2) is 16
> strideof(Matrix2x2) is 16
> 
> m.count is essentially a compile time constant and is not stored with the
> rest of the data but is available and can also be used to do runtime bounds
> checking.
> 
> struct Vector3 {
> var v: Float:3
> }
> 
> sizeof(Vector3) is 12
> strideof(Vector3) is 12
> 
> C code should also now be able to expose data types that contain fixed
> sized arrays within them.
> 
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160404/25d4fbd0/attachment.html>


More information about the swift-evolution mailing list