Question re variable redefinition

My dear developers I am wondering if you can tell me the consequence of defining the same macro/procedure function many times?

I have a small macro tool I would like to include with many of my packages, basically it involves a macro to support changing config settings. The thing is I would like this available if I install just one of my packages or many, so it will be in a global definition and be defined as many times as packages that include this.

Will it hurt the performance, or load time if the same macros is defined many times?, I know the last will win and I am happy with that.

  • Of course this is a candidate for including in the core as when code is common it make sense it belongs in the core but that may take more time.

I would prefer not to complicate matters by demanding a separate install or dealing with and overwite prompt in the import process.

What do you think?

Is there an alternative approach?

Should I present it here for core inclusion?

Note on this occasion it needs its own tiddler and a $:/tags/ViewTemplate tag.

If I understand correctly, I’ve thought about this a few times…

My latest idea is to retrieve the value for the variable from either:

  1. a known, common-to-all tiddler
  2. or each package/plugin also carries the same field preloaded with the value and each subscriber gets the value from there.

Essentially, they both behave the same way:

<$let somevar={{common-tiddler!!somevar}}>

  <<and-away-we-go>>

</$let>

Hope that makes sense.

Interesting;

If I must have a common tiddler this changes the logic a little, but this is good food for thought.

  • I am also thinking we could use a test [[myprocorvar]getvariable[]!is[blank]else[<local-proc>]
  • Or some kind of cascade or tag driven way.

I am still keen to know what the impact of multiple redefinitions of the same variable/procedure are.

There is an impact, but no more than…

<$let var=X>
  Stuff
  <$let var=X>
    Stuff
    <$let var=X>
      Stuff
</$let></$let></$let>

And really, you’re only getting the one that’s “nearest in scope”.

The question is what if a dozen tiddlers all have a global definition to set the same variable?, will it be read once or many times to end up with the last value? and when a refresh is triggered?

I am thinking something like $:/config tiddlers but for a procedure/function, informed by your first suggestion. eg; $:/config-macro/mytest…

AS I understand it…

When you reference my-var, TW looks back up the scope-chain, finds it and uses the value found. It doesn’t keep on searching.

Now, be aware, if the others are there but further back in the scope-chain (like my previous example), they are still “in memory”. To see this for yourself…

<$log $$all=yes />

(You don’t actually need $$all in that example, I’m just being super-clear).

Add that log call somewhere deep inside a “dense” tiddler. In the browser console, open the table and start scrolling down – you’re seeing the scope-chain leading all the way back to when the universe started :wink:

I have tiddlers so lengthy and dense, they break <$log> – nothing happens when I try to open the log table. Move it to something “lighter”, and it’s fine.

I will review your example when back at may desk, thanks.

I am still in a brainstorm phase. I am thinking test if the proc/variable or its global definition is available and if so use its current value, if not set, use its default value in code. If changing the value from default for the first time create the global definition to the non default value.

If the global definition exists use it default or otherwise

Or something like that :nerd_face:

The main problem with duplicated code is maintenance. I personally would try to avoid that situation at all cost. It will create super hard to find problems. Especially if others try to use your code.

As you know. The last tiddler tagged $:/tags/global that is loaded will win. The sort order in first instance is defined by the tiddler title

So I personally would create a bundle or plugin, that is dynamically created using only 1 source of truth, to avoid duplicating code.

The TW plugins have a “dependents” and a “parent-plugin” field, that can be used to install plugins with dependencies. That’s the mechanism codemirror uses

From my point of view it would make much more sense to have a closer look how you can create your own plugin-library, that uses the core possibilities, than to create a hack that will only cause problems for yourself and others

3 Likes

Thanks for your considered responce @pmario

I have already learned from you what you stated here. The original question was to identify what happens with variable redefinition. I am trying to understand what happens with redefinition, in memory etc…

  • I would be happy with an answer to this question

However I provide more for the inquisitive;

In this case it would be a small global macro or variable only. Barely worth a plugin let alone building a library.

  • My request for details on the library mechanisium so I can build a generator, without needing node, has gone unanswered. I would use a zip to export the library tiddler s. But I cant identify the library requirements.
  • I must revisit this

Here is an example, consider that I may have 100s of solution packages. A subset of these are sensitive to the current user name. A useful support tool would be an alternative to the qualify macro that includes the username, so we can set and retain state tiddlers per user.

  • This simple macro may be needed by all user sensitive packages but only one or more may be installed at a time.
  • thus it may be defined more than once
  • its so simple I am not concerned about which macro wins, only that one does. If I had to in the future I could deploy a version garenteed to win.

As you may see, a user sensitive qualify may be a suitable core improvement and if that happens i will not need to include this in many of my packages but until then…

  • One work around may be to define the macro many times, once for each package with a unique name, however this may consume memory. And is a little more complex to manage.

Other notes

Also note I most likely would build all user sensitive packages on the same wiki so I can insure this shared macro is identical.

I am researching the idea of a “Shared mechanisium” to resolve this issue but until then I want to understand the status quo.

Variables stack. So if you remove the last tiddler that defines the macro, the “next” one will take over.

That’s why I wrote that it will create hard to find problems. If a user modifies the wrong tiddler with the code, it will not be activated.

But will only one be in memory at any time, if they are global?

  • I can document things so its not a problem in trouble shooting. But these are private to the installed packages.

  • I created a macro once with a ? Parameter listing every re/definition source.

Technically they are all in the memory at the same time, but only the “last” one is visible to the rest of the code.

\define test() a

<$let test=b>
  <<test>>
</$let>

<<test>>

The memory several global variable definitions create is very similar to the one this example cerates.

I should have asked does it tax the refresh mechanisium?

Not really, except if you have 1000++ of redefinitions.

Thanks all. I Concider this thread complete.

I have also come up with a design idea that allows multiple plugins or packages to include a tiddler in their own namespace with an indicator requesting a shared tiddler title, its tags will be hidden in an additional field.

  • There will then be a startup mechanisium that checks all tiddlers with the same shared tiddler name, and selects the most recently modified and creates a shared tiddler from that (applying the supplied tags).
  • if the current shared tiddler has the same modified date as the latest, nothing else happens.
  • The mechanisium can also list all tiddlers requesting the shared tiddler title.
  • only one tiddler will be active, the latest,
  • not only a form of versioning, the latest modified wins if a new package is added later or one of them edited by the use the newest wins
  • later we could add the ability to select or regress to another version of the shared tiddler and also compare text fields to detect content differences.

I will publish seperatly on this.

1 Like

I have abandoned the above approach, although it suggests an interesting code pattern, because I have found another approach that is much simpler.

If a shared tool, including a procedure/function is installed and tagged appropriately such as $:/tags/Global it will have the resulting procedure/function available, I can test for this and use it if already installed.

  • If however it is not available then I need to import it or use another definition