question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IEnumerable is eagerly iterated

See original GitHub issue

Writing 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:closed
  • Created a year ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
xoofxcommented, Apr 9, 2022

Fixed by commit b39f7a1, will be available in next version

1reaction
xoofxcommented, Apr 9, 2022

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found