The proposal includes a swapAt function that updates an element and returns the old one. This method does not exist on Array and instead we have a global swap function to do it. Is this best thought of as a "swap" operation? I hate to be bringing up new naming concerns, but since it doesn't exchange the contents of two objects, I was wondering if there are alternatives considered. replace(at:with:)? There has to be more.
Less actionable now, but I think the ExpressibleByVectorLiteral section doesn't go far enough. I think that ExpressibleByVectorLiteral should replace ExpressibleByArrayLiteral because array literals, by definition, always have a fixed size.
I didn't see it mentioned explicitly, but can you confirm whether global/static data will then also be represented as constant data in the binary if the values themselves are literals and that no other initialization cost would occur when accessing it?
A major problem Swift has today is that something like static let myArray: [UInt8] = [...] has unpredictable codegen; depending on whether you're compiling with optimization or not, and depending on the size of the array, it might get outlined to constant data or it might generate a sequence of instructions to initialize a backing array at runtime. This makes it extremely difficult to write algorithms that use tabular data while guaranteeing good performance. While it would be nice if Array addressed this, if Vector does then it at least gives us another path to explore.
It shouldnât depend on the size of the array, because the optimization is most profitable for large arrays. If you find a reproducer please file a bug. It might even make sense to promote it to a mandatory optimization since I donât think it impacts debug info, but that depends on how expensive the transformation is. But again if it doesnât scale well thatâs something that ought to be addressed eventually. The same optimization should apply to fixed size arrays too, I canât imagine a situation where we cannot make this guarantee, assuming the element type is known.
Long time observer just chiming in but I actually like the name Vector and I think it makes sense for this type given what it is. My educational background in CS started with languages that called the âgrowableâ container an Array and then moved to languages like C that called the fixed size one array and I always found that confusing.
That said Iâll note some interesting tidbits: the Wikipedia page for array mentions (in passing)
In some cases the term "vector" is used in computing to refer to an array, although tuples rather than vectors are the more mathematically correct equivalent.
Even given that Iâd still rather it be called Vector (especially since we already have something called Array and that ship has sailed) and prefer that over something like FixedSizeArray (which to me implies some kind of sub-typing is going on).
Another thing I wanted to throw out there is that we can make the transition from tuples to Vector easier by allowing types to respond to numeric fields, @dynamicMemberLookup-style. If you could write vector.1 and that was the same as vector[1], most code bases would be instantly compatible with the change.
Filed #76953 (similar to this post from a few years ago, which unfortunately got little traffic). Even a trivial 10-element global array codegens move instructions without -O.
At a minimum, I hope that simple static arrays of numeric constants could be done this way without it being expensive; my own use cases aren't embedded programming but it feels like this would be a major need there to embed data without incurring major codegen/runtime costs.
Would there be a way to use a runtime integer to initialize this fixed-size array? IIRC, generic int parameters need to be initialized with a compile-time constant. If not, what would be a good way to replace withUnsafeTemporaryAllocation with a safer construct?
In this model an ordinary value of type Int is an existential so you could imagine passing an Int value as an integer parameter type by âopeningâ it, just like we do with any P; it would have the same limitations and guarantees.
This is not an inherent requirement, since integer parameters are not required to be specialized any more than other generic parameters are. We should eventually be able to use a constant integer value as a local generic parameter, analogously to how existential values can be opened to use their dynamic type as a generic type parameter.
Yes, a Vector will always have the layout of Count elements with Element.stride * Count.
This type is just a regular value type like Int and Double. You can explicitly copy it (if it's copyable) and that will be an immediate eager copy and mutations will occur on whatever owned copy you have.
All types in Swift have metadata, so by extension this type will come with new metadata.
We technically already have this problem with tuples however. Tuples cannot have uninitialized elements, yet we import potentially uninitialized C arrays into fully initialized tuples in Swift. This pitch isn't making any current behavior better or worse with regards to imported C array initialization.
This type does not have the ABI layout as tuples as tuples omit padding on the last element while this type preserves such padding.
Thereâs certainly the elementwise implementation of this conformance, but given Vector is sort of like an array, wouldnât you expect [1, 2] + [3, 4] == [1, 2, 3, 4] as Vector to be true?
If we do this, I feel like there should be a way for conforming types to be allowed to constrain their initializer to a fixed set of count(s). For example, [1, 2, 3] as SIMD2<Int> should be a compile-time, not runtime, error.
I don't have a specific issue with the name Vector but I am curious what a future Fixed Capacity Array might be named, and similarly what names we might give other fixed collections, like {Stack|Queue|RingBuffer}<let Capacity: Int, Element> etc...
To add to the madness, what if we allowed for type overloading by generic parameter name? I don't necessarily think this is a great idea but maybe it's a direction thinking about. Array<Capacity:> != Array<Count:> != Array
This is great! Would you consider providing a way to create a Vector parallel to the Array(unsafeUnitializedCapacity:initializingWith:) initializer? Sometimes it's useful to initialize out of order, as long as you can still guarantee the total number of elements.
Since it wouldn't have an integer parameter, it might need to be a static method:
While I fully support the long overdue and much-needed proposal, I can't help but chime in on the least important aspect, the name.
In mathematical usage, a 'vector' is just a thing with certain algebraic properties (namely, addition and scalar multiplication). It has nothing to do with being a fixed-length list of elements.
Naming this new type a vector wouldn't right any past wrongs, but only add to the confusion.
Strong +1 for the pitch. It is sorely needed for Embedded Swift.
As for naming, I think FixedSizeArray makes as much sense for this type, as DynamicSizeUnicodeCharactersCollection does for a string type, i.e. not at all.
Since const generics are a special case of dependent types, in dependent types Vector is a well-established term of art. For Swift not to follow that would be disappointing.
In fact, only alternative I would consider is Vec, in the same way we've chosen Int instead of Integer. I realize for collections and sequences we're not consistent and are sticking to verbose spelling, like String instead of Str and Dictionary instead of Dict. Thus Vector it is.
As for naming, Vector doesn't worry me much since different languages ââalready have different names for dynamically sized arrays. In C# it's List, C++ it's std::vector and Swift it's Array. So for a fixed size array, Vector is no more confusing than this already existing confusion ;)
However, during the first debate about fixed-size arrays in Swift in 2022, the name FixedArray was proposed and I really liked it.