A question about defining functions outside the \function pragma

I am making substantial use of the custom filter operators we can define with the \function pragma.

I have a useful function (custom filter operator) that I define in the top of a tiddler that is made use of later in the tiddler.

However I want to use a different definition of the same function later in the tiddler. Is there any way I can redefine the function pragma for use later in the tiddler?

  • It is clear here in the documentation Variable Usage that it can’t be redefined as regular variables can.

Is there a workaround? is this a gap? Would it be reasonable to provide a method even a widget, that wraps a section of wiki text where an alternative function definition can be used?

I found a resonable work around which may interest some of you.

  • However I expect many of my questions above still stand.
\widget $tag.search()
   \function search.context() [tag[TiddlyWiki blog to self]]
   \define transclusion() unique1
   {{$:/core/ui/SideBarSegments/search}}
\end
\widget $toc.search()
   \function search.context() [tag[TableOfContents]descendants[]]
   \define transclusion() unique2
   {{$:/core/ui/SideBarSegments/search}}
\end

<$tag.search/>
<hr>
<$toc.search/>

I defined two custom widgets, as they can include pragmas.

  • Not also setting transclusion to two different values to make the resulting popups unique.
  • The above example will not do anything unless other changes are implemented, but they work for me.

Why?

This is an issue that arose building an “In context” search that leverages the existing search tool.

1 Like

I think the work-around you found is likely the best you’re going to get.

(Note that I’m speaking from a much-deeper understanding of JS the language than of the Tiddlywiki tool; I may suffer from some misunderstandings.)

The problems is that “later in the tiddler” has to do with the order in the source code, but nothing to do with when you happen to use it. If you were able to redefine the function in the same scope, then when you use it, you would get the last-defined version. As it stands, you’re not allowed to redefine it, so you get the first-defined one.

But a function pragma introduces a new scope where you can shadow the outer version. This means at runtime, when you enter that function scope, you might add definitions that will only last until you return to an outer scope. The newly defined functions will be found ahead of those from the outer scope.

This is an extremely common situation in programming languages. Almost all languages work this way, and TW is simply layering atop the JS language, which has this behavior.

I think you found it.

No, not particularly.

Well, function pragmas already provide that. It would certainly be possible to add other syntax. JavaScript generally introduces a new scope when you enter a { - } -delimited block of code. But I think it’s much cleaner to use the function scope.

2 Likes

Have you considered using the <$importvariables> widget? Not sure it works with \function pragmas, but it may be worth a try. Each one of your different variants of the function should be defined in its own tiddler though.

Fred

A useful trick at times is to use a typed block which opens the door for using pragmas at the beginning of each typed block, which can be anywhere in a tiddler.

1 Like

Does this have similar drawbacks as the $wikify widget? If I remember correctly, the usage of that widget causes a lot of overhead and can slow things down if used in larger quantities…

Yaisog

It does indeed have poor performance if you specify a render type.

Thanks @saqimtiaz I will have a play with this and sounds very interesting. I was not aware of this.

  • it appears to answer by question well :+1:

I did not mention using transclusions as a method to “import content” that can contain its own “redifined” pragma, however this tip is a way to do it “inline” in the text.

  • I can see some new code patterns are possible
  • I imagin the performance will be similar.

Good idea as well @tw-FRed. I will investigate. I think @saqimtiaz approach may suit me because the redefined pragma are visible in the current tiddler and it avoids additional tiddlers from which to import.

  • however there will be cases where this may be better
  • it does however address the original question, thanks

It is always importiant to be aware of potential performance issues and alternatives, with larger quantities.

  • however I am rarely so worried about this because I try and avoid the large quantities in the fist place. Not in my data, but the presentation.
  • within a tiddler I can limit or scope the quantity
  • coincidentally this was to support “in context search” as you may see in my workaround. Which is by definition trying reduce quantities by setting a scope.
  • an this case I wanted to use more than one version of a pragma in the current tiddler but not many.