Skip to content

Filter specification #24

@jg-rp

Description

@jg-rp

Filters feel inconsistent, brittle and poorly defined, partly because we're carrying over some or all of the behavior demonstrated by Shopify/liquid.

I want to be specific about the types of the arguments filters accept and I want to define automatic type coercion rules for each parameter.

We'll need to decide on a policy for how to handle values that can't be coerced to an acceptable type. Right now, filters will sometimes raise an exception and sometimes fallback to a default value.

find_index example

I'm conscious that introducing lambda expressions as filter arguments means we're effectively overloading some filters. Add legacy Shopify/liquid behavior when two arguments are given, and we have quite a mess of rules. In contrast, JavaScript, for example, has separate findIndex and indexOf Array functions that accept a function or value for comparison, respectively.

These examples attempt to illustrate the mess that we need to unravel.

This expects a to be an array of objects with string keys, and has ill-defined behavior when a contains items that are not objects.

{{ a | find_index: 'title', 'bar' }}

This is equivalent, but naturally handles items of any type thanks to variable lookup (path resolution) semantics.

{{ a | find_index: i => i.title == 'bar' }}

This has an implicit second argument of null, indistinguishable from an explicit nil/None/null.

{{ a | find_index: 'z' }}

Strings inputs are coerced to single-element arrays, like ["zoo"], resulting in surprising substring matching behavior. Here, we'll get an index of 0.

{{ 'zoo' | find_index: 'oo' }}

Ojects/hashes are also implicitly coerced to a single-element array. If obj is {"z": 42}, this will give us an index of 0, which is reasonable for find_index, but maybe not so for first.

{{ obj | find_index: 'z' }}

So will this.

{{ obj | find_index: 'z', 42 }}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions