-
Notifications
You must be signed in to change notification settings - Fork 226
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
Allow array resizing #374
Comments
Semi-related: A full staging system would allow us to better separate an arbitrary compile-time only language that expands out into a separate runtime language. We currently have quite an ad-hoc version of this with little separation, the compiler will attempt to manually inline recursive functions/loops until an upper limit is reached for example. With a fully separate compile-time language we could support arbitrary data types and control flow so long as it can be proven to terminate. Best inspiration here (avoiding dependently-typed languages) I believe is terra: https://terralang.org/ in which the distinction between language (terra) and metalanguage (lua) is clear yet ergonomic. |
For dynamic size containers, we can introduce a vector like Rust does. Though we should plan around the implications of dynamically sized arrays, like inserting in an if statement. |
I also think we should use vectors for resizable arrays and keep array size fixed.
|
Using a hardcoded array size does not resolve this usecase since it only works for an input array of one size rather than any size. I was thinking these growable arrays / vectors would still have a size known at compile-time and we'd track it as it grew. For example, we may take in an array |
Also worth noting that by allowing this new method to construct arrays we could remove the return value of a for-loop expression. Currently it is unimplemented but meant to fill the use-case of mapping an array to return a new one. With array push/pop we could implement a |
I was just chatting with Kev about #516, and he reckons vectors could also be used to address that one too. However, I think it's worth flagging that if you introduce an explicit vector type that is distinct from arrays, library developers are going have to implement the same functionality twice in order to support both types. (That's unless we have some abstraction for iterables which can be either dynamically or statically sized.) |
Indeed. I think we also have the opportunity in noir to keep having only 1 array type and still allow it to be pushed/popped from. Here's an example of such an API: // This impl looks a bit odd, may have to be builtin since there is no type name for arrays
impl<T, N> [T; N] {
#[builtin(arraypushfront)
fn push_front(self, elem: T) -> [T; N+1] {}
#[builtin(arraypushback)
fn push_back(self, elem: T) -> [T; N+1] {}
// constraint: N >= 1
#[builtin(arraypopfront)
fn pop_front(self, elem: T) -> [T; N-1] {}
#[builtin(arraypopback)
fn pop_back(self, elem: T) -> [T; N-1] {}
#[builtin(arrayinsert)
fn insert(self, index: u64, elem: T) -> [T; N+1] {}
fn map<U>(self, f: fn(T) -> U) -> [U; N] {
let mut result = [];
for e in self {
result.push_back(f(e));
}
result
}
} There is actually no real need for Iterators in general in noir since we can just use arrays. They should be removed entirely at compile-time so there is no runtime-cost argument which is the standard reason to use iterators over containers directly. The other Iterator argument of implementing |
@vezenovm what is the status of this issue? |
We now have slices where syntax originally listed in the issue and the example API is now supported. Here is an example of a resized slice and the API in the stdlib. However, merging of slices is still missing as well as dynamic indexing of slices, so we have partial but not full support yet so the issue should remain open. |
I'm reopening this issue until #2599 is solved as it is critical for matching up slices w/ array functionality. |
#2599 has been solved, so I'm closing this issue. There are still remaining issues with slices but I think the original part of this issue of having some way for arrays to be resized is complete. |
We should allow users to dynamically resize arrays by pushing/popping/inserting elements so that they can build arbitrary arrays more easily. Without this it is more difficult to create new arrays based on input arrays but with different sizes. For example, we cannot* write a function currently that takes in a
array: [T]
and returns a new array containing every other element from the original.let mut ret = [default_value; len(array) / 2];
and fill in the elements from there, but this is not possible either currently.Suggestions: arrays should instead be vectors, or a table/tree structure where we could push/pop/insert elements as needed:
The text was updated successfully, but these errors were encountered: