go-functional icon indicating copy to clipboard operation
go-functional copied to clipboard

Implement tee for iterators

Open BooleanCat opened this issue 2 years ago • 5 comments

Please provide a brief description of the change.

Support tee behaviour for iterators.

Which issue does this change relate to?

#88

Contribution checklist.

Replace the space in each box with "X" to check it off.

  • [X] I have read and understood the CONTRIBUTING guidelines
  • [X] My code is formatted (make check)
  • [X] I have run tests (make test)
  • [X] All commits in my PR conform to the commit hygiene section
  • [X] I have added relevant tests
  • [X] I have not added any dependencies

BooleanCat avatar Jan 26 '24 07:01 BooleanCat

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Comparison is base (b3ea617) 100.00% compared to head (eb938d2) 100.00%.

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #93   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           24        26    +2     
  Lines          572       637   +65     
=========================================
+ Hits           572       637   +65     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Jan 26 '24 07:01 codecov[bot]

@myusko This is a fairly naive implementation of tee. The buffer resizes make it fairly ineffeicient. I'd considered using a linked list instead but it's conceptually more difficult and will take more time for me to figure out.

What do you think about the API for this? I can change how it works under the hood to make it more efficient later but I'd curious about how easy it is to use.

BooleanCat avatar Jan 26 '24 08:01 BooleanCat

@williammartin I'd be curious too if you have any thoughts on how Tee is used here or better suggestions on making it more efficient than using a linked list or ring instead of a slice.

BooleanCat avatar Jan 26 '24 08:01 BooleanCat

I'd considered also using two buffered channels but I'd need the channels to be unbounded in size in order to not lock Next from iterators where one is far ahead of the other.

BooleanCat avatar Jan 26 '24 08:01 BooleanCat

On the usage suggestion - an alternative would be to have Tee directly return the two iterators:

one, two := iter.Count().Take(3).Tee()

I could then make TeeIters private - it's never intended for direct use anyway.

e.g. https://github.com/BooleanCat/go-functional/commit/b8fad8b44a4acaaa4dba52f478f50311a35821c5

BooleanCat avatar Jan 26 '24 08:01 BooleanCat