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

Hello Swift community,

The second review of SE-0453: Vector, a fixed size array begins now and runs through 17 December, 2024. For a summary of the changes from the first review, please see the announcement here.

Additionally, in this second review, feedback for the name Vector will be considered on-topic.

As mentioned in the pitch thread, with these sorts of bikeshedding discussions it is always helpful to articulate more than just a +1 or a -1 for a given name, and to suggest alternatives if you are speaking against the name the authors have proposed. The Language Steering Group is more interested in exploring the reasons that reviewers have for preferring certain names, or certain types of names, than we are the raw number of reviewers speaking for any particular choice.


Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager. When emailing the review manager directly, please keep the proposal link at the top of the message.

Trying it out
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/swiftlang/swift-evolution/blob/main/process.md

Thank you,

Freddy Kellison-Linn
Review Manager

19 Likes

+1, including the name. I do worry about the imbalance in semantics from incoming C++ developer's perspective, but as more of an abstract thing, as I don't do a lot of C++ interop work myself.

I'm very much looking forward to having this in the language as a first-class citizen.

7 Likes

I like it, and I like the name.

However, if we ever are to add binary operators for this type it should be the pairwise operators, or none at all.

Although we probably will move towards making this some kind of collection type, and this type is analogous to the C array, I think we should be careful about how we talk about and describe the type in documentation. Since a Swift Array is entirely different, I think we should not use that word at all.

E.g. the review title "fixed-size array" may not be the best way to cement a common understanding of what the type is, and what it is for. For people coming from a C background, I think it makes perfect sense, but for newer programmers, the word easily confusable with the Swift Array.

I think we should encourage people to think of Vector as a fixed, inline span of values, like a tuple, mathematical vector or array in the C-sense of the word.

7 Likes

As previously, I think the name is going to be confusing and should be reconsidered. +1 to the proposal overall.

5 Likes

I'm very much in favor of the feature, but I really don't like the name.

