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

feat(corelib): Iterator::peekable #7097

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

hudem1
Copy link
Contributor

@hudem1 hudem1 commented Jan 15, 2025

I suggest the addition of Iterator::peekable to be able to use peek() on iterators.

Example

let xs = array![1, 2, 3];

let mut iter = xs.into_iter().peekable();

// peek() lets us see one step into the future
assert_eq!(iter.peek(), Option::Some(1));
assert_eq!(iter.next(), Option::Some(1));
assert_eq!(iter.next(), Option::Some(2));

// The iterator does not advance even if we `peek` multiple times
assert_eq!(iter.peek(), Option::Some(3));
assert_eq!(iter.peek(), Option::Some(3));
assert_eq!(iter.next(), Option::Some(3));

// After the iterator is finished, so is `peek()`
assert_eq!(iter.peek(), Option::None);
assert_eq!(iter.next(), Option::None);

I set my PR as a draft because i have 1 issue and 1 question, possibly related:

  1. When I run my test, it says Error: Compilation failed without any diagnostics.. It does not display the reason of the compilation error and the test file doesn't show any particular error from the LS. I do get an LS error in the iterator.cairo file saying Trait has no implementation in context: core::iter::traits::iterator::Iterator::<T>., which does not make much sense to me as T obviously implements Iterator as we are in the Iterator<T> trait.

  2. I am unsure about how to use the custom trait for the peek method. I exported it in the adapters.cairo and iter.cairo files to be able to import it in my test file, but I am not sure it is the correct way to use it.

@reviewable-StarkWare
Copy link

This change is Reviewable

@hudem1 hudem1 marked this pull request as draft January 15, 2025 21:18
Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

it is required to be added to the prelude in that case, but lets postpone that.

Reviewed 5 of 5 files at r1, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @hudem1)


a discussion (no related file):
@gilbens-starkware for 2nd eye.


corelib/src/test/iter_test.cairo line 44 at r1 (raw file):

    let xs = array![1, 2, 3];

    let mut iter = xs.into_iter().peekable();

Suggestion:

fn test_iter_adapter_peekable() {
    let mut iter = (1..4).into_iter().peekable();

Copy link
Contributor

@gilbens-starkware gilbens-starkware left a comment

Choose a reason for hiding this comment

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

Reviewed 2 of 5 files at r1, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @hudem1)


corelib/src/iter/traits/iterator.cairo line 305 at r1 (raw file):

    #[must_use]
    fn peekable(self: T) -> Peekable<T, Self::Item> {
        peekable_iterator(self)

We should find the impl we in, but meanwhile, maybe this will work:

Suggestion:

peekable_iterator::<T, Self>(self)

Copy link
Contributor Author

@hudem1 hudem1 left a comment

Choose a reason for hiding this comment

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

Ok.

Reviewable status: 2 of 5 files reviewed, 2 unresolved discussions (waiting on @gilbens-starkware and @orizi)


corelib/src/iter/traits/iterator.cairo line 305 at r1 (raw file):

Previously, gilbens-starkware (Gil Ben-Shachar) wrote…

We should find the impl we in, but meanwhile, maybe this will work:

Thank you for the suggestion. I tried but it doesn't work, it says Unknown impl over the Self, and running the test still gives the same error Error: Compilation failed without any diagnostics..


corelib/src/test/iter_test.cairo line 44 at r1 (raw file):

    let xs = array![1, 2, 3];

    let mut iter = xs.into_iter().peekable();

Done.

Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

Reviewed all commit messages.
Reviewable status: 2 of 5 files reviewed, 3 unresolved discussions (waiting on @gilbens-starkware and @hudem1)


corelib/src/iter/adapters/peekable.cairo line 17 at r2 (raw file):

pub fn peekable_iterator<I, impl IterI: Iterator<I>>(iter: I) -> Peekable<I, IterI::Item> {
    Peekable { iter, peeked: Option::None }

remove this - it would remove the requirement in the trait - that you don't actually need.

Suggestion:

pub fn peekable_iterator<I>(iter: I) -> Peekable<I, IterI::Item> {
    Peekable { iter, peeked: Option::None }

corelib/src/iter/adapters/peekable.cairo line 21 at r2 (raw file):

impl PeekableIterator<
    I, impl IterI: Iterator<I>, +Drop<I>, +Drop<IterI::Item>,

Suggestion:

    I, impl IterI: Iterator<I>, +Destruct<I>, +Destruct<IterI::Item>,

Copy link
Contributor Author

@hudem1 hudem1 left a comment

Choose a reason for hiding this comment

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

Reviewable status: 2 of 5 files reviewed, 3 unresolved discussions (waiting on @gilbens-starkware and @orizi)


corelib/src/iter/adapters/peekable.cairo line 17 at r2 (raw file):

Previously, orizi wrote…

remove this - it would remove the requirement in the trait - that you don't actually need.

Oh yeah as we are sure that if we reach this function, the parameter iter will be an iterator, and we don't need to use actual iterator methods in this function, good idea! As expected, it now works! :)


corelib/src/iter/adapters/peekable.cairo line 21 at r2 (raw file):

impl PeekableIterator<
    I, impl IterI: Iterator<I>, +Drop<I>, +Drop<IterI::Item>,

I tried, but then i get the error that the variable from self.peeked.take() is not dropped.
Please find attached a screenshot for more details.
error.png

Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

Reviewed 2 of 3 files at r2, 1 of 1 files at r3, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @gilbens-starkware and @hudem1)


corelib/src/iter/adapters/peekable.cairo line 21 at r2 (raw file):

Previously, hudem1 wrote…

I tried, but then i get the error that the variable from self.peeked.take() is not dropped.
Please find attached a screenshot for more details.
error.png

applied changes to the code itself to make it work.
(the causing issue is the fact that we don't lookup negative impls, but just the lack of positive impls, should be solved soon enough, but this will suffice for the time being)


corelib/src/iter/adapters/peekable.cairo line 32 at r3 (raw file):

        }
    }
}

Suggestion:

impl PeekableIterator<
    I, impl IterI: Iterator<I>, +Destruct<I>, +Destruct<IterI::Item>,
> of Iterator<Peekable<I, IterI::Item>> {
    type Item = IterI::Item;

    fn next(ref self: Peekable<I, IterI::Item>) -> Option<Self::Item> {
        let next_value = match self.peeked {
            Option::Some(v) => v,
            Option::None => self.iter.next(),
        };
        self.peeked = Option::None;
        next_value
    }
}

@hudem1 hudem1 force-pushed the feat/iter_adapter_peekable branch from dd50ae8 to eb3cf8a Compare January 18, 2025 11:32
Copy link
Contributor Author

@hudem1 hudem1 left a comment

Choose a reason for hiding this comment

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

Reviewable status: 3 of 5 files reviewed, 2 unresolved discussions (waiting on @gilbens-starkware and @orizi)


corelib/src/iter/adapters/peekable.cairo line 21 at r2 (raw file):

Previously, orizi wrote…

applied changes to the code itself to make it work.
(the causing issue is the fact that we don't lookup negative impls, but just the lack of positive impls, should be solved soon enough, but this will suffice for the time being)

Done. And for my understanding, why do we want to use +Destruct instead of +Drop here ?


corelib/src/iter/adapters/peekable.cairo line 32 at r3 (raw file):

        }
    }
}

Done.

@hudem1 hudem1 marked this pull request as ready for review January 18, 2025 11:35
Copy link
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

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

Reviewed 1 of 2 files at r4.
Reviewable status: 4 of 5 files reviewed, 1 unresolved discussion (waiting on @gilbens-starkware)


corelib/src/iter/adapters/peekable.cairo line 21 at r2 (raw file):

Previously, hudem1 wrote…

Done. And for my understanding, why do we want to use +Destruct instead of +Drop here ?

It just supports more cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants