[Second review] SE-0453: Vector, a fixed size array

ArrayTuple stands for array-like tuple, a tuple with some array behaviors, so I guess the literal should be parenthesis like a tuple: (1, 2, 3). It probably should have a tuple-style shorthand syntax for the type such as (3 * Int) or (3 Int).

Or we could have TupleArray for tuple-like array and then we'd get brackets: [1, 2, 3].

I'm not saying these are good names, hence the "half-jokingly" qualifier I used. HomogenousTuple or FixedSizeArray, or even InlineArray (despite the conflict with the other projected type), would be less confusing I think.

1 Like

A question not related to the name.

Will it be possible to initialize a Vector from a Swift tuple? Llibraries will have properties or function arguments as tuples for a long time.

// 3d party library code
let elements: (Uint16, Uint16, Uint16, Uint16, Uint16, Uint16, Uint16, Uint16) = ...

// our code
let vector: Vector<8, Uint16> = Vector(elements) // ?

Will it be possible? There is no information about such case in proposal.

It seems that C tuples can be transformed to Vector representation but Swift tuples doesn't.

2 Likes

Of the names proposed thus far, I like Run best. “A run of 16 ints” sounds natural and is unambiguous with existing Swift types. The name is short without being an abbreviation. It does not conflict with existing naming schemes and could serve as the base for a new set of names, if needed.

Vector is fine, but I dislike the conflation with geometric vectors and would like to see that name reserved for libraries dealing with such objects.

I think the name Run also feels like inline storage to me, compared to Slab or Buffer or other names which are not explicitly InlineSomething.

2 Likes

How about "Indexee"? "Vector" would be fine if the language were being newly designed, but there must be a million programs that already have variables or functions called Vector, and even if these programs would still compile, they will become confusing for anyone to work on. I doubt many existing programs contain the word "Indexee".

About naming, I like both Vector and FixedArray.
But also I understand the arguments expressed by John McCall.

So what do you think about Cluster ?

Cluster a number of similar things that occur together

Just an idea

1 Like

I find it odd that, in order to avoid having to explain to C++ developers what Vector means, that we would then pick a random English word like Slab or Bunch -- that we would have to explain to everyone.

I rarely write Array or Dictionary because there's good syntactic sugar for them, and I hope the same will be true for this type.

Let's use plain words to describe exactly what it is. In my subjective ranked order from better to good:

  • FixedCountArray - the .count property is what is fixed
  • FixedSizeArray - this is more pleasant to my ear; the Array header-comments say "size" plenty so it's an ok synonym.
  • Vector - This is fine; I'll get used to it.
6 Likes

For String we have StaticString. Wouldn't this then logically be StaticArray?

It's not a short name but anyone can guess what it is and how it behaves. I also feel like Vector will cause confusion.

Edit: Ah this was discussed already. Then my vote goes to FixedSizeArray.

2 Likes

Static_ defines an entirely different construct in the language as has been previously pointed out.

2 Likes

MonoTuple then?

Been thinking about extending the existing native tuple type with new syntax for homogenous elements but I understand that the ship has sailed already, too late to propose this kind of changes after 189 comments under the second iteration... :person_shrugging:

1 Like

A few people brought up tuples in the original discussion, including myself:

But @scanon enumerated several reasons why this approach was not taken:

I still think the right approach is to resolve these issues instead of introducing a new language construct that models a precise subset of tuple functionality. Even with an ideal name that everyone could agree to, the existence of this new type will forever present the question of which to use in any given situation. The language is conceptually leaner with a single tuple type.

Is it at all feasible to name this type Tuple and commit to the eventual goal of making it the nominal generic supertype of all tuples?

8 Likes

The issue is not about tuples, it is about C interop – we have nothing better than tuple to represent a C array at this time.
So Vector is a suitable construct for C arrays representation.

Swift tuples on their own will be used but for different purposes. I suppose no-one in Swift would create homogenous tuples with large count of elements – large tuples are a burden of importing C api's, because there was nothing better at the time when C interop was implemented.

I agree that it would be cool to have some collection-like operations for tuples, like access by index, iteration and count. Some languages have these features for tuples.
The point is that in this concrete proposal improvements are about C arrays, not Swift tuples. As a bonus we get other Vector capabilities like inline storage and fixed capacity data structure useful on its own.

It is, however, conceptually a more foundational or primitive type, more so than even Array. I mean it in the following sense:

We learn how to create and use values of basic types like Int before we learn how to define even the simplest of data types. After learning about how to work with one value at a time, a very reasonable next step is wanting to work with, say, two or three or four such values.

Currently, the options for expressing this are: tuples, arrays, defining your own data types, and then more esoteric choices. This data type is more primitive than all of these: it is homogeneous where tuples are not (and also a nominal type where tuples are not), fixed in count where arrays are not, and a standard type where your own types are not. Slotted into a textbook, it would be appropriate to present this topic before any of these existing topics—indeed, each of these (tuples, arrays, custom types) offers additional complexity to fulfill some particular need when the thing you're doing outgrows this type in some particular way (for example: you have values of heterogeneous types, or you need dynamic resizing, or you want copy-on-write, or you need to encapsulate business logic alongside your data).

For this reason, I feel very strongly that this type isn't a good candidate for being named as an appendage of some other type, as most two- or three-word names tend to be. Instead, the name should be legible to users who know nothing about the heap or stack, copy-on-write, dynamic sizing, or even what "storage" is: if you know what Int values are, this is merely n of them in order, and that is all there is to it as a threshold matter.

In that sense, it is very different than @convention(c) or InlineArray or pretty much everything else.

16 Likes

Never did I suggest that C interop would avoid this new type. I’m saying the end state of the language is much cleaner if this type eventually becomes the nominal supertype of all tuples, including large homogenous ones imported from C.

Now, I'm not a mathematician, but my impression on doing my reading is that the sense in which @lorentey is using "vector" in this proposal is actually well precedented in math: for instance, the Wikipedia article on "ordered pair" calls out that it is sometimes also called a "2-dimensional vector" even though it is technically an abuse of the term, which reads to me like if there is some "loosy goosy"-ness to it, that originates with mathematicians. So while other uses in computer science put a "spin" on it, we really wouldn't be doing any spinning here.

I definitely agree that a type spelled Vector<2, Int> is going to be tantalizing to someone who wants to use SIMD2<Int> in a way that's problematic when their memory alignment doesn't match. Addressing that issue by naming choice would require us to "salt" the name of Vector sufficiently that no one likes it who should look for SIMD2 first. That's sad.

Were feasibility not in question, I would much rather have us look into whether, for all n and T where SIMDn<T> is supported, Vector<n, T> could and should be made "magically" to have the same memory layout including alignment.


To my mind, that originates from a different "original sin" that has nothing to do with this type, which is only drawing it out.

Rather, we've always said that our fixed-width integer types model both the integers and the sequence of bits by which they are encoded. Here, this comes homes to roost because Vector<MAX_PATH, CChar> is being used for its "sequence-of-bits"-ness rather than its integer-ness. But we committed to this choice long ago; it would not be an issue if it'd been decided that bytes aren't to be represented by UInt8 when it was decided (correctly) that Bool shouldn't be an integer type.

8 Likes

Sure, as a final goal it is great.
As a future direction some compiler magic can be added to make possible all Vector operations with homogenous tuples. In such a way it seems to be realistic.

This seems to be the most common way this type has been described in English in this thread, so why not use this as the name? HomogenousTuple is pretty explicit about the layout (if you are familiar with tuples, modulo padding of the last element) and doesn’t have the mathematical or other-programming-language baggage of Vector.

(BTW, I don’t see the Vector/Array swap causing anything other than momentary confusion for C++ developers - it’s pretty clear from having an int value parameter on the type which is a fixed length!)

3 Likes

One problem with HomogenousTuple is that the canonical spelling should be HomogeneousTuple—"homogenous" is a biological term that has historically also been a misspelling for "homogeneous" but has occurred frequently enough that it's now considered by some to be an accepted alternative. But if that means the name would be hard to spell correctly, it's not a great choice for a name.

Other than that, the type being described here isn't really a tuple. Tuples provide compile-time-index access via .0, etc., whereas this type supports dynamic subscripting with [...]. Literals of tuple types are initialized using (...), but this type is initialized using literals written with [...]. Calling it <Adjective>Tuple feels misleading and confusing given these differences.

5 Likes

In principle, Swift could support .<expression>, i.e. t.i or t.(i + 1). I'm not a big fan of this myself but in principle indexed access to a fixed-size array could be visually different from that of the variable-sized one.

Same, nothing terribly wrong in saying anything [...] is variable-sized whereas (...) is fixed sized.

Interesting (and useful) point but if we have somehow managed Colour vs Color or .gray vs. .grey (autocompletion help us all) I don't see a big problem with it. Besides, my suggestion was a more succinct MonoTuple.

2 Likes

For the Tuple/_Tuple name, imagine us explaining in the future:

This is a [homogenous] Tuple because it has a contiguous, inlined memory layout. These are collections of data that can be iterated over, randomly accessed, has a count, and are extendable.

However, that differs from ()-defined tuples, because those aren't necessarily homogenous and have entirely different syntax construction and operations like element-index-like dot syntax access, individual element labels, and allows same-structural usage.

The word "tuple" ambiguously means two different language constructs.


If this were some kind of super type of "tuples", I'm curious how that implementation would look alongside existing tuples. I believe we're way past being able to redefine tuples in this manner, imo.

This is a brave argument, which I wholeheartedly support.

Let's, please, abandon all proposed names, including Vector, and embrace the true thing, which is Tuple.

// 3 by 3 identity vector
let u: Tuple <3,Tuple <3,Int>> = [1, 0, 0, 0, 1, 0, 0, 0, 1]

// Sugars
let u: [3 x [3 x Int]] = ...
let u: [3, [3, Int]]   = ...
let u: [3  [3  Int]]   = ...