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): FromIteratorTrait #7018

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

Conversation

julio4
Copy link
Contributor

@julio4 julio4 commented Jan 7, 2025

  • Define new trait FromIteratorTrait in iter::traits::collect alongside IntoIterTrait.
  • Add FromIteratorTrait to prelude
  • Implement ArrayFromIterator and SpanFromIterator

Issue

I tried to add collect function to iterator trait but it seems that there's some issue with default trait implementation or that I didn't managed to do trait bounds correctly. I tried this:

fn collect<C, impl FromIterImpl: FromIterator<C, Self::Item>>(
    self: T,
) -> C {
    FromIterImpl::from_iter(self)
}
// error: Identifier not found.
//        FromIterImpl::from_iter(self)
//        ^^^^^^^^^^^^
fn collect<C, +FromIterator<C, Self::Item>>(
    self: T,
) -> C {
    FromIterator::<C, Self::Item>::from_iter(self)
}
// error: Type not found.
//        FromIterator::<C, Self::Item>::from_iter(self)
//                       ^

Documentation

Conversion from an [Iterator].

By implementing FromIterator for a type, you define how it will be
created from an iterator. This is common for types which describe a
collection of some kind.

If you want to create a collection from the contents of an iterator, the
[Iterator::collect()] method is preferred. However, when you need to
specify the container type, [FromIterator::from_iter()] can be more
readable than using a turbofish (e.g. ::<Array<_>>()). See the
[Iterator::collect()] documentation for more examples of its use.

See also: [IntoIterator].

Examples

Basic usage:

let iter = (0..5_u32).into_iter();

let v = FromIterator::from_iter(iter);

assert_eq!(v, array![0, 1, 2, 3, 4]);

Implementing FromIterator for your type:

// A sample collection, that's just a wrapper over Array<T>
#[derive(Drop, Debug)]
struct MyCollection {
    arr: Array<u32>,
}

// Let's give it some methods so we can create one and add things
// to it.
#[generate_trait]
impl MyCollectionImpl of MyCollectionTrait {
    fn new() -> MyCollection {
        MyCollection { arr: ArrayTrait::new() }
    }

    fn add(ref self: MyCollection, elem: u32) {
        self.arr.append(elem);
    }
}

// and we'll implement FromIterator
impl MyCollectionFromIterator of FromIterator<MyCollection, u32> {
    fn from_iter<I, +Iterator<I>[Item: u32], +Drop<I>>(iter: I) -> MyCollection {
        let mut c = MyCollectionTrait::new();
        for i in iter {
            c.add(i);
        };
        c
    }
}

// Now we can make a new iterator...
let iter = (0..5_u32).into_iter();

// ... and make a MyCollection out of it
let c = FromIterator::<MyCollection>::from_iter(iter);

assert_eq!(c.arr, array![0, 1, 2, 3, 4]);

@reviewable-StarkWare
Copy link

This change is Reviewable

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 6 of 8 files at r1.
Reviewable status: 6 of 8 files reviewed, 2 unresolved discussions (waiting on @julio4)


corelib/src/prelude/v2023_01.cairo line 6 at r1 (raw file):

};
pub use crate::ops::Deref;
pub use crate::iter::{FromIterator, IntoIterator, Iterator};

pub has no real effect here - don't add for a reduced change.

Suggestion:

use crate::iter::{FromIterator, IntoIterator, Iterator};

corelib/src/array.cairo line 862 at r1 (raw file):

        ArrayFromIterator::from_iter(iter).span()
    }
}

should we have this one?
this should probably wait for a consuming Span (which will require sierra changes)

Code quote:

impl SpanFromIterator<T, +Drop<T>> of crate::iter::FromIterator<Span<T>, T> {
    fn from_iter<I, +Iterator<I>[Item: T], +Drop<I>>(iter: I) -> Span<T> {
        ArrayFromIterator::from_iter(iter).span()
    }
}

Copy link
Contributor Author

@julio4 julio4 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: 6 of 8 files reviewed, 2 unresolved discussions (waiting on @orizi)


corelib/src/array.cairo line 862 at r1 (raw file):

Previously, orizi wrote…

