IEnumerable is eagerly iterated
See original GitHub issueWriting a for
loop over IEnumerable
objects works but it seems like it enumerates everything (supposedly in an array buffer?) before executing any loop body and performing rendering.
As a user, this is surprising as the similar foreach
goes through the enumerable lazily.
It has some undesirable consequences:
When the template code influences the enumeration itself. This is my use-case and how I noticed this: I have a queue of items that needs to be rendered, and rendering one item can enqueue a new one. Anything enqueued inside the loop isn’t processed.
Processing infinite sequences is impossible.
You may be tempted to do a TakeWhile
pattern but it won’t work:
for item in infinite
if item.stop_here; break; end
end
Issue Analytics
- State:
- Created a year ago
- Comments:9 (5 by maintainers)
Top Results From Across the Web
C#: IEnumerable, yield return, and lazy evaluation
This interface enables iterating over a collection. In other words, if something is an IEnumerable , you can mostly think of it like...
Read more >Foreach loop doesn't iterate over entire IEnumerable
An IEnumerable is an iterator, so it returns one result at a time. Each time foreach loops, it asks the iterator for the...
Read more >IEnumerable is Lazy… And That's Cool
IEnumerable is lazy while an array or list is implicitly eager. Consider an array. First, you have to define its size which is...
Read more >IEnumerable Vs List : r/csharp
IEnumerable is lazy (lazy can be a good thing) while List or Array is eager. So IEnumerable is not evaluated until you iterate...
Read more >C# IEnumerable Eager vs Lazy Loading | by Aisha khan
This is called deferred execution or lazy loading. While you are iterating over the collection, the connection to the database remains open.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Fixed by commit b39f7a1, will be available in next version
Agreed, it was introduced quite some time ago because Liquid was requiring the length to be accessible in a variable, so I made quite some change back in the days (the previous implementation was much simpler actually)
https://github.com/scriban/scriban/blob/3ba3cc3ec8baa65a3a5983c1e610ad5cfc662b5f/src/Scriban/Syntax/Statements/ScriptForStatement.cs#L114-L116
So rethinking about it, it should be possible to make the access of the length deferred (so that in that case you pay the price of a potential forced iteration on all elements) and use the enumeration otherwise for the loop.