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

Dynamic loop magically working #5011

Open
aajj999 opened this issue May 10, 2024 · 4 comments
Open

Dynamic loop magically working #5011

aajj999 opened this issue May 10, 2024 · 4 comments
Labels
documentation Improvements or additions to documentation

Comments

@aajj999
Copy link

aajj999 commented May 10, 2024

Aim

Understand why the code below works:

fn main() {
    let mut bounded_vec: BoundedVec<u8, 10> = BoundedVec::new();
    bounded_vec.extend_from_array([1, 2, 3, 4, 5]);

    let mut counter: u8 = 0;
    for i in 0..bounded_vec.len {
        counter += 1;
        println(f"i: {i}");
    }
    println(f"Counter: {counter}");
}

It has a loop that uses the length of BoundedVec. Not its maximum length, but its actual length.
When I execute it, its prints show that it actually looped 5 times.
I want ot understand why it works, when and how it is safe to use this.

Expected Behavior

I understand that dynamic loops generally don't work.

Bug

It's rather an unexpected behaviour that I want to understand.

To Reproduce

  1. Execute code given in Aim

Project Impact

Nice-to-have

Impact Context

I want ot understand this behaviour so I would know when and how it is safe to use it.

Workaround

Yes

Workaround Description

No response

Additional Context

No response

Installation Method

Binary (noirup default)

Nargo Version

nargo version = 0.28.0 noirc version = 0.28.0+7dfa151da95c7ca9e1aaa752347b62f9fafe2c2c

NoirJS Version

No response

Would you like to submit a PR for this Issue?

None

Support Needs

No response

@aajj999 aajj999 added the bug Something isn't working label May 10, 2024
@TomAFrench
Copy link
Member

Hi @aajj999, the reason that the for-loop works is that it's not actually dynamic, i.e. we can determine what its value will be at compile time.

fn main() {
    let mut bounded_vec: BoundedVec<u8, 10> = BoundedVec::new(); // bounded_vec.len = 0
    bounded_vec.extend_from_array([1, 2, 3, 4, 5]); // bounded_vec.len = 5

    let mut counter: u8 = 0;
    for i in 0..bounded_vec.len { // Can replace bounded_vec.len with 5.
        counter += 1;
        println(f"i: {i}");
    }
    println(f"Counter: {counter}");
}

An example where the for loop is dynamic would be in situations where its length depends on program arguments.

fn main(x: bool) {
    let mut bounded_vec: BoundedVec<u8, 10> = BoundedVec::new(); // bounded_vec.len = 0
    bounded_vec.extend_from_array([1, 2, 3, 4, 5]); // bounded_vec.len = 5
    
    if x {
        bounded_vec.extend_from_array([1, 2, 3, 4, 5]); // bounded_vec.len = 10
    }
    
    // We now don't know the value of bounded_vec.len at this point as it can either be 5 or 10 depending on program argument `x`

    let mut counter: u8 = 0;
    for i in 0..bounded_vec.len { // Cannot determine for loop range
        counter += 1;
        println(f"i: {i}");
    }
    println(f"Counter: {counter}");
}

@aajj999
Copy link
Author

aajj999 commented May 10, 2024

Thank you for the explanation. Do you think there is maybe a place in Noir documentation to include this? I think it may be unclear also for other users.

@TomAFrench TomAFrench added documentation Improvements or additions to documentation and removed bug Something isn't working labels May 10, 2024
@TomAFrench
Copy link
Member

Yep, docs improvements are always welcome!

@jfecher
Copy link
Contributor

jfecher commented May 10, 2024

It's also worth mentioning that this depends on compiler optimizations so the precise line in the sand where things are known or unknown at compile-time may change. For example, when mutable references are involved in control flow the analysis can be a bit more hazy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
Status: 📋 Backlog
Development

No branches or pull requests

3 participants