Negating \functions

I don’t see a syntactic affordance made for functions to be negated – so is the following definition and use of it safe*?

\function .mentions(re) [search:title:regexp<re>]
\function !.mentions(re) [!search:title:regexp<re>]

<$list filter="... [.mentions[this]!.mentions[that]]" ... />

*Safe in the sense that a variable name is safe and allowed to begin with “!”.

It works :slight_smile:

2 Likes

I think true negation could be developed for functions, I like your approach as semantically appropriate but there is another way and that is to use the function as a custom filter operator. Then using then/else to determine the output, else is in effect the negation of then.

\function  title.exists(tiddler) [<tiddler>has[title]then[exists]]

{{{ [title.exists[tiddler]else[notexists]] }}}

<<title.exists tiddler>> 

No, not really. What it is is a roadblock.

That’s an interesting question - I would like to know that too. I’ll have a closer look at the code and single step it. Feedback comes soon

1 Like

@pmario I read the deleted stuff… I hope it’s not the case I need to write not-mentions or whatever.

I had to delete it, because I could not hide it. Still more testing needed. I did not test all combinations yet.

It identifies the exclamation mark ! as an operator prefix and not as part of the function name.

In your list: <$list filter="... [.mentions[this]!.mentions[that]]" ... /> the second function name is the same as the first one – and the internal structure knows about the ! prefix.

The filter evaluation seems to know and respect the internal ! prefix with functions used as operators.

Conclusion

It will also work with the following code.
Your second function definition is ignored. (Which actually confused my quite a bit)

\function .mentions(re) [search:title:regexp<re>]

<$list filter="... [.mentions[this]!.mentions[that]]" ... />
All possible test-cases
\function .mentions(re) [search:title:regexp<re>]

----

test `.mentions`

1: link: <$list filter="[[input-this].mentions[this]]"/>

2: no link <$list filter="[[input-that].mentions[this]]"/>

3: no link: <$list filter="[[input-this].mentions[that]]"/>

4: link <$list filter="[[input-that].mentions[that]]"/>

----

test `!.mentions`

1: no link: <$list filter="[[input-this]!.mentions[this]]"/>

2: link <$list filter="[[input-that]!.mentions[this]]"/>

3: link: <$list filter="[[input-this]!.mentions[that]]"/>

4: no link <$list filter="[[input-that]!.mentions[that]]"/>

-----------

test `.mentions[a]!.mentions[b]`

1: link <$list filter="[[input-this].mentions[this]!.mentions[that]]"/>

2: no link <$list filter="[[input-that].mentions[this]!.mentions[that]]"/>

3: no link <$list filter="[[input-this].mentions[that]!.mentions[that]]"/>

4: no link <$list filter="[[input-that].mentions[that]!.mentions[that]]"/>

5: no link <$list filter="[[input-this].mentions[this]!.mentions[this]]"/>

6: no link <$list filter="[[input-that].mentions[this]!.mentions[this]]"/>

7: no link <$list filter="[[input-this].mentions[that]!.mentions[this]]"/>

8: link <$list filter="[[input-that].mentions[that]!.mentions[this]]"/>

---
---

test with title: `this-that` and `this-thaX`

1: no link <$list filter="[[input-this-that].mentions[this]!.mentions[that]]"/>

2: link <$list filter="[[input-this-thaX].mentions[this]!.mentions[that]]"/>

Link to the responsible parser code in TW

hope that helps
-mario

3 Likes

Wow, that’s some exemplary diligence, Mario. Danke!

Maybe the docs should mention explicitly that negation is supported…

Sorry I don’t understand this?

If a function is defined like my example to return a result if true, otherwise nothing, then the use of then/else or :else filter run, becomes a way to respond to the negative.

Thanks for identifying and documenting this @pmario I thought I had seen negation working in the past when I was teaching myself about the functions.

else[] constructs a new output and terminates the run – most certainly not what my proposed operator needs.

See also the aforementioned :else filter run, that can be a fully fledged filter that follows the previous one, only if it produced no input, ie the title does not exist. The ..then[]else[something]] sets if the subsequent :else filter run is performed or not. It is swapping the non-output to the output.

  • It may not be what you are looking for, but it is another form of negating a filter
  • As demonstrated by @pmario the negation ! is actually possible.