SE-0483: `InlineArray` Literal Syntax

Hello, Swift community!

The review of SE-0483: InlineArray Literal Syntax begins now and runs through May 16, 2025.

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 me as the review manager by email or DM. When contacting the review manager directly, please put "SE-0483" in the subject line.

Trying it out

If you'd like to try this proposal out, you can download a toolchain supporting it for Linux, Windows, or macOS using a recent main development snapshot from Swift.org - Download Swift and enabling the InlineArrayTypeSugar experimental feature.

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,

Holly Borla
Review Manager

10 Likes

Note that while the grammar allows for any expression, this is currently limited to only integer literals.

As @Slava_Pestov reminds us, integer generic parameters are an important, already supported feature which leads to non-literal sizes of InlineArray. Is it the meaning of this proposal that the following is currently not supported as part of this proposal?

func f<let n: Int>(_: [n x Int]) {}
4 Likes

Using the latest nightly snapshot, this works just fine for me:

func something<let n: Int>(_: [n x Int]) {}

func main() {
  let a: [2 x Int] = [0, 0]
  something(a)

  let b: [3 x Int] = [0, 0, 0]
  something(b)
}

main()
7 Likes

This is sugar for whatever can be done with InlineArray, so this is really a question about whether you could write the above with InlineArray. For further example, if at some point InlineArray could use compile-time constant values rather than integer literals, this sugar would gain that too.

4 Likes
  • [5 of Int] is more verbose than x but could be considered more clear. It has the upside or downside, depending on your preference, of being almost, but not quite, grammatical.

of, differently from the proposed syntax and the other alternatives, is the only semantically asymmetrical operator, which can became significant in a future direction where of can be used in value position (e.g. [3 of 5]).

8 Likes

I really strongly dislike making an inconsistent exception for x as what amounts to a type-level operator. I think it sets a bad precedent. I know Swift has a history of making weird exceptions as a language, but personally I would love for it to move away from making further exceptions around syntax. On principle, I hope the powers that be agree with that and opt to go with an alternative syntax. Of the alternatives considered, I would honestly prefer any of them over x.

41 Likes
[ of Int]` is more verbose than `x` but could be considered more clear. It has the upside or downside, depending on your preference, of being almost, but not quite, grammatical.

Fully disagree. of is more clear. Since either x or of would be considered keyword operators in Swift, and keyword operators are English words, it feels more natural and clean that we choose of as our keyword operator.

If this must move forward, I believe strongly that this needs to be course corrected.

On a side note, I am still slightly team 'this should NOT be implemented.' I think that those in the original pitch discussion have made somewhat of a good case for this, and I am hoping that that is taken strongly into considerations.

Regardless, I can see that people do want this and as Swift becomes more capable of programming kernel, lower OS code, I think that syntax like this may be appreciated by those deep in that world.

At the minimum, let's get rid of x and switch to of.

EDIT:

Since x cannot follow another identifier today, [x x Int] is unambiguous,1 but would clearly be hard to read. This is likely a hypothetical concern rather than a practical one. While x is used often in scratch code for a local variable, a more meaningful name is usually preferable, and this would be especially the case if it is found being used for the size of an array literal. In addition, while i, j, or n are often legitimate counters that might be suited to the size of an array, x is generally not used for such things.

Regardless of this being hypothetical or not (which it isn't, people do name their variables all sorts of letters), it is less likely that one would be named of as it would be x.

It would equally be valid to say it is more preferable that we name our English word operators full English words and not ambiguous things like x. I mean, that is actually preferable.

15 Likes

On that point: We actually do have somewhat of a precedent for inventing a slightly different syntax for a type-level operator, the & operator for protocol composition, which is clearly not a bitwise-and operation and was chosen to be close-to-but-not-the-same-as &&.

If there were some consistent twist we put on every "ordinary" operator to make a type-level equivalent, then that would be one thing, but I agree that there's something that doesn't sit well to me about building up (one at a time) to a whole set of just slightly wonky operators, but each wonky in their own way.

9 Likes

I agree with @JuneBash in that I strongly dislike "x".

I think using "by" instead of a single-letter keyword that is trying to look like an operator without actually being one is a much much better idea. "by" has literally just a single extra character compared to "x", yet it's incompatibly more clear, more appropriate and less conflicting with existing symbols. No matter how much the documentation will remind about "x" being a contextual keyword, it will always look like a fake operator.

At the end of the day, I'd even strongly prefer typing out "InlineArray<5, Int>" over "[5 x Int]".

10 Likes

I don’t see how && would have been a better or more consistent syntax than &. Protocol composition isn’t any more a logical AND than it is a bitwise one. Plus, && has a connotation of short-circuiting which does not apply to protocol compositions.

In fact, short-circuiting has historically been the defining characteristic of &&. Many other C-family languages (including C, C++, Java, and C#) allow you to use & as a logical AND that doesn’t short-circuit when both parameters are booleans.

3 Likes

As discussed in the pitch thread, I really wonder if this addition of further syntactic sugar holds its weight, given that InlineArray is a fairly specialised tool (nowhere near as common in use as normal arrays—several orders of magnitude less, I'd expect). While the rationale at the beginning of the proposal contrasts it with a standard array, I'm not sure that's a valid comparison—do we expect multi-dimensional inlined arrays to be so common that it's worth adding additional complexity to the language for this?

I note that "doing nothing" is not even considered under "Alternatives Considered".

Perhaps it will be common and worthwhile to solve, but I think it's worth reflecting on at least—or simply postpone putting in sugar until there's some real-world experience with InlineArray, and later RigidArray, ...)

30 Likes

This part convinced me: "multi-dimensional arrays [...] flattened to [5 x 5 x Int]". Eat that, Python!

1 Like

I don't see how that is the same thing. The problem with x is that it is a letter, that happens to look like a multiplication sign Ă—. Ampersand is an established symbol for "and" in many different situations, both on computers and in the real world.

Using x for Ă— would correspond more to something like using R as a boolean "and" because it looks a bit like &.

11 Likes

To be clear, in no way am I arguing that && would have been better for protocol compositions or denying that there were clear reasons for avoiding it. Nor am I raising the point that I did raise to argue that * would be better here or denying that there are also clear reasons for avoiding it.

And to further clarify, in no way am I arguing that my point is about the same thing or denying that there are other concerns which one may raise about the proposed spelling here. To demonstrate that yours and mine are orthogonal points, Ben could have proposed Ă— here and it would address your point but I would still be raising my point.

2 Likes

Well said! :clap:t2:

1 Like

Another strong vote against x here. It feels way too 'cute' and coincidental, it will look confusing whenever x also exists as a variable, which is extremely problematic given how common x is as a variable name, and it will read poorly (imho) if we allow syntax like [i * j x Int]. It also feels like something that fans of other languages will point at and say, to be polite, 'what on earth were they thinking'.

of has all of the benefits of x while suffering none of the above issues.

10 Likes

The difference here is x is commonly accepted in this context in English, e.g. 4x4 or 2in x 4in. R is not.

7 Likes

So if following that future direction, writing a multi-dimensional InlineArray would have a more compact syntax than a multi-dimensional normal Array then, which also seems a bit curious, given the expected relative frequency of using the respective types of arrays.

I also in general wonder a bit on the combination of the suggested sugar, and the intention that there will be many more types of arrays (1, 2) added in the near(?) future (at least to collections, whether they would graduate to standard lib remains to be seen, the future is shrouded in some mystery...).

6 Likes

As many mentioned, x is a common variable name, hence [x x _ ] and similar expressions might be very confusing.
If it has been already decided that x is the way to go, may be a X could be used instead? Variables rarely begin with capital letters and single letter names are not common for types. If there is a problem with using a capital letter as a keyword, may be :x could be used instead? It is both invalid operator and variable name, keeps the "intuitive" x part, and will cause less confusion.
Otherwise, if we Swift is borrowing ideas from Rust, why not borrow some syntax? ; is a good option. It doesn't cause naming conflicts, is ergonomic and is already used in Rust, which will make it more familiar with other language. As for " [5; Int] is what Rust uses, but appears to have little association with "times" or "many". ", the moment Swift team decides it denotes "times" or "many", it will have lot of association, as [5; Int] will read as "5 times Int" if Swift team decides that ; means "times" in this context.

2 Likes

TBH, after InlineArray gets introduced, there's no reason for them to to be less frequent than regular array, if it they properly introduced and documented.