Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arrays #1928

Closed
wants to merge 3 commits into from
Closed

Arrays #1928

wants to merge 3 commits into from

Conversation

foxtran
Copy link

@foxtran foxtran commented Aug 5, 2022

This proposal adds arrays to Carbon programming language.
It presents several definitions of arrays, their internal representation and indexing (by integer value and array of integers).

I did not look on initialization since current initialization is fine for me and I do not see the reason for changing it.

@foxtran foxtran marked this pull request as ready for review August 5, 2022 18:58
@foxtran foxtran requested a review from a team August 6, 2022 17:35
@foxtran foxtran added the proposal A proposal label Aug 6, 2022
var array_2D: i32[4, 10];
var array_nested: i32[4][10];
```
This definition requires contextual information since `i32[4]` is the same as
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relatedly, if types are treated as values (I don't know if that's something Carbon is aiming for), then in generic contexts <expr>[1] can mean dramatically different things.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That is the problem for this definition. But this is most lovely definition for me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relatedly, if types are treated as values (I don't know if that's something Carbon is aiming for), then in generic contexts <expr>[1] can mean dramatically different things.

Yes, Carbon is definitely aiming for that, so this is a major drawback.

```cpp
struct {
int32_t dimensions;
int32_t * dimension_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this data live? Is it static? Is it mutable (i.e., can I change the shape of my array?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In implementation, it can be mutable but compiler should not provide possibility to change shapes nowadays. Later, it should be possible via standard library of Carbon. But it should be impossible to change number of dimensions.

I could definitely see some applications having 2gb character strings and this size being insufficient.

Looks like here uintptr_t should be.

of arrays contains additional metadata:
```cpp
struct {
int32_t dimensions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. I could definitely see some applications having 2gb character strings and this size being insufficient. A uintptr_t would work by definition.

But I'm also hesitant to have this in optimized builds. I don't know what the cost is, but it's certainly not free. Should this be only in debug and hardening modes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dimensions variable contains only number of dimensions. For example, 1 for 1D array and 2 for 2D array. It is the size of the following array. Anyway, you raised the problem and it is actual for the following dimension_size variable.

BTW, what is the problem with optimized builds? Does it different from void func(void * data, int32_t data_len);? Anyway, you should pass the length of your array (strings usually contains "\0", so we know where is the end).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the principle I'm relying on here is that, for optimized builds, we should make programmer errors undefined behavior so that the compiler is free to optimize assuming they do not exist. Certainly I see the value in catching these bugs in debug and hardened modes, but if I cannot remove debug information in optimized builds, we have left room for a lower level, more efficient language, failing at a core principle of the language.

For arrays whose length is known at compile-time, it is a programmer error to access the array out of bounds and so, for optimized builds, should be undefined behavior. Thus, for such arrays, there is no need to store the dimensions at all.

struct {
int32_t dimensions;
int32_t * dimension_size;
void * data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the ownership model for this data?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data will be destroyed at the end of scope (or when calling destructors of base scope, like classes). Later, via standard library, it would be possible to destroy object earlier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really a pointer to the data or is the data stored in-line after the header information, eg T * n, where n is the product of all the dimension_sizes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a pointer to the data. For example, in C++, to allocate some memory for array, then in Carbon code, to build header over array.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect the most common uses for arrays in C++ today are to avoid the allocation intrinsic to std::vector. I think Carbon will want to have a guaranteed non-allocating array type.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Carbon will want to have a guaranteed non-allocating array type.

No doubt, but I interpret this proposal as saying "the non-allocating array type gets some other type syntax" rather than "the non-allocating array type doesn't exist", although the proposal should probably be explicit about that.

That said, I think the non-allocating type should get this syntax, because I think we only have syntactic "room" for one built-in array type syntax, and all the other array types will need to be spelled like library types (e.g. StaticArray(T, N)). That being the case, I think it would be surprising and confusing if the array type that "looks built in" were not the lowest-level type.

(I think there will actually be two lowest-level array types -- the other one is what I referred to here as RuntimeSizedArray. That one is much weirder and more awkward to use than either std::array or std::vector, so it definitely doesn't get to be the one with a built-in syntax.)

Copy link
Contributor

@asoffer asoffer Aug 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only have syntactic "room" for one built-in array type syntax

I don't think this has to be true at all, but I don't mind at all if we go that way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only have syntactic "room" for one built-in array type syntax

I don't think this has to be true at all, but I don't mind at all if we go that way.

Well, I'll put it this way: I think we should presume this is the only built-in array syntax, unless this PR also proposes a syntax for statically-sized arrays, so we assess how the language looks with both of them.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unless this PR also proposes a syntax for statically-sized arrays

I hope syntax for statically-sized and runtime-sized arrays will be close. Probably, the simplest change is to replace numbers with colon.

Indexes are also possible on left-side expression:
```carbon
var array: [6; i32] = (5, 4, 3, 2, 1, 0);
array[(0,1,2)] = array[(3,4,5)]; // array = (2, 1, 0, 2, 1, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the types of the left and right and side?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left side is [3; i32] and right --- [3; i32].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen that syntax before, does that syntax exist in a different language?
It feels a bit unclear to me, and seems to force users to manually indicate individual indexes. Supporting ranges of indexes (for example like Python does slice[begin:end]) would be super valuable for sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I write array[(0,2,4)] = array[(1,3,5)]?
If so, I don't think the left-hand side can be an array. It would need to store references to each particular element that can be assigned to.

But to be honest, I'm not sure this passes the readability test for me (maybe it's just lack of familiarity?) It doesn't seem too bad to me to write
(array[0], array[2], array[4]) = (array[1], array[3], array[5]), or just three assignments.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen that syntax before, does that syntax exist in a different language?

It exists in Fortran; see section 6.2.2.3.2 Vector subscript in Draft of Fortran 2003 Standard.

Supporting ranges of indexes <...> would be super valuable for sure.

See #1927. Slices will generate arrays then they may be used as indexes, so array[begin:end] will be possible with two these proposals.

Can I write array[(0,2,4)] = array[(1,3,5)]?

Yes, you can. I checked what Fortran compiler do: it is just a simplification of cycles. The main idea why array should be indexes via arrays is slice usage.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @asoffer regarding the readability of array[(0,2,4)] = array[(1,3,5)]. To me it looks like we build arrays from tuples, or similar. I don't think we should allow (or at least promote) this kind of syntax. (array[0], array[2], array[4]) = (array[1], array[3], array[5]) looks fine to me as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would array[(0,1)] = array[(1,0)]; do? Is that a swap, or does one of the elementwise assignments happen first? If it's a swap, then in general (with runtime indexes on both sides) would we form an intermediate array with the selected elements?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Pixep, I understand that (array[0], array[2], array[4]) = (array[1], array[3], array[5]) is more readable then array[(0,2,4)] = array[(1,3,5)]. My point of such construction that later slices may generate arrays, so no changes in arrays will be needed because syntax already supports arrays as indexes. Better example is arrays[0:4:2] = array[1:5:2] but currently it does not work.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zygoloid,

What would array[(0,1)] = array[(1,0)]; do?

It is a good point! It would be better to be a swap. At least, it is that what humans expect.

would we form an intermediate array with the selected elements?

It would be better to avoid it; but probably compiler can do small them for using vectorized instructions.

proposals/p1928.md Outdated Show resolved Hide resolved
```

Only of size is defined in compile-time and it is less than
`MAX_STACK_SIZE_ARRAY`, array is located in stack memory. Other definitions are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might go against predictible performance, or be a gotcha. std::array for instance are predictible in that regard, and I believe we would want a similar predictible behavior.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might go against predictible performance

I understand it. This definition can be easily be checked in compile time for showing warnings regarding to lower performance. Here, the point is that all int array[n] inside of function will work via alloca. std::array does not allow such construction since it required to have compile-time defined size of array.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. This proposal says that the array is stored on the stack only if the size is fixed at compile time, so alloca would never be needed.

Indexes are also possible on left-side expression:
```carbon
var array: [6; i32] = (5, 4, 3, 2, 1, 0);
array[(0,1,2)] = array[(3,4,5)]; // array = (2, 1, 0, 2, 1, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen that syntax before, does that syntax exist in a different language?
It feels a bit unclear to me, and seems to force users to manually indicate individual indexes. Supporting ranges of indexes (for example like Python does slice[begin:end]) would be super valuable for sure.


This presented representation is closer to `std::vector<T>` rather then `T[]`.
Then, interoperability between C/C++ and Carbon is limited. So, alternatively,
we may use C/C++ style arrays.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main difference seems to be how you recommend memory allocation, it otherwise has similarities with std::array.

```
as
```fortran
rhosum(1:npoints) = rho(1:2*npoints:2) + rho(2:2*npoints:2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[start:end] would be great indeed, was it your intent?

@github-actions github-actions bot added the proposal rfc Proposal with request-for-comment sent out label Aug 8, 2022
For simplifying usage and raising safety of array usage, internal representation
of arrays contains additional metadata:
```cpp
struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying that the Carbon implementation has to use a struct with exactly this layout, or are you just illustrating what kind of information a Carbon array will carry at run-time?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just illustrating what kind of information a Carbon array will carry at run-time. I'm not sure that is best representation, especially when interacting with C++ is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, then maybe it could be something like this instead:

struct {
  std::vector<int32_t> dimension_sizes;
  std::unique_ptr<T[]> data;
}

That seems more self-documenting, at least for a C++ programmer. For example, you don't need to explain that dimension_sizes is an array, because the type tells you that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to:

template <typename T, int32_t N>
struct Array {
  std::array<int32_t, N> dimension_sizes;
  std::unique_ptr<T[]> data;
};

Number of dimensions for arrays shouldn't be changed.

of arrays contains additional metadata:
```cpp
struct {
int32_t dimensions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This proposal seems to be focused on the 1-D case, which means dimensions isn't needed yet, and dimension_size can just be an integer size instead of an array.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but it would be better to keep in mind that multidimensional arrays will be necessary in future.

In the case of nested array, definition of them a bit misunderstood due to
following indexing is inversed.

Suggested in [#1787](https://github.com/carbon-language/carbon-lang/pull/1787):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this and the other alternatives belong in the "Alternatives considered" section. This section should focus on what you're actually proposing.

Comment on lines 97 to 98
In this alternative, `auto` will work only for types, not for dimensions of
array.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, it makes the binding pattern syntax much more complicated and hard to explain. Right now a binding pattern always consists of the name being declared, a :, and then the type of that name, but with this syntax the type is split across both sides of the :.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dropped this alternative and added Go-like alternative

var array_2D: i32[4, 10];
var array_nested: i32[4][10];
```
This definition requires contextual information since `i32[4]` is the same as
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relatedly, if types are treated as values (I don't know if that's something Carbon is aiming for), then in generic contexts <expr>[1] can mean dramatically different things.

Yes, Carbon is definitely aiming for that, so this is a major drawback.

Comment on lines 105 to 106
This definition requires contextual information since `i32[4]` is the same as
`array_1D[1]` so it is necessary to separate type and variable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why i32[4] would be the same as array_1D[1], under this approach.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it might be possible to make that work, depending on how we specify x[y] (eg, impl forall [N:! BigInt] Type as IndexableWith(IntLiteral(N)) where .Result == Type ...), but it definitely seems like it'd be surprising in some cases and would probably significantly limit the semantics we can provide, such as variable-length arrays. (We might not want VLAs, but being unable to have them because of a syntactic choice would be concerning.)

Comment on lines 161 to 163
This presented representation is closer to `std::vector<T>` rather then `T[]`.
Then, interoperability between C/C++ and Carbon is limited. So, alternatively,
we may use C/C++ style arrays.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "alternatives considered" section needs to explain why the listed alternatives were not chosen. It might help to take a look at previous successful proposals to get an idea of what that should look like.

proposals/p1928.md Outdated Show resolved Hide resolved
struct {
int32_t dimensions;
int32_t * dimension_size;
void * data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really a pointer to the data or is the data stored in-line after the header information, eg T * n, where n is the product of all the dimension_sizes?

Comment on lines 105 to 106
This definition requires contextual information since `i32[4]` is the same as
`array_1D[1]` so it is necessary to separate type and variable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it might be possible to make that work, depending on how we specify x[y] (eg, impl forall [N:! BigInt] Type as IndexableWith(IntLiteral(N)) where .Result == Type ...), but it definitely seems like it'd be surprising in some cases and would probably significantly limit the semantics we can provide, such as variable-length arrays. (We might not want VLAs, but being unable to have them because of a syntactic choice would be concerning.)

Indexes are also possible on left-side expression:
```carbon
var array: [6; i32] = (5, 4, 3, 2, 1, 0);
array[(0,1,2)] = array[(3,4,5)]; // array = (2, 1, 0, 2, 1, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would array[(0,1)] = array[(1,0)]; do? Is that a swap, or does one of the elementwise assignments happen first? If it's a swap, then in general (with runtime indexes on both sides) would we form an intermediate array with the selected elements?

```
It requires the same sizes on the left and right sides.

## Rationale
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be useful to say something about C++ compatibility and interop here, especially since the representation chosen isn't the same as in C++. Is it OK that Carbon's array representation would be different?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK that Carbon's array representation would be different?

I think that it is OK. The point of usage void * data is for simply interoping between C++ and Carbon.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does that work with ownership? Could you copy a c++ array into carbon and then destroy it? What would happen there?

rhosum(1:npoints) = rho(1:2*npoints:2) + rho(2:2*npoints:2)
```

## Alternatives considered
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I think it's worth considering is that when working with an array with a known type, unless it's got a runtime bound, we don't need to store the bound at runtime because we have it as part of the type. To that end, I think we should consider an approach where an array is a contiguous collection that doesn't store its bounds, and have a distinct type (a "span" or "array view" or similar) that represents an indirect reference to an array or subarray and does store its bounds at runtime.

struct {
int32_t dimensions;
int32_t * dimension_size;
void * data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Carbon will want to have a guaranteed non-allocating array type.

No doubt, but I interpret this proposal as saying "the non-allocating array type gets some other type syntax" rather than "the non-allocating array type doesn't exist", although the proposal should probably be explicit about that.

That said, I think the non-allocating type should get this syntax, because I think we only have syntactic "room" for one built-in array type syntax, and all the other array types will need to be spelled like library types (e.g. StaticArray(T, N)). That being the case, I think it would be surprising and confusing if the array type that "looks built in" were not the lowest-level type.

(I think there will actually be two lowest-level array types -- the other one is what I referred to here as RuntimeSizedArray. That one is much weirder and more awkward to use than either std::array or std::vector, so it definitely doesn't get to be the one with a built-in syntax.)


One-dimensional and nested arrays have `dimensions = 1`.

### Declaration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In accordance with the principle that all APIs are library APIs, [Type; Size] will need to be an alias for some library class type, e.g. Array(Type, Size). It would be good for this proposal to specify the name of that type.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took names from #1061

@jonmeow jonmeow mentioned this pull request Aug 12, 2022
Comment on lines +58 to +61
template <typename T, int32_t N> struct Array {
std::array<int32_t, N> dimension_sizes;
std::unique_ptr<T[]> data;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
template <typename T, int32_t N> struct Array {
std::array<int32_t, N> dimension_sizes;
std::unique_ptr<T[]> data;
};
template <typename T, int32_t Dimensions> struct Array {
std::array<int32_t, Dimensions> dimension_sizes;
std::unique_ptr<T[]> data;
};

Otherwise people might mistakenly think that the second parameter is the number of elements in the array.

property of `dimension_sizes` contains information about number of dimensions.
`data` is continuous in memory place keeping scalar data.

This representation is closer to `std::array<T>` rather then `T[]`. Then,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This representation is closer to `std::array<T>` rather then `T[]`. Then,
This representation is closer to `std::vector<T>` rather then `T[]`. Then,

std::array<T> has the same representation as T[]. This type isn't exactly like std::vector either, but it seems closer.

```

Only of size is defined in compile-time and it is less than
`MAX_STACK_SIZE_ARRAY`, array is located in stack memory. Other definitions are
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. This proposal says that the array is stored on the stack only if the size is fixed at compile time, so alloca would never be needed.

`MAX_STACK_SIZE_ARRAY`, array is located in stack memory. Other definitions are
located in heap memory. It is especially important for the last example.

### Library API

For arrays that size is defined in compile-time, `StaticArray(T, shape)` is.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For arrays that size is defined in compile-time, `StaticArray(T, shape)` is.
`StaticArray(T, shape)` is for arrays whose size is defined at compile-time.

(Grammar fix)

### Library API

For arrays that size is defined in compile-time, `StaticArray(T, shape)` is.
`shape` contains information for `dimension_sizes`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What information, exactly? More than just the number of dimensions?

`MAX_STACK_SIZE_ARRAY`, array is located in stack memory. Other definitions are
located in heap memory. It is especially important for the last example.

### Library API
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you intend the [T; N] syntax to be an alias for one of these types? If so, which one?

Comment on lines 100 to 102
Only if size is defined in compile-time and it is less than
`MAX_STACK_SIZE_ARRAY`, array is located in stack memory. Other definitions are
located in heap memory. It is especially important for the last example.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the array storage is on the stack, does this type still use the representation shown above, with a pointer to storage outside the object, or does it use a representation like std::array, where the storage is located within the object itself?

Comment on lines +153 to +154
This representation is closer to `std::array<T>` rather then `T[]`. As extension
of `std::array<T>`, it allows to have sizes not defined in compile-time. Then,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted above, this type seems closer to std::vector than std::array.

that know enough information itself.
- [Software and language evolution](/docs/project/goals.md#software-and-language-evolution).

## Alternatives considered
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important to explain the reason for not choosing these alternatives, in enough detail that future readers can understand what issues we considered, and why we made the decision we did. In a lot of ways that's going to be the most important part of this proposal. I recommend looking at some of the other documents in proposals/ to get an idea of what that should look like.

@benstigsen
Copy link

If the syntax is going to be var array: [6; i32], how would I create a multi-dimensional array?
var array: [4; [6; i32]] ?

@github-actions
Copy link

github-actions bot commented Feb 6, 2023

We triage inactive PRs and issues in order to make it easier to find active work. If this PR should remain active, please comment or remove the inactive label.
This PR is labeled inactive because the last activity was over 90 days ago. This PR will be closed and archived after 14 additional days without activity.

@github-actions github-actions bot added the inactive Issues and PRs which have been inactive for at least 90 days. label Feb 6, 2023
@github-actions
Copy link

We triage inactive PRs and issues in order to make it easier to find active work. If this PR should remain active or becomes active again, please reopen it. \n\n\n This PR was closed and archived because there has been no new activity in the 14 days since the inactive label was added.

@github-actions github-actions bot closed this Feb 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
inactive Issues and PRs which have been inactive for at least 90 days. proposal rfc Proposal with request-for-comment sent out proposal A proposal
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants