It's unfortunate that the history of other languages forces this, but I just don't think we can call this type Vector when in other languages, Array and Vector are precisely the opposite of what they will be in Swift.
This doesn't mean those other languages were right – they definitely made the wrong choice of naming their growable array vector. But Swift exists in the context of what came before, I'm afraid.
Calling this type Vector seems like it will inevitably lead to a kind of "Who's on first" dialog with developers coming to Swift from e.g. C++:
"You shouldn't use Array here. Array is a dyanically growable type like a C++ vector, it'll incur reference counting and bounds checking even though you know the size at compile time."
-- OK. So what should I use
"A Vector"
-- I thought you said not to use one of those.
"No, a Swift Vector. It's like an array in C++."
-- But you said don't use an array!
"No, you want a C++ array. In Swift that's a Vector. Not Array, which is like a vector."
Now I get that this is frustrating, but it is what it is. This would be more of a shame if Vector in the mathematical sense was intuitively what these things are. But they aren't – they're just kinda similar, and can be used to represent vectors. Using this mathematical term of art for something that's not really the same as the vector you learned about in high school (assuming you even did) isn't helpful.
Finally – there is a lot of Swift code out there that already defines a vector, and is not necessarily going to change (for example, I have plenty of code that just does typealias SIMD3<Double> = Vec). So stomping on the name with this new probably-not-what-you-actually-want type is a little rude.
My recommendation is to name this something more descriptive, like FixedArray (we need as ever to avoid the temptation to cram more clarifying words in there). My hope is that this type launches with syntactic sugar, in which case a slightly more verbose name isn't going to be a problem in practice.
I don't entirely disagree, but the ship for "avoid confusing C++ devs" sailed over a decade ago¹ when we called the growable thing Array. That's already the state of affairs.
¹ realistically, it sailed a long time before that when someone picked the name NSArray.
"It's already bad, so it's fine to make it worse for no particularly good reason" isn't super compelling to me :)
An alternative to my dialog that I'd prefer:
"You shouldn't use Array here. Array is a dyanically growable type like a C++ vector , it'll incur reference counting and bounds checking even though you know the size at compile time."
-- OK. So what should I use
"In Swift what you want is called FixedArray"
-- Ah, OK
Please dont call this type FixedArray, it means nothing. What about it is "fixed"?
Is Array broken? Should you never use Array?
Are the values fixed? Is this like NSMutableArray and NSArray?
Is the capacity fixed? Can it grow within count?
etc...
Vector extremely succinctly describes the type's properties.
Additionally typing FixedArray is materially more annoying than Vector.
^ IMO suggesting sugar over just using the type's name implies the type is going to be extremely common (I disagree) or that the name is too long to write.
Reiterating, in a real world adoption, I found no need for syntactic sugar. Type inference works great and removes the need, e.g. this just works:
let data: Vector = [1, 2, 3] // Vector<3, Int>
And again, every time we add sugar to the language we make macro author's lives measurably more difficult and likely force breaking changes in swift-syntax across the ecosystem. (if sugar is truly worth it, then fine, but the bar should be very high)
wrt naming: To me, the key design features for the name to elicit, in order of importance, are:
It's a value type
It has N initialized values of the same element type.
N is constant
Its Copyable status tracks the element type.
It supports subscripting
The Int count type parameter conveys 2 and 3 well enough. 4 and 5 are somewhat implicit features, expected of any indexable sequence of ~Copyable, so surfacing them as name parts might be noise for later types in this family.
So perhaps just Values<N, T> or Elements<N, T>?
wrt semantics, I still don't understand e.g., consuming a subset of ~Copyable element (via subscript) while preserving the notion of always-initialized values, but that was raised in the first review. And I'd want a get+set API to swap an element at one position out for a new element, getting the old in return, to preserve the always-initialized property.
Since the growable type in Swift is named Array already, I don't think "Array and Vector have swapped meanings in Swift vs C++" is any harder to explain than "Array is like a C++ vector, and FixedArray is like a C++ array".
In fact, I'd argue that the latter is more confusing to explain to someone coming from C++. An analogous conversation could be:
— You shouldn't use array here. Array is a dyanically growable type like a C++ vector, it'll incur reference counting and bounds checking even though you know the size at compile time.
— OK. So what should I use?
— A fixed array.
— I thought you said not to use an array!
— No, you shouldn't use an array. A fixed array, on the other hand, is like a C++ array.
— Isn't fixed array an array?
— Well, on Swift both are arrays, but you want a C++ array, which is fixed array specifically, not array, which is like a vector.
— [surprised pikachu face]
Of course, it helps a lot to add formatting so "Array" and "array" look like different things. But that's really hard to do on spoken conversations (or, more generally, when someone is being lazy with formatting).
Actually, a general concern I have with FixedArray as a name (which I also raised during the pitch) is that it clashes with any statements of the form "arrays in Swift do X and Y..." because now you have to second-guess whether that statement applies to only the type Array or any other "array" (like FixedArray). This could be more palatable if the only difference between Array and Vector was the fixed length, but there's the inline aspect of it as well. Seems to me that Array is fundamentally different enough from Vector that these statements are going to create a lot of confusion.
FWIW, if anything, I think having the names swapped could help discoverability for those coming from C++: upon learning that Array is a growable collection type in Swift, it's natural to then go on and search whether "Vector" exists and what it means in Swift, as that's the type C++ programmers would reach for when in need of a growable collection.
Coming up with a "unique" and "succinct" yet a non-descriptive and misleading name and justifying it with reasons like "others did it", "it's recognizable", "it's shorter", or worse yet: "it's not a description" is (to me, based on any practice of high-quality API design I've ever seen) is the worst reason to pick a name.
I could summarize this idea in a sentence:
If it doesn't look like a duck, quack like a duck, swim like a duck and fly like a duck, then don't call it a duck!
Take a look at the open(2) syscall on Darwin (or any other POSIX-like OS). Its name is "succinct", looks like it should be convenient to use, and (unlike the name Vector in context of the proposed type) almost feels like it describes what the function does.
In reality, it is way too terse, fails to convey a large set of important information about its numerous edge cases (like the fact that it can also create files, delete files, set permissions to files and configure the IO preferences on the created file descriptor). The name itself does absolutely nothing to help understand what the function does or how to use it. It's merely a semi-arbitrary lookup key into the system manual pages.
In case of this particular function, its behavior is so complex that a description name would have to be truly gigantic (something silly like openOrCreateMaybeDeletingFileWithOpeningAndIOConfiguration), which is not a naming problem, but a complexity problem. No function should be this cumbersome with this many edge cases and this much complexity crammed into a tiny API. The solution to this problem would be (obviously not considering the fact that it's way too late to change) to break it apart into smaller and lower-level APIs (it's not like POSIX is trying to provide a high-level API in the first place).
The Swift standard library cannot afford to do what most app code bases unfortunately opt to do: save effort on rigorous naming practices in favor of coming up with a quick and fun name and justifying that with an esoteric reason.
I like the Rust syntax sugar but I would prefer a comma [4, Int]. Swift does not use semicolons so Rust syntax stands out, and I find it very noisy even for Rust standards.
Please though, anything but Vector, if later on someone wanted to implement an actual Vector<N, T> type, like a vector in a game engine which can be multiplied with matrices, the names would collide.
On the naming debate, I'll say that the API that has annoyed me the most in my time using Swift is SwiftUI's Section type.
Not because I use SwiftUI's Section type much myself, but because "section" is such a broad term that I already had large existing codebases which made extensive use of my ownSection types. I spent a long time on them, carefully designing a really nice API which did everything a great Swift API is supposed to do - it was concise, yet clear at the point of use.
All of that went out the window once SwiftUI introduced its own type named "Section". SwiftUI is used so extensively that there was truly nowhere that didn't break, requiring lots of ugly disambiguations. It was kind of heartbreaking to see what the changes did to the code I had designed so carefully
In my opinion, the SwiftUI authors overstepped with that one. It's fair enough for a UI library to define its own Color type, but a term like Section is too broad for a UI library to claim; and in the language we have today, with its features and limitations, that has a significant negative effect on downstream clients.
In the context of this proposal, we should also consider very carefully whether the term Vector is too broad for this language's standard library to claim.
We (already) have special rules for the standard library so that end user code doesn’t need disambiguation in such circumstances.
As detailed in this proposal, whatever the type is named it will not require users to rename their own types, and furthermore there exist (approximately) no such types in anyone’s code which take an integer as the argument for the first generic parameter.
I'm pretty sympathetic to "it's not a vector" arguments (it isn't!), but I really do not think that this type should be XxxArray. It simply isn't an array. Its API and usage patterns are not like the API and usage patterns of Array,¹ other than representing a contiguous sequence with a zero-based integer subscript. Any argument about "Vector" being misleading or confusing applies more strongly to names that are variants of "Array"--"Vector" may be confusing to C++ programmers, but "Array" is confusing to Swift programmers.
If this were to be a Fixed anything, it would be a FixedSpan, not a FixedArray--Span at least shares some of the not-an-array characteristics of this type. That name isn't great for other reasons (it would be ideal to keep XxxSpan focused on non-escapable transient views of data structures), but it's still less confusing than any variant of Array.
¹ You can append and insert and remove elements from an Array. You can initialize an Array and then add other elements to it later. An Array has "free" copies and copy-on-write, which gives its API wildly different performance characteristics than this type has. This type is almost nothing like an Array, and confusing people with a name that suggests they're part of a family of similar data types is a mistake.
I'll give one very serious naming suggestion, and a few others.
The serious one:
Slab
This has previous usage in computer science (slab allocation, slab fill, etc), but not so widely that it is compromised by those existing uses. It connotes, to me, a fixed chunk of something. It's terse, and would seem to be a good kin to Span.
In the real world, slabs, whether concrete or granite, are hard and durable and can't easily be modified. Slabs have extent. Slabs are durable. Slabs are contiguous. Slabs are homogeneous.
In the world of buildings, both Slabs and Spans are fundamental structural components that are used to build other things.
A few other ideas, some already mentioned:
StableVector
StableArray
FixedVector
FixedArray
And one that is firmly tongue-in-cheek given how long this bike shedding has been going on:
Mess (as in: this routine takes a Mess of UInt64s)
As a former C++ programmer, I prefer Vector to any of the alternatives. It's widely recognised that C++ reverses the meanings of vector (fixed-length sequence) and array (variable-length sequence), so it's good for Swift to correct this mistake.
I've also found it easy to translate between different name usages: C++ map is Swift Dictionary, C++ (misnamed) vector is Swift Array - so I don't think I'd have any problems with C++ (misnamed) array is Swift Vector.
It seems to me more on the nose (other than the memory layout discrepancy) to regard this type as a homogeneous tuple.
[Amusingly, I googled to see what some other languages that describe a homogeneous tuple call this type, and the first result was some Haskell library that said something to the effect of “homogeneous tuples (also known as vectors).”]
That collides with RawSpan and the UnsafeRawPointer family — those types don’t have typed storage, and they can in theory hold a heterogeneous collection of values. If anything, I‘d expect there to be a future RawVector<count> type (replacing Vector with whatever name this ends up having) to represent the storage underlying such a value. (Although on the other hand, that type could be easily defined as Vector<count, UInt8>
I'm very curious about this line of argument and I would like to find out more before I give a ±1 on this.
Personally my biggest need is for a fixed capacity array and/or RingBuffer for no allocation purposes. This will be essential for things like Audio DSP and graphics work, where we often need to process e.g. exactly 1024 Floats in a fixed-size non-allocating, non-copying buffer. Swift makes this difficult as is.
If Vector is not the solution to the above problem space, and the actual solution is also not able to be implemented in terms of the proposed type, then I would be strongly against providing such a tempting-sounding type much of a platform. For example, it should sound much less accessible than it currently does.
Above all though, I am wondering what is so different about the proposed type from a hypothetical FixedCapacityArray? The current pitch's title ("a fixed size array") sounds identical enough to that type for me to consider it paraphrasing.