[swift-evolution] Yet another fixed-size array spitball session
Rod Brown
rodney.brown6 at icloud.com
Mon May 29 02:21:20 CDT 2017
While I can’t comment about the technical details, I have to say, this looks really “unswifty” to my eye. I’d probably expect something more along the lines of:
let x: FixedArray<Int> = [1, 2, 3]
or:
let y: StaticArray<Int> = [1, 2, 3]
> On 29 May 2017, at 4:37 pm, Daryle Walker via swift-evolution <swift-evolution at swift.org> wrote:
>
> Static-Sized Arrays
> This is a new proposed syntax for handling array types whose size is fixed at compile time. This is a classic kind of type that's still missing in Swift.
>
> Like the built-in processor numeric types are mapped to special struct types, any built-in vector types should be mapped to special array types. There should be some sort of construct to allow parallel visitation of elements.
>
> For a given array type A with an element type B, we have strideof(A) == COUNT * strideof(B), where COUNT is the number of elements in the array, which is the product of the lengths along each dimension. (A zero-dimension array has an element count of one.)
>
> New Keywords
> array
> of
> These keywords should be conditional if possible. The of shouldn't appear without following an array, so of should be easy to make conditional.
>
> Immediate Arrays
> Immediate arrays are a new kind of compound type. They have value semantics.
>
> let x: array 3 of Int = [1, 2, 3]
> var y: array 2 of array 5 of Double
> Hopefully, this is simpler than my last proposal. I'm thinking that "array" is like a verb here.
>
> The element type is at the end, so no parentheses (or similar) are needed. The syntax is easy to expand for nested array types. Here, the extents go from the widest span to the narrowest, like nested arrays in C. The inner element type is at the end instead of the start.
>
> assert(x.0 == 1)
> x.3 = 3 // ERROR!
> y.1.3 = 3
> y.0 = [-3, -2, -1, 0, +1]
> Elements are addressed just like in tuples.
>
> Nominal Arrays
> Nominal arrays are a new kind of named type. They have value semantics.
>
> array MyArray: (0..<6) of Int {
> /* ... */
> }
> I'm thinking "array" is like an adjective (or noun) here. The base-and-protocol list must have a shape specifier as its first item.
>
> shape-specifier → ( extents-list_opt ) of type
>
> extents-list → extent
>
> extents-list → extent , extents-list
>
> extent → type storage-rank_opt
>
> extent → expression ..< expression storage-rank_opt
>
> extent → expression ... expression storage-rank_opt
>
> storage-rank → : expression
> A type used for an extent:
>
> Must be a raw-value enumeration type.
> The raw-value type must be one of the default integer types.
> There must be at least one case, and all the cases must form a contiguous range of values.
> A range used for an extent:
>
> Must use for its boundary type either:
> a default integer type, or
> an enumeration type that could qualify as an extent type.
> Must be a valid range with at least one element.
> The expression for a storage rank must evaluate to a compile-time integer value that is at least zero and less than the number of extents. An extent without an explicit storage rank gets one equal to the smallest valid value yet unused. (Multiple extents without explicit ranks are finalized in lexical order.)
>
> The extent with the largest storage rank has elements with adjacent indexes (assuming all other extents use fixed indexes) placed adjacent in memory. The extent with storage rank 0 have elements with adjacent indexes (assuming all other extents use fixed indexes) the furthest span apart in memory.
>
> The total number of elements for the array is the product of the lengths of the extents. A zero-dimension array has a singular element.
>
> A nominal array type can have type-level members and computed instance-level properties, just like the other named types. The initial set of members, if not overridden, are:
>
> A type-alias Element that refers to the element type.
> A type-alias Index that refers to a tuple composed of the extent types. For a range-based extent, the corresponding type is its boundary type.
> If the element type is default-initializable, a default initializer.
> An initializer that takes as its only parameter an Element, which is copied to each element.
> An initializer that takes as its only parameter a closure that takes as its only parameter an Index and returns the value the corresponding element starts with.
> An initializer similar to the previous, but the closure takes the index tuple's parameters separately.
> Two subscript members, with get and set modes, to handle dereferencing. One member takes an Index, the other an exploded index list. It's an error to refer to an invalid index location.
> Flexible Array Reference
> To not have to fix a function for each extent shape, something similar to the old T[] array segment idea from C(++) is needed:
>
> func foo(x: array of Int) -> Int
> func bar(y: array of mutating Double) -> Int
> Without a size given inside the array declaration, these functions can work with any array with the given element type. Array-segment references are reference types.
>
> An array-segment reference conforms to RandomAccessCollection. A reference that is marked mutating also conforms to MutableCollection. (Should we create a new mutable keyword instead?)
>
> A function that returns or otherwise writes out an array-segment reference must ensure it points to memory that will survive the function's end. (I'm not sure we should enforce some sort of retain/ARC instead.) (Should we ban these instead?)
>
> An array-segment reference can be generated from an immediate array or a nominal array using as. A reference can be mutatingif the source array starts in var mode. Array-segment references access their elements in storage order.
>
> Conversions
> These conversions can work through as:
>
> array N of T → array of T
> array N of T → array of mutating T, if the source array was in var mode
> array N of T → array M * N of U, when T is an array M of U
> MyArray → array of MyArray.Element
> MyArray → array of mutating MyArray.Element, if the source array was in var mode.
> array of mutating T → array of T
> array of T → array of U, where U is the element type of T
> array of mutating T → array of mutating U, where U is the element type of T
> Any conversion that requires a chain of these is also legal. When a function has an array-segment reference as a parameter, and the argument is an array with the same element type, the argument doesn't need an explicit as.
>
> (Should we allow the reverse-direction transformations, or even chains of them, with "as!" and/or "as?"? Note that this could end up converting an array 5 of Int to an array 3 of array 2 of Int with its last Int nested element invalid.)
>
> Parallel/Vector Processing (only semi-serious)
> As the processor's built-in numeric types are mapped to the default numeric types, we should do something similar for a processor's built-in vector numeric types. Like a processor that has four integers as a vector, we could define a Int_4 structure type that maps to it.
>
> We also need a way to possibly do evaluations in parallel. What about:
>
> do x, y, z as array {
> z = x == y
> x += y
> }
> The three objects between do and as have to have the same shape. Within the block, the object names now refer to corresponding individual elements.
>
> Extra Traits
> As I was writing this, I came up with new functionality and corresponding keywords. Should we have an #extentsof(type)to use an extent shape from one nominal array type to another? Should we have an #extentscount(type)?
>
> Example: take the do as array block. If x and y were function parameters, but z was an internal object, how would we define z besides manually copying the shape list?
>
> —
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170529/e404ef6f/attachment.html>
More information about the swift-evolution
mailing list