List of tiddlers and their associated fields

@Scott_Sauyet thanks for your considered feedback.

The difference between us is my non-locality is supported by standard variable names such as I always code for acting on currentTiddler, and always use filename both in the function name and variable. In a sense it may be non-local but it becomes global.

  • Yes there is, multiple ways and I use them a lot, but something not everyone has realised yet is; “the key input can be the title given it by the filter” it is placed within. I think I need to document that separately.
    • see how op.fields[] is responding to the current title, in this case currentTiddler
  • Parameters can be passed as for macros <<function var:"val">>
  • Parameters can be passed as for operators [function[val]]>> [function<varname>,{!!fieldname}]>> etc…
    • The filters title is fed into the operator
    • All variables are available in the function unless overidden with a parameter name.
    • I think there is another way I can’t remember right now :frowning_face: I remember :grinning_face_with_smiling_eyes:
      • Calling with macrocall and transclude widgets.
      • Also within the backtick attributes, as variables or filter operators.

Here is my rewrite of your code, the way I would do it. Changed the tag for more data. The prior example was to replicate the source in the topic.

\function tagged.list(tag) [tag<tag>]
\function op.fields() [fields[]prefix[op]] -[[text]] -[[title]]
\function fieldname-title() [<fieldname>sentencecase[]]
\function fieldname-value() [all[current]get<fieldname>]

<$list filter="[tagged.list[Filter Operators]]">
<$link/>
<ul>
<$list filter="[<currentTiddler>op.fields[]]" variable=fieldname>
<li><<fieldname-title>>: <<fieldname-value>></li>
</$list>
</ul>
</$list>
  • tag. List[] is unnecessary but it demonstrates a parameter
  • fieldname-title and fieldname-value are used as variables, with the added advantage they are shown as text, they imply thay act on fieldname (to me at least)
    • I removed the parameter name because the value is obtained from the variable in the list. If you name the parameter I think it becomes blank if not given, and you loose access to <fieldname>

[Post script]
One area I am not sure of yet is if I want to paramatise a suffix to an operator eg in format:titlelist[] the titlelist, it can still be done with the \define` and a substitution. PPS Eric gave the answer here Can the suffix of an operator be given a variable? substitution in the backtick attributes.

PPPS;
Typicaly function returns only the first non-blank value (like cascades) but they can also be used to store lists or concatenate values with +[format:titlelist[join[ ]] OR +[join[ ]]

I know the code is only an example for a creative way to use functions, but for this concrete example with the filters and fields used, I would create a table and render the field values instead using them as plain text.

I think a table would be easier to read.

\function f.taggedList(tag) [tag<tag>]
\function f.opFields() [fields[]prefix[op]] -[[text]] -[[title]]

<$list filter="[f.taggedList[Filter Operators]]">
<table class="tc-max-width">
	<tbody>
		<tr>
			<th colspan=2><$link/></th>
		</tr>
		<$list filter="[<currentTiddler>f.opFields[]]" variable=fieldname>
			<tr>
				<td><<fieldname>></td><td><$transclude $field=<<fieldname>>/></td>
			</tr>
		</$list>
	</tbody>
</table>
</$list>

I did also rename the functions. For some time now I do use a special function format, to be able to easily identify functions used in filters or as variables. The format is like this: f.functionName for if the function belongs to a global procedure eg: myProc I use f.myProc-functionName, which can be a bit “clunky”, but will avoid naming conflicts for global function names.

Functions can also be used using the function-operator as in the following code. That mechanism is important, if a function can get more than 1 parameter. See the parameters of the first list-widget

\function f.taggedList(test, tag) [<test>] [tag<tag>]
\function f.opFields() [fields[]prefix[op]] -[[text]] -[[title]]

<$list filter="[function[f.taggedList],[non existing Title],[Filter Operators]]">
<table class="tc-max-width">
	<tbody>
		<tr>
			<th colspan=2><$link/></th>
		</tr>
		<$list filter="[<currentTiddler>function[f.opFields]]" variable=fieldname>
			<tr>
				<td><<fieldname>></td><td><$transclude $field=<<fieldname>>/></td>
			</tr>
		</$list>
	</tbody>
</table>
</$list>


just some thoughts
-mario

Yes, I agree about using tables, I was responding to the syntax a functions issue, and did not want to make it more complex.

  • lately I have being using minimalist tables just to get the row column output, but it is much easier to read. Example below.
  • when it comes to naming each to there own, I like moving towards plan language and away from code like names.
  • Like you I do gravitate towards function operators but prefer them to be name driven, I rarely use the function[] format and prefer to used the custom.name[]
    • But this is the wonderful quality of the 5.3.x improvements, there are lots of opportunities to find what we feel is the optimum approach for our minds, and far more possibilities than before.

This is what I mean by minimal table

<table style.width="..  >
<$list filter="...
   <tr><td>Row name</td><td>row value</td><tr>
</$list>
</table>
  • sometimes I even put the row in a separate procedure and just call that.
    • Now days we can have one procedure in another so its local only to that definition, I even put custom functions inside a procedure or widget if its not a global tool.
  • I like how your example makes a row out of the heading :+1:

It is interesting seeing how others make tiddlywiki their own.

I am slowly accruing a set of functions, some procedures and some widgets and a set of naming standards, to build a set of global features, I may use in all my wikis, eventually, but I also like each solutions to be stand alone. Plug compatible you could say, In many ways extensions to tiddlywiki. So I am happy to build a codex, or meta language I can remember, so I don’t need to check the syntax as often (because that annoys me).

1 Like

If you’re going to do that, I think that a very slight tweak would improve readability a lot, using a single table. The simplest way to do that would just be to interchange the outer <$list> widget with the <table> tag. Alternate Table Demo.json (598 Bytes):

\function f.taggedList(tag) [tag<tag>]
\function f.opFields() [fields[]prefix[op]] -[[text]] -[[title]]

<table class="tc-max-width">
<$list filter="[f.taggedList[Filter Operators]]">
	<tbody>
		<tr>
			<th colspan=2><$link/></th>
		</tr>
		<$list filter="[<currentTiddler>f.opFields[]]" variable=fieldname>
			<tr>
				<td><<fieldname>></td><td><$transclude $field=<<fieldname>>/></td>
			</tr>
		</$list>
	</tbody>
</$list>
</table>

I might then go back and left-align the <th>s and increase their font size and padding. There are plenty of other ways we could achieve this, but this one is especially simple. However, the separate tables in your version are a little nicer. The simplest way to do this is to fix the width of the first column.
Alternate Table Demo 2.json (621 Bytes):

				<td style="width:20%;"><<fieldname>></td><td><$transclude $field=<<fieldname>>/></td>

This of course has the problem that we have to pre-guess the likely width of that column, whether it’s as a percentage or a fixed width. A single table makes that easier.

Either way, I find consistent-width columns across parallel tables much easier to read.

1 Like

global is the ultimate in non-local. And it’s what I’m hoping to avoid. In my day-job, I push functional programming over other paradigms. One tenet of FP is that functions are pure, relying only on their parameters and not any global or other non-local environment for their functioning. That’s why I asked this:

What I was really looking for is a fix for this:

\function fieldname-title(fld) [<fld>sentencecase[]]

<$list filter="[<currentTiddler>t.fields[]]" variable=my-field>
<<fieldname-title <<my-field>> >>
<!--              ^^^^^^^^^^^^--- This is illegal syntax  --->
</$list>

Is there a simple replacement for that? One that doesn’t involve depending on global or other non-local variables in the function?

Right, and I’m not very happy with that either. For some reason, it bothers me less, but I would like to address that at the same time. I want my functions to know nothing about the outside world not passed to them as parameters (or as the current context when used as operators.)

Adding those parameter names is precisely what I’m trying to support. I know this is outside the norm when using TW, but is it possible to do it in a user-friendly way?

Can they also be called with parameters when they’re just used like variables, not inside a filter run? To repeat myself, I’m trying to solve this:

\function fieldname-title(fld) [<fld>sentencecase[]]

<$list filter="[<currentTiddler>t.fields[]]" variable=my-field>
<<fieldname-title <<my-field>> >>
<!--              ^^^^^^^^^^^^--- This is illegal syntax  --->
</$list>

Is there a simple replacement for <<my-field>> here?

With the desire for complete clarity and documentation on the subject of filter functions;

  • Please understand I am spending serious time on a carefully worded reply to help promote use and understanding of one of my favorite new features I have spent many hours experimenting with. I will try and generalise this to some documentation.

There are a number of replacements for the non-working <<fieldname-title <<my-field>> >>

  • Use them within another filter ...fieldname-title[literal]... or ...fieldname-title<my-field>... or ...fieldname-title{!!my-field}...
  • have my-field known in the function and don’t even use the parameter as I did with fieldname
  • Use {{{ [fieldname-title<my-field>] }}}
  • Use the following with backticks
<$text text=`${ [fieldname-title<my-field>] }$`/>
  • If more come to mind I may return and update.
  • What is important to remember here, is functions have in part being designed to allow the creation of custom filter operators, which by definition are themselves filters that process their input and generate output. That is we expect them to process their input - the titles or strings as given them by the filter they are used in.
    • Functions are very similar to, but better than the subfilter operator which also processes their input.
  • However like any filter you can write it to start with a Selection Constructor effectively ignoring its input. Then keep this fact in mind when using it in a filter.

On local, global etc…

To me this is a non-issue, not simply because I do like to globalise reusable functions in effect building a meta language but because we can no go ultra-local if we want, in procedures and custom widgets, even tiddlers you transclude.

This is because we can easily write a procedure or custom widget that has nested in it any of the following;

  • \define macro(p) $p$ with substitutions
  • \procedure .. using parameters or variables available to it
  • \function .. using parameters or variables available to it

Such “nested pragma” and any other content including the $parameters widget and its capabilities all exist only inside the “procedure and custom widget” n which it is defined.

  • And of course this “outer” definition can be inside the tiddler you use it in and available now where else (unless imported).
  • Except when using something where it is defined, the outer procedure is almost by definition a piece of code that is addressable independent of where it is defined, as soon as you tag it as global or in the view template etc… it is being globalised to some extent.

When to go global?

As I design a procedure or custom widget and write new macros / procedures / functions, nested within it, I am always thinking about writing globally relevant solutions sometimes I;

  • leave them inside the outer definition (ultra local)
    • especially bespoke ones, to simplify reading the code and have something defined once, used multiple times.
  • move them outside the outer definition providing code reuse (local to the definition)
  • Move them to a tiddler with a global tag for use in this package or solution and possibly throughout the wiki (for this solution/package)
  • Move them to my collection of global items because I want to use all the time.

Want to be ultra local?

Nesting your Tiddlers, macros, procedures and functions within your own procedure, custom widget or transcludable tiddler, is the first approach to ultra local but the $parameters widget also supports this. Just consider that the parameters widget;

  • Can handle even unnamed and unlimited parameters
  • Can process a parameter in its actual definition
    • For example provide a “field name” as a parameter then in the parameters widget retrieve the value in that fieldname on the current tiddler.
  • Can be used instead of let/set/vars to define variables in a sense keeping all the parameter and variable initialisation in one widget.

Why ultra local? - because it all ceases with </$parameters>

  • Just remember local only solutions need more bytes than solutions using global or semi-global definitions.

Regards
Tony

I just want to comment specifically on this.

As the designer you can choose the best approach to suit your coding style.

If I were writing code for an application, such as Excel, or an application delivered in the cloud, I may very well stick religiously to this approach (possibly by order of my employer).

However;

Depending on what you intend to do with your tiddlywiki but coding within tiddlywiki,

I think it is fair to argue another paradigm is warranted.

  • The most global you can get is within your wiki, or that of the tiddlywikiverse.
  • Reusable code reduces the necessary bytes
  • Findable and readable code makes it easier to share and repair.
  • Perhaps being open source, we may be inclined to keep the solutions we develop “open for reuse”
  • When I install something in a TiddlyWiki I intend for it to be used in the wiki, so trapping it inside a locally restricted piece of code is like handicapping what it has to offer.
  • However you use tiddlywiki there is form of localisation taking place anyway, my viewtemplate code appears only in view templates, currentTab is “only” available inside tabs…
  • In someways I treat my tiddlers and their content including TiddlyWiki script as objects and methods. Thus its more like object oriented programming (as much as I understand it) ultimately modularising almost everything for reuse.

And I thank you for that.

We have some fundamental disagreements here, and I thank you for your patience regarding them.

[quote=“TW_Tones, post:26, topic:8987”]

What I really wanted to know was if there was a replacement for the non-working <<my-field>>. We can call a function, as your earlier example showed, by just <<fieldname-title>>, assuming that any values it needs are in global (or some other outer) scope. I was wondering if we could pass parameters to them in the same format.

My original, completely broken code is at: Attempt 1.json (577 Bytes)

I’m not sure how you’re suggesting I’d use this. They would also have to include a . character in their name to be used like this, right? I did that in the examples below, but I’m not quite sure what you’re suggesting as a replacement for my broken code.

This gets the appropriate content, but wraps it in unwanted links: Attempt 2.json (582 Bytes).

If I wrap this in a <$text>-widget (like this: <$text text={{{ [fieldname.title<myfield>] }}}/>) it does work correctly: Attempt 3.json (610 Bytes). But that’s getting pretty far from <<fieldname.title ??my-field?? >>.

Again that works but is fairly far from what I would love to have. Attempt 4.json (609 Bytes)

I think we may be talking past each other here. I’m not particularly objecting to $:/tags/Global. For more complete modularity, we might prefer \import, but I am not worried about that at this stage in my TW understanding.

What I object to is something like this:

\function my-value() [all[current]get<fieldname>]

To understand how to use this, you have to look beyond the signature of the function, and understand its entire body, which might span hundreds of lines. You have to find all free variables (such as fieldname here) and then you have to ensure that when you call the function, those free variables have been defined in some scope that encloses your call. If you are calling multiple functions, you need to find a way to ensure that the name of those free variables do not conflict, but that they are the same if the same value needs to be passed to multiple functions.

Compare that to

\function my-value(fieldname) [all[current]get<fieldname>]

Here we don’t need to know anything about the body to know what we have to pass when we call the function. And we can pass the same value to different functions or pass different values to two different functions, even though both function use the parameter fieldname.

It is precisely this independence of functions that lets me “build a meta language” out of reusable functions.

Yes, I use much the same thinking, but the issue I brought up was about free variables, not function visibility.

For me, I’ve very happy with the Functional/Declarative paradigm. To my mind, t’s actually a very good fit with TiddlyWiki, especially compared to an Object Oriented/Imperative paradigm:

  • Similar to FP, which has a few datatypes and many common operations on them – and unlike OO, which has many datatypes, each with a few operations – TW works mostly with tiddlers and lists of strings, especially lists of tiddler titles. And it has many operations on these types.

  • The filter operations act very much like monadic structures.

  • Operations tend to be declarative, not imperative. It feels more like SQL than like Java.

  • There is very little imperative code of any sort in my wikitext. I’m not telling the computer “do this, then do that, and afterwards, do this other thing.” And when we do need to do anything like this, we usually end up burying it in JS tiddlers, comfortably out of sight.

And of course note that I started this sub-thread by saying

While I’m quite happy discussing competing programming paradigms, what I’m really interested in knowing is whether the one I would prefer to use is well-supported. Is there a simple way to pass arguments to a short-form function call, some syntax to replace the ??param?? to pass the parameter param to the function my.function in this

<<my.function ??param?? >>

I do too, because I believe in all sincerity, I have given an answer you your question as follows a number of times;

  • In the same format as what?

I am keen to understand and overcome where we are at “conceptual odds” I will reflect more on your last reply and respond later.

Just to if it helps
I call functions this way, as if it was a variable, when I want the result displayed. It also displays the result in text.

  • The functions I call this way are usually stand alone, that is they contain within them access to the fields, filters and variables they need, that can include the current value of a variable.
  • However it is possible to pass parameters to a function just as you would a procedure or macro <<functioname p1:"value">>
    • Similarly you can use $macrocall and $transclude $variable to use the paramname= to pass even evaluated values using transclusion, variables, backtickl attributes and filterd transclusions.
    • The parameters always become variables of that parameter name you can use in the function <parmaname>

However;

  • I tend to use functions now more often in filters, including in filtered transclusions {{{ filter }} and backtick attributes, as well as custom operators where we need the name to contain . as we do if defining `custom. Widget’s.

As I said;

I am keen to understand and overcome where we are at “conceptual odds”, I will reflect more on your last reply and respond later.

  • because other may have this same question.

You’ve given me any number of alternative ways to do what I’m trying to do, of varying degrees of simplicity and complexity. But what I’m asking is a simple yes-no question, where a “yes” should be backed up by a simple syntax demonstration, and a “no” will lead me to some minor disappointment and to thinking about which of the many alternatives to the larger construct we’ve seen I should adopt.

As specifically as I can ask it, in this, can the highlighted bit in this:

<<functioname p1:"value">>
<!--             ^^^^^^^  -->

that is, the characters ", v, a, l, u, e, " be replaced by a simple reference to the local variable my-field so that its value will become the argument to the function being called?


But where I thought we were talking past each other actually had to do with how we were using global and local. I was using it to discuss the scope of function parameters. I think you were using it to discuss the visibility of functions. They’re quite different.

<<functioname p1:"value">> is the shortcut form and can’t be used to do as you wish.

<$macrocall $name=function p1=<<my-field>>/>
OR
<$transclude $variable=function p1=<<my-field>>/>

And I answered, just as it is for macros, procedures and always with widgets.

  • There is no reason for it to be different for functions.
  • However there are many more ways to use functions I illustrated to get around this limitation, like {{{ [function<my-field>] }}}

