sway icon indicating copy to clipboard operation
sway copied to clipboard

Implements Iterator trait and for loops.

Open esdrubal opened this issue 1 year ago • 2 comments

Description

This implements an Iterator trait in std-lib, and adds iter() to Vec. This also adds parsing and desugaring of for loops.

    for pattern in iterator {
        code_block
    }

is desugared into:

    let mut iterable = iterator;
    let mut value_opt = iterable.next();
    while value_opt.is_some() {
        let value = value_opt.unwrap();
        value_opt = iterable.next();
        code_block
    }

This also adds for loops documentation to the control flow docs.

We still have to fix this issues:

  • #5567
  • #5568
  • #5570
  • #5571

Closes #145

Checklist

  • [x] I have linked to any relevant issues.
  • [x] I have commented my code, particularly in hard-to-understand areas.
  • [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • [x] I have added tests that prove my fix is effective or that my feature works.
  • [x] I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • [x] I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • [x] I have requested a review from the relevant team or maintainers.

esdrubal avatar Feb 06 '24 10:02 esdrubal

LGTM but @esdrubal can you create the issues you mention in the description before we merge this?

IGI-111 avatar Feb 07 '24 14:02 IGI-111

@IGI-111 I created the issues.

esdrubal avatar Feb 07 '24 17:02 esdrubal

Any reason why we materialize next before the code block? It makes sense to avoid the generation of the next item if the user wants to break the loop and it is not going to use it.

    let mut iterable = iterator;
    let mut value_opt = iterable.next();
    while value_opt.is_some() {
        let value = value_opt.unwrap();
        code_block                                     // <- swaped this
        value_opt = iterable.next();            // and this
    }

xunilrj avatar Feb 08 '24 08:02 xunilrj

Any reason why we materialize next before the code block? It makes sense to avoid the generation of the next item if the user wants to break the loop and it is not going to use it.

    let mut iterable = iterator;
    let mut value_opt = iterable.next();
    while value_opt.is_some() {
        let value = value_opt.unwrap();
        code_block                                     // <- swaped this
        value_opt = iterable.next();            // and this
    }

You may have a continue inside the code_block that would skip the next() call if it is at the end as you suggested.

esdrubal avatar Feb 08 '24 08:02 esdrubal

We could fix the issue of calling next prematurely by doing something like:

    let mut iterable = iterator;
    while true {
        let value_opt = iterable.next();
        if value_opt.is_none() {
             break;
        }
        let value = value_opt.unwrap();
        code_block
    }

esdrubal avatar Feb 08 '24 08:02 esdrubal

We could fix the issue of calling next prematurely by doing something like:

    let mut iterable = iterator;
    while true {
        let value_opt = iterable.next();
        if value_opt.is_none() {
             break;
        }
        let value = value_opt.unwrap();
        code_block
    }

That seems much more robust. :+1:

IGI-111 avatar Feb 08 '24 11:02 IGI-111

Updated desugaring code to the better version.

esdrubal avatar Feb 08 '24 13:02 esdrubal