Not Defined Function Returns All Tiddlers

Open TiddlyWiki — a non-linear personal web notebook
Create a new tiddler with below content


<$list filter="[function[not.defined]count[]]"/>

<$count filter="[function[not.defined]]"/>

<$count filter="[not.defined[]]"/>

All of these returns 1782 which is equal to <$count filter="[all[]]"/>!

But this is confusing and error prone!

1 Like

When used in a filter, functions are “selection modifiers”. This means that they expect to have preceding filter syntax that provides a list of items as input to the function.

However, when a selection modifier occurs as the first operator in a filter run that does not begin with + or :then, there are no specified input items and it is instead preceded by an implicit all[tiddlers].

This behavior is consistent with all the other selection modifiers, such as [tag[...]], [has[...]], [addprefix[...]], and even math operators like [abs[]] (which will return 1782 zeros!).

The only issue I see is that I can’t find where this handling is documented.

-e

1 Like

Hi Eric,
Thank you for your clarification!
I expect a not.defined function returns nothing so <$list filter="[all[]function[not.defined]]"/> should return nothing, but it passes through all input!
This is a bit confusing especially when you have the function but its scope is local and cannot be seen in calling tiddler.

1 Like

Filter Operators starts with:

A filter operator is a predefined keyword attached to an individual step of a filter. It defines the particular action of that step.

Important: In general, each first filter step of a filter run not given any input titles receives the output of [all[tiddlers]] as its input.

While it definitely belongs there, it might also make sense in Filters and Filter Syntax.

If only there was some way to include small pieces in many places. :wink:

This is also a pretty useful trick when dynamically creating filters. For example, selectively defining a function that is a selection modifier based on a user UI selection. If the function does not exist, everything is passed through.

Combined with using text references to specify function names and thus switching between which function is called, I have been getting a lot of mileage out of functions to replace string concatenation to create dynamic filter strings.

4 Likes

How’s this for reducing confusion: when the filter fails, what you get is …

unfiltered

:open_mouth:

Which is to say, a firehose of all of the tiddlers. Makes sense, no?

1 Like