I hope this helps.

Thank you. That’s what I’d come to expect, even if it’s disappointing. I’ll figure out which syntax appeals best.

While that would probably be my second choice, it introduces unwanted links.

But thanks too you, I have plenty of other options.

It does, very much. As always, thank you very much for your help.

Avoiding links is a key value of functions in my view, avoiding the verbose text widget.

  • There are better choices than the ones I presented to achieve specific results and simplify the parameters to “call” a function especially to avoid links. I expect you will discover them in time.
  • They should all be able to be derived from my extensive answers above however I may post more on this in another topic.
  • Leads for you to follow
    • If your desired outcome is to display a result, using a custom widget may be better, even if you still make use of the function you defined.
      • Thus you can pass any parameter value in a somewhat short form <$.my.func p1=<<my-field>>/>
    • If rather than “parametising a function”, you use a procedure, and within that the $parameters widget to pre-processes each parameter you could call a procedure as follows in a short form, like this
      • <<my.proc my-var>> OR <<my.proc my-fieldname>>
        • where the parameters widget sets my-var internally to my-var={{{ [<my-var>getvariable[]] }}}
        • OR my-fieldname={{{ [all[current]get<my-fieldname>] }}}

Thank you very much. I look forward to playing with both. I can’t believe that after all my TW activity in the last 18 months, that I have yet to create a custom widget!