New type: Iterator - a safe IEnumerator #1431
louthy
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Language-ext gained
Iterablea few months back, which is a functional wrapper forIEnumerable. We now haveIterator, which is a more functional wrapper forIEnumerator.IEnumeratoris particularly problematic due to its mutable nature. It makes it impossible to share or leverage safely within other immutable types.For any type where you could previously call
GetEnumerator(), it is now possible to callGetIterator().Iteratoris pattern-matchable, so you can use the standard FP sequence processing technique:Or, bog standard imperative processing:
You need to be a little careful when processing large lists or infinite streams..
Iterator<A>usesIterator<A>.ConsandIterator<A>.Niltypes to describe a linked-list of values. That linked-list requires an allocated object per item. That is not really a problem for most of us that want correctness over outright performance, it is a small overhead. But, the other side-effect of this is that if you hold a reference to the head item of a sequence and you're processing an infinite sequence, then those temporary objects won't be freed by the GC. Causing a space leak.This will cause a space-leak:
firstreferences the firstIterator<A>.Consand every subsequent item via theTail.This (below) is OK because the
iterreference keeps being overwritten, which means nothing is holding on theHeaditem in the sequence:This type is probably more useful for me when implementing the various core types of language-ext, but I can't be the only person who's struggled with
IEnumeratorand its horrendous design.A good example of where I am personally already seeing the benefits is
IO<A>.RetryUntil.This is the original version:
Notice the
foreachin there and the manual running of the item to retry withRunAsync. This has to go all imperative because there previously was no way to safely get theIEnumeratorofSchedule.Run()and pass it around.This is what
RetryUntillooks like now:Entirely functional, no imperative anything, and even (potentially) infinitely recursive depending on the
Schedule. There's also no manual running of theIOmonad withRunAsync, which means we benefit from all of the DSL work on optimising away theasync/awaitmachinery.Future:
IteratorinStreamTIteratorin PipesIteratorT(although this would likely just beStreamT, so maybe a renaming)This discussion was created from the release New type: Iterator - a safe IEnumerator.
Beta Was this translation helpful? Give feedback.
All reactions