I fully understand that the name Vector referring to an array has precedent in C++ and one possible interpretation (from a programmer's perspective) of a geometric vector is a list of numbers, however:

  • The decision to use vector in C++ was (as far as I know, please correct me if I'm wrong) made with no consideration of it clashing with the concept of a geometric vector and was later considered a mistake. A single notable instance of the name being used this way is hardly a pattern and especially considering that the difference in semantics between a C++ vector and a Swift array with compile-time know count, I don't see any benefit of following this naming precedent. Because of this, I think it would be even more of a mistake that the C++ decision was.
  • The list of numbers interpretation of a geometric vector specifically applies to numbers representing coordinates. The Swift array with compile-time know count has vastly different semantics and has no direct correlation with a geometric vector, which mean it's in direct conflict. A typeVector<let degree: Int, Scalar: FloatingPoint> that is almost identical to the proposed type spelling (except for the generic constraint on the Scalar generic parameter) is a lot more appropriate for representing a geometric vector.

For these reasons, I think it's a huge mistake to name this type Vector that will be practically impossible to fix once it's in the standard library.

3 Likes

@grynspan and @technogen, do either of you have a preferred alternative that you've seen for similar concepts in other languages, or that came up in the pitch thread?

@Jumhyn: Unfortunately, to my knowledge, only C++ has provided both a dynamic-size and a static-size array simultaneously, so there is very little precedent to go off of.

I have to admit that I haven't been following the discussion threads too closely, so if anyone has ever proposed (or thought of) an alternative name, I'd really like to hear them!

The way I'd propose coming up with a name would be to establish a naming pattern that solves this general problem (which I expect to be exacerbated by the addition of more compile-time features):

How to differentiate two types that are functionally equivalent, except for the fact that one of them works at compile-time for one or more of its major features and the other one entirely works at run-time.

I expect that the proposed type is merely one of many types that will be subject to this naming problem.

We already have such "standard" naming problems with equally standard solutions. Here are the ones that come to mind:

  • Append the word "Protocol" to the name of a protocol to disambiguate it from an associated type that is a better fit for baring the original name.
  • Append the word "Type" to the name of an associated type to disambiguate it from the protocol that is a better fit for baring the original name.
  • Prepend the word "unsafe" to names of declarations that are known to be working around the normal Swift memory safety guarantees.

A naive answer to this question would be to prepend the word "Static" to the name, but that would clash with the existing semantic of the word static (roughly meaning has only one meaningful instance/behavior per process).

I'd love to hear opinions on solving this general naming problem, which would not only answer the question "How to name the proposed type?", but any similar naming problem in the future.

Big +1 to the proposal. I'll reiterate here that Vector is pretty much an ideal name for this type (although I personally would prefer Vec or Vect for a type I expect to be commonly used, similar to how we picked Int instead of Integer).

It is an established precedent in languages with dependent types, and since const generics are a subset of dependent types, it makes perfect sense to follow that precedent. Picking any other name than Vector or Vec/Vect would only introduce needless confusion.

11 Likes

I wish we could swap Array and Vector, but obviously that's not an option.

Both Multiple and Repeat were suggested in that thread: they bring to my mind the right concept of "this is storage for multiple or repeating instances of T" rather than relying on terminology that would, in this context, imply Collection conformance.

I could be roped into bikeshedding those terms further.

5 Likes

On the topic of Vector "clashing" with the concept of mathematical vectors:

I think anyone used to reading mathematical notation would identify this as a vector in informal conversation:

v = (1, 2, 3)

Because of the notation used. Yes, it would be reasonable to argue the above is not a vector until you specify a few other things, like how addition and scalar multiplication work, or which field was used to construct the vector space v belongs to. But that kind of information is often context-dependent, not explicitly written.

The way I see it, the same thing holds true with Vector. The type information would be analogous to the notation used for mathematical vectors. Semantically, when the second generic parameter is an Int, Double or similar (ie Vector<3, Double>), you will always be able to define addition and scalar multiplication operations to define a vector space. Just like with mathematical vectors, you can't modify the length of the vector in any way, as vectors of different lenghts are fundamentally different things (or types).

For plain Vector<N, Double> instances, element-wise addition would be akin to adding two mathematical vectors from a vector space where the basis is orthogonal, which is most often what you want.

At times, one may want to define addition in a way that is not element-wise addition. For example, if your Vector<2, Double> is used to represent a coordinate in polar coordinates. Maybe a developer in this situation would create a light wrapper around Vector<2, Double> named PolarCoord to disambiguate how addition and scalar multiplication is to be performed. Seems to me like Vector is still an ideal building block for this type too.

As for the case when the second generic parameter in Vector is not number-like at all, there's no risk of confusing Vector with its mathematical counterpart. Is Vector<3, URLResponse> intended to be interpreted as an element from a vector space? Well, probably not!

Even in that last case, the name Vector provides some nice intuition as to the fixed-length of the type, drawn from the concept of mathematical vector.

I like the proposal, and I like the name. Looking forward to it!

12 Likes

In principle, I appreciate the name Vector for this type. In isolation it would be a great name.
However, I fear that this will be a source of friction for developers coming from C++ and Rust, because both of these languages made the dubious design decision to swap the names of their types corresponding to Array and the proposed Vector. I know that itā€™s not ideal to base Swiftā€˜s design decisions on dubious decisions in other languages, however as these two languages in particular probably have one of the largest developer overlaps with Swift, they are hard to ignore in this matter.

Unfortunately, I donā€™t have an alternative name suggestion. I still wanted to voice my concern here.

1 Like

Iā€™ve been sitting on an alternative name suggestion for a while: Block.

In various programming contexts, a ā€œblockā€ often refers to a contiguous, fixed-size piece of data or memory. Languages like C and C++ use the term when discussing memory blocks, and in lower-level operations you frequently talk about blocks of memory. The termā€™s widespread usage ensures developers intuitively understand that a Block represents a chunk of data that isnā€™t meant to resize dynamically.

Swift encourages clarity, and ā€œblockā€ is a short, English noun that conveys the essence of what the type represents: a collection of a fixed size. Itā€™s easy to spell, pronounce, and remember. Block feels natural alongside other types from the standard library like Set, Dictionary, and Array, sticking to the ā€œdonā€™t surprise the readerā€ guideline.

In mathematics and computer science, a ā€œblockā€ is often used to denote a fixed partition of a larger structure. Matrices are described in terms of their sub-blocks; filesystems operate on data blocks. The connotation is a well-defined, self-contained unit. For a fixed-length sequence type, this analogy provides a mental model where a Block is a stable, rigid constructā€”like building blocksā€”fitting nicely into larger data structures without changing shape.

Array is dynamic, StaticString hints at immutability, and ContiguousArray emphasizes memory layout. Block would differentiate itself by focusing specifically on the property of fixed size. It does not imply mutability or immutability of the elements themselves, just the invariant length.

When teaching or documenting this type, saying ā€œa Block of four Floatsā€ or ā€œa coordinate is a Block of two Intsā€ sounds natural. It implies a known quantity, something a reader of the code can rely on.

14 Likes

With my review manager hat off for a moment, the potential issue I immediately see with Block is due to Swift positioning as an Objective-C replacement the term 'block' is already somewhat overloaded to mean 'block of code'. I don't think the Swift documentation itself uses that anywhere, but it definitely shows up in the Swift version of Objective-C library docs, and (though less common with each passing year) I definitely see folks with an Objective-C background colloquially refer to Swift closures as 'blocks'.

Don't think this is totally disqualifying but wanted to make sure it was mentioned.

14 Likes

Itā€™s also already in the language as @convention(block) (Foo) -> Bar closure types.

8 Likes

Ah, you're right, good catch.

2 Likes

I'm very happy with the results of the previous review.

The changes to the initializers in particular are well thought out. Consistency across types in the standard library makes learning and using Swift much easier.

Delaying C interop is necessary, as there are still too many unanswered questions that need solutions before we can move away from importing those types as tuples.

As for the name, I can't imagine it being called anything other than Vector. The word "array" should definitely not be in the name of the type, as an array brings expectations of adding/removing items. A fixed capacity array (with a constant capacity but variable length) would certainly be a useful addition to Swift but that's an entirely separate thing from this Vector type, where the count and capacity are always equal (and constant).

I don't see any conflict with mathematical vectors. Vector is well suited to modeling mathematical vectors (either by adding operators to it directly or by wrapping it in types to add operators and other conveniences).

Yes, C++ made some unfortunate (IMHO) choices on naming types. I don't see any need to perpetuate that here, as it's not the only language with which Swift needs to interoperate and Swift has already made bold choices in the past to improve on the status quo.

7 Likes

The RegexBuilder module already has a Repeat type.

2 Likes

I first thought the name Vector was good until I realized that the size needs to be known at compile time and not be just set at initialization.

Iā€˜m still +1 on the proposal, although the use in my projects will be pretty limited due to the constraints of such type (mainly the compile time size) but in my opinion, the name needs to reflect this constraint as well as being prominently mentioned in the docs.

I donā€˜t have a good name myself either, as Swift, like mentioned above, does not have a prefix for "known as compile time". Looking at C++ and not my general displeasure with the Vector, what about ConstVector?

2 Likes

Having once been enmeshed in the game development world, I tend to think of Vector as being part of the family of types that is usually suffixed by either 2, 3, or 4, representing vectors/points/spans in 2/3/4-dimensional space. For that reason I would prefer an alternative. In fact, it may be worth pointing out that CGVector in CoreGraphics reinforces that definition for Vector, and so the name feels a bit 'off'.

What about FixedSizeArray? I know it's a little more verbose, but it is in keeping with the tradition of lower-level types tending to be more verbose (though I know with stuff like Atomic and Mutex we've more recently been moving away from that tendency).

9 Likes