\parameters and \function

function being variables with only limited arguments possibilities, I was tempted (out of despair about argument values) to try them with parameters widget. Of course it failed.

But the doc should be more explicite about this.

Now, why am I asking for this? Well, it’s because I have a case where my functions argument is blank when in fact I feed it with non empty value, and I was tempted to see if that could help solve the problem. Note that this topic is NOT about that problem.

An other question: if a procedure call a function, are there effects about parameters if the procedure is called as argument (actions=…)? This was not the case for my problem, but I’m beginning to feel really suspicous about procedures…

On a related note, see that code:

\define have(joy)
<$parameters joy="fun">
<<joy>> and $joy$
</$parameters>
\end

* <<have>>
* <<have luck>>

The result is:

  • fun and
  • luck and luck

The first bullet is a bit disappointing from a consistance point of view. Anyway, if with $parameters, \define macros can behave as \procedure macros, what’s the point of \procedure ? Is that only internal stuff?

@jypre If I may suggest, you have “gotten yourself in a knot”, as did I some time ago trying to understand these changes based only on GitHub notes.

Please let me be straight. I speak from a good level of understanding on this subject and hope this helps you resolve your quandaries.

  • I have not as yet found any serious issues.

This is simply not true.

You just can’t use the parameters widget within it, because that is a widget, and functions are filters. We have never been able to put widgets in filters.

Any value can be accessed in a filter, variable, field tiddler are all available and the parameters can be defined and set to defaults inside the (p1:"VALUE") (just like define macros) and they can be referenced as variables within the function or as <paramname> in filters.

The substitute operator helps here to replace the deprecated $var$, <<__var__>> and $(var)$ in procedures as well. See below.

  • We can now use a filter like a variable by using <<functionname>> as a custom operator [function[functionname]] or [functionname[]] and more with parameters.
  • I too was not happy with only the first value being returned but now I see its value and how to get around it with +[join[]] or +[format:titlelist[]join[]]

Procedures replace macros and blending deprecated macros and procedures is surely not what you should be doing, but its fun to explore.

Now let us consider procedures

There are technical reasons, I don’t understand, but they replaced macros \define macroname so we would be able to do without them, but we need to keep them for backward compatibility. The thing they do not want us using macros for is the substitution the $(varname)$ and $paramname$, and <<__var__>> is replaced with <<var>> now.

  • The old macro definition is ONLY deprecated and you can use them. Use them until you learn how to do without them.
  • Research of mine show you can use $parameters widget in transclusions, $macrocall to call procedures and $transclude $variable= to call macros. With logical limitations (only) when it comes to some additional features.

Despite taking these “parameter forms” away from the \procedure and only passing parameters that can be used as variables inside the procedure, procedures have added flexibility now through the provision of the $parameters widget, the new backticks for attribute values (Which do have $(var/param)$) and more. And you still have access to anything you can reference in wikitext as you can with macros.

  • Add to that the genesis widget, custom widgets, custom operators.

We are leaps ahead in 5.3.x than we have ever being.

  • The $joy$ is the problem, they do not want us to use this form, or $(varname)$ unless we must, and arguably we need not.

Thanks you @TW_Tones. OK, so if I use \define macro but restrain from using $pbram$ bnd $(param)$ and any textual substitution, I should be fine. This is glorious time for filters and function.

I am rather saying use define and its substitution as you need just try and replace it over time. Personaly I find that the new fffunction fffilter makes this easy once you come to terms with its operation.

I have come up with a solution to my problems:

  • I systemically define procedure parameters with the $parameters widget.
  • if I call a procedure with a parameter, I use the $transclude widget with named parameters
  • if I have to call such a procedure as a argument (for a button for instance), I define an ad hoc parameterless function that does it.

Example:

\procedure setupRound()
<$parameters roundid={{!!round}}>
  <$action-setfield roundjob=<<roundid>>/>
</$parameters>
\end

\procedure start_setupRound() <<setupRound 7>>

<$button actions=<<start_setupRound>>>do automatic pairing 7 (hard coded)</$button> currently, roundjob value is "{{!!roundjob}}".

That’s not very nice but things are done well with that! With the $parameters, I have set code for using a “roundid” field if I do actions=<<setupRound>> instead.

Yes I found this in the documentation to be a key value of the parameters widget

When the default value of a parameter must be computed dynamically

Using one procedure to call another is also a useful way to reduce the complexity of making a call.

I am glad you made progress.

I am not sure of the bigger picture of your solution but I have a hunch we can simplify it further.

The following code does the same thing without parameters.

Named parameters are invaluable in the long run and should be prefered.

Positional parameters will create maintenance nightmare if there are many of them and if you need to change the order in the future.

\procedure setupRound(roundid:{{!!round}})
  <$action-setfield roundjob=<<roundid>>/>
\end

\procedure start_setupRound() <<setupRound 7>>

<$button actions=<<start_setupRound>>>do automatic pairing 7 (hard coded)</$button> currently, roundjob value is "{{!!roundjob}}".
1 Like

@pmario You said “Positional parameters will create maintenance nightmare if there are many of them and if you need to change the order in the future.” I agree but I think that myproc(b, b) is as postionnal than <$parameters a b>’ though the first one is more common and preferred.

Also, my field fetching example is cited as a use case for the parameters widget.

That stuff seems more complex than it should be and surely more fuzzy than it could be. My code was my first successful use of it.

I will just add providing a value to a parameter works but we need to resort to a macro call or now transclude variable, if the parameters value is in a variable

However a new pattern I have started to explore is passing the procedure, function or variable name only and inside the procedure or custom widget, with the help of the parameters widget retrieve the value.

  • Unfortunatly this is a newish pattern and may cause ambiguity. Eg proc=procname vs proc=<<procname>>
  • the exception may be if you write a procedure, custom widget or transclusion to intentionally handle an indefinite number of parameters.
  • this can include to redefine a widget with the genesis widget. Allowing any/all parameter/value pairs to be passed through to another step.
  • and especialy if you know or code the solution so position is unimportant.

functions and procedures have built in parameters. They are both positional and named.

The parameters widget and pragmas are intended to be used with transclusions. Prior to v5.3.0 there has been no possibility to call transclusions with parameters. Especially the transclusion shortcut syntax.