should we have this one?
this should probably wait for a consuming Span (which will require sierra changes)

I'm not sure I understand what you mean by waiting for a consuming Span.
Regarding SpanFromIterator, it was mostly for syntactic sugar of let _: Span = (ArrayFromIterator::from_iter(iter)).span()


corelib/src/prelude/v2023_01.cairo line 6 at r1 (raw file):

Previously, orizi wrote…

pub has no real effect here - don't add for a reduced change.

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 1 of 3 files at r2.
Reviewable status: 4 of 8 files reviewed, 3 unresolved discussions (waiting on @julio4)


corelib/src/array.cairo line 862 at r1 (raw file):

Previously, julio4 (Julio) wrote…

I'm not sure I understand what you mean by waiting for a consuming Span.
Regarding SpanFromIterator, it was mostly for syntactic sugar of let _: Span = (ArrayFromIterator::from_iter(iter)).span()

yeah - i have some understandable issue with this specifically.

there was and old issue with trying to have a Span version that is the owner of the values within it, and not the holder of just snapshots of the values.


corelib/src/prelude/v2024_07.cairo line 20 at r2 (raw file):

};
pub use crate::{assert, bool, felt252, starknet, usize};
use crate::iter::{FromIterator, IntoIterator, Iterator};

don't change the pub configuration as a part of this PR in non of the preludes please.

Code quote:

use crate::iter::{FromIterator, IntoIterator, Iterator};

corelib/src/prelude/v2023_10.cairo line 30 at r2 (raw file):

    RangeCheck, SegmentArena, assert, bool, felt252, keccak, math, starknet, to_byte_array, usize,
};
use crate::iter::{FromIterator, IntoIterator, Iterator};

.

@julio4 julio4 force-pushed the feat/from_iter_trait branch from 1485da9 to f1dc066 Compare January 9, 2025 12:30
Copy link
Contributor Author

@julio4 julio4 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 8 files reviewed, 3 unresolved discussions (waiting on @orizi)


corelib/src/array.cairo line 862 at r1 (raw file):

Previously, orizi wrote…

yeah - i have some understandable issue with this specifically.

there was and old issue with trying to have a Span version that is the owner of the values within it, and not the holder of just snapshots of the values.

I see, I'll remove it then!


corelib/src/prelude/v2023_10.cairo line 30 at r2 (raw file):

Previously, orizi wrote…

.

Done.


corelib/src/prelude/v2024_07.cairo line 20 at r2 (raw file):

Previously, orizi wrote…

don't change the pub configuration as a part of this PR in non of the preludes please.

Done.
Should I open another PR after this one or it should not be included in preludes for now?

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 8 files at r1, 4 of 5 files at r3, all commit messages.
Reviewable status: 7 of 8 files reviewed, 2 unresolved discussions (waiting on @julio4)


corelib/src/prelude/v2023_10.cairo line 30 at r2 (raw file):

Previously, julio4 (Julio) wrote…

Done.

still same changed pub issue.


corelib/src/prelude/v2024_07.cairo line 20 at r2 (raw file):

Previously, julio4 (Julio) wrote…

Done.
Should I open another PR after this one or it should not be included in preludes for now?

adding to the prelude makes sense to me - just don't mess with the pub level in this PR.

@julio4 julio4 force-pushed the feat/from_iter_trait branch from f1dc066 to 489db26 Compare January 9, 2025 13:58
Copy link
Contributor Author

@julio4 julio4 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: 5 of 8 files reviewed, 2 unresolved discussions (waiting on @orizi)


corelib/src/prelude/v2023_10.cairo line 30 at r2 (raw file):

Previously, orizi wrote…

still same changed pub issue.

Oh my bad, I didn't noticed there was different visibility across prelude versions.


corelib/src/prelude/v2024_07.cairo line 20 at r2 (raw file):

Previously, orizi wrote…

adding to the prelude makes sense to me - just don't mess with the pub level in this PR.

Done.

@julio4 julio4 force-pushed the feat/from_iter_trait branch from 0bdfaa4 to 7434298 Compare January 9, 2025 14:02
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 4 of 4 files at r4, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @julio4)


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

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.

3 participants