I was trying to create a recursive function that tested whether a tiddler—or any of its ancestors—has tag MyTag
, where ancestry is found by checking the parent
tag of any given tiddler, should it exist.
I couldn’t find anything simpler than a mutual recursion with a helper function, and several other threads here also do something similar, so that may simply be how its done. (If not, I’d appreciate advice on how to do this in a single function)
These are my functions, with in.hierarchy
being the main one and .step
being a simple helper:
\function .step(tid) [<tid>get[parent]] :map[in.hierarchy<currentTiddler>]
\function in.hierarchy(tid) [<tid>tag[MyTag]then[yes]] :else[!has[parent]then[no]] :else[.step<tid>]
The idea is that if the current tiddler has the tag, we return yes
. If it has no parent, we return no
. Otherwise, we use the helper function to recur on the value of the current tiddler’s parent
field.
(I couldn’t do this in one go because I couldn’t find a way to combine the final else
of the main function with the full-filter expression that’s stored in .step
. I can’t find it at the moment, but I believe there is discussion here or in GitHub about allowing let-bindings inside filters. If it’s really happening, I can’t wait! I also should note that I know I should also do some recursive cycle-breaking to avoid any cycles such as C.parent = B
, B.parent = A
, A.parent = C
. But I need to walk before I run. I’ll worry about that later.)
However, the main function does not properly report the results of recursive calls. It properly handles those with the tag and those without parents. But when it tries the return the result of a recursive call, it always seems to return no
.
But, and here’s the head-scratcher, the helper function (which itself calls back to our main function) seems to work fine. As long as the tiddler has a parent
, it reports the value correctly.
Any suggestions about what I’m doing wrong?
You can test this on the main site with RecursiveFunctionTest.json (2.2 KB), which includes the test cases along with the code in the main widget, plus FirstTiddler
, which has MyTag
, and SecondTiddler
, which doesn’t, plus some descendants of them.