For loops support a range syntax for iterating a fixed number of times,
which looks like this.
```liquid
{% for i in range (1..100) %}
...
{% endfor %}
```
Previously, we converted these ranges to arrays using `to_a`, which
initialized an array containing each number in the range. Since all we
use these ranges for is iteration, this is far less efficient than
using a range iterator.
Doing this means that iterating over ranges now takes O(1) rather than O(n)
memory. See the PR for more benchmarks.
* Remove to_a cast on ranges
* Add ReversableRange iterator
* Add custom range-specific slicing logic
Users of Liquid will often wish to filter an array to only those items that match a certain criteria. For example, showing "pinned" messages at the top of a list.
Example usage:
`{{ comments | where: "pinned" | first }}`
or
`{{ products | where: "category", "kitchen" }}`
* Add where filter to standard filters
* Add tests for new where functionality