Decorators? Directives?

@jeremyruston

Have you thought about decorators? (There’s actually a better term way back there in my tired, old brain, but it \escapes me right now :wink: ) Maybe directives?

\private

Irrespective of whether the host tiddler is tagged $:/tags/Global/ $:/tags/Macro, macros et al encountered after \private are not exportable up until the following is encountered (if present) …

\public (or \global)

Irrespective of whether the host tiddler is tagged $:/tags/Global / $:/tags/Macro, macros et al encountered after \public or \global are exportable.

Then, for simple one-offs…

\define private my-macro(a, b)

\procedure global my-proc(x, y)

Finally…

\procedure my-library::my-proc(ultimate-question) 42

Where my-library:: has absolutely no effect whatsoever, it’s purely for my (the coder’s) benefit – and much more informative, here:

<<my-library::my-proc "the question">>

especially if this were allowed…

<<$:/my-stuff/my-library::my-proc "the question">>

And because blah:: has no effect, the following is an identical reference:

<<my-proc "the question">>

Of course, if you can see your way to making <<my-library:: functional… :slight_smile:

And obviously, the double-colon part of the syntax is just a suggestion.

Thoughts?

Sorry for the long post.

History

IMO A little bit of history is necessary to put my conclusions at the end of this post into context.

We do have predefined variable scopes, that are active, since macros have been introduced with alpha-11. Since then the mechanism did grow “organically”.

  • Macros are local by default. So only available within 1 tiddler
  • Transcluding tiddlers does not import variables.

v5.0.13-beta introduced the importvariables widget

  • Macros can be made global with <$importvariables-widget
  • Global variables are defined within the $:/core/ui/PageTemplate tiddler

v5.1.18 introduced the \import pragma

  • Macros can be imported into templates using the \import pragma for “ease of use”
  • Internally the import-pragma is resolved with an importvariables-widget

v5.1.22 added support for a new system tag $:/tags/Macro/View which allows users to define macros only active in the ViewTemplates

  • $:/core/ui/Viewtemplate contains a \import pragma for VT global macros

v5.2.3 added support for a new system tag $:/tags/Macro/View/Body which allows users to define macros only active in the ViewTemplates Body section

  • $:/core/ui/ViewTemplate/body contains a \import pragma for VT Body global macros

v5.2.4 added Nested Macro Definitions

  • Macros can be private to an “outer” macro definition

v5.3.0 Functions and procedures have been introduced, so the term “$:/tags/Macro” was considered a bit misleading.

That’s why $:/tags/Global… has been introduced. $:/tags/Global and $:/tags/Macro have the exact same behaviour and each one of them has 3 scopes

  • $:/tags/Global, $:/tags/Global/View, $:/tags/Global/View/Body
  • $:/tags/Macro, $:/tags/Macro/View, $:/tags/Macro/View/Body

Conclusion

\private pragma

I think, we do not really need a \private pragma because:

  • procedures, functions and macros are already private by default
  • Do not mark tiddlers as global, if their functionality should be private
  • If you want to use “my-library” functionality use the \import pragma instead
  • Nested procedures allow us to completely “hide” functionality from “outer scopes”

\public, \global pragma

IMO The existing \import pragma and <$importvariables widget are sufficient to define every “global” scope users need for their templates.

The existing 3 global scopes can be extended at any time by the core or by users out of the box.

New pragmas would need new code js code, to achieve something, that already exists.

my-library::

IMO the main argument for a “library-prefix” would be the possibility to avoid naming collisions for imported macros.

If that’s a concern, do not make your macros global. If a fine-grained control is really needed use the \import prgma and you can implement your “library-prefixes” using namespaces eg:

\import [[$:/my-stuff/my-library]]

I think you did not think your suggestion to the end. Decorators and Directives are 2 completely different concepts.

I think our pragmas are more like “Directives”, except we do not have a “compile-step” like other languages have.

Code optimization can not be done at compile time, TiddlyWiki has to optimize performance at runtime.

So we need concepts, that can be parsed and optimized in a single wikitext-code passthrough.

If we write eg: \private and \global procedures into 1 tiddler we will add a lot of complexity. I think we cannot be resolved those scopes in a single parser run. With the current concept, imo we cannot implement it at all

just my thoughts.
-mario

Thanks for the extensive treatise, @pmario. That took quite some work!

Like I said, there’s a better term but it wasn’t coming to me. I won’t let get in the way of communication of ideas.