Design Opportunity pass parameters to macros and procedures from a filter?

Folks,

I just noticed how functions / custom filter operators allow us to pass parameters in a filter,

\function my.func(p1 p2 p3) [<p1>] [<p2>] [<p3>] +[join[ ]]
\procedure my.proc(p1:1 p2:2 p3:3) <<p1>> <<p2>> <<p3>>

;We can
# `{{{ [my.func[a],[b],[c]] }}}` {{{ [my.func[a],[b],[c]] }}}
# `{{{ [function[my.func],[K],[J],[L]] }}}` {{{ [function[my.func],[K],[J],[L]] }}}
# `<<my.proc A B C>>` <<my.proc A B C>>

;We can't
# `{{{ [<my.proc 1 2 3>] }}}` {{{ [<my.proc 1 2 3>] }}}
# `{{{ [my.proc[1],[2],[3]] }}}` {{{ [my.proc[1],[2],[3]] }}}
# `{{{ [[my.proc],[K],[J],[L]] }}}` creates list of tiddler titles
# `{{{ [procedure[my.proc],[K],[J],[L]] }}}` blank

I wonder if we could make any of the forms in the we can’t section to work?

For example also what if we could say

{{{ [function[now],<date-format>] }}}

You’re missing the initial backslash in your \function—I’m not sure if this was just a copy-paste error or a typo when you were testing, but I do think think it may be influencing your results. With the correct pragma, I get {{{ [[my.proc],[K],[J],[L]] }}} = a link to “my.proc”, which is about what I would expect. It’s obviously bad syntax, but I assume the parser is treating [[my.proc]... as a title and ignoring the rest of the filter, since there aren’t any other proper operators. But this syntax wouldn’t work with a function, either; {{{ [[my.func],[K],[J],[L]] }}} yields a link to “my.func”.

I’m not sure I’m following your general goal and expectations, though.

  • I wouldn’t expect any of your “we can’t” examples to work: procedures are functionally (:wink:) far closer to macros or template transclusions (input optional variable parameters to get wikitext output). Functions are more comparable to a $let widget that defines a variable with a filtered transclusion (they yield an unformatted string of text equal to the first result of the filter).
  • Procedures, like macros, aren’t meant to be filter operators, so #3 and #4 just don’t contain any valid syntax.
  • Filters don’t fully wikify their input prior to parsing, so there’s no opportunity for variable substitution in #1 and #2. my.proc gets treated like a static variable. Honestly, I’m a little surprised that #2 works at all.

I’m just trying to figure out what you’d expect from {{{ [<my.proc 1 2 3>] }}}, and why you’d use it over <<my.proc 1 2 3>>, which obviously does work. Do you think it should be yielding the same output as {{{ 1 2 3 }}}? What if <<my.proc>> contained, say, an $edit-text widget?

You can, if you’ve defined a function now that takes at least one parameter, and you’ve already defined the <<date-format>> variable. But I suspect that’s not what you meant. Do you want to use the <<now>> macro in a filter with a variable parameter, as we can currently use it with a literal parameter like [<now YYYY0MM0DD>]?

I’m not an expert, but it seems like this might be conflating some separate issues. <<now>> is a Javascript macro, so it’s already somewhat distinct from procedures (= transclusions) and even “normal” wikitext macros. And we only got the ability to use [<now...>] with a literal parameter in 5.2.0, which also suggests to me that it’s an outlier among macros (most of which don’t produce a simple string and can’t be meaningfully used in filters). So I’m not sure whether it’s a very useful example if we’re discussing the behavior of more generic macros/procedures in filters.

I may be missing something, though. I hope you can clarify!

Edit: In case anyone is trying to solve this issue for now in particular, the format operator lets us do this already:

<$let date-format="YYYY0MM0DD">
{{{ [<now [UTC]YYYY0MM0DD0hh0mm0ssXXX>format:date<date-format>] }}}
</$let>

Thanks for your feedback and I could have given more details including differentiating between macros like now and procedures, and in fact there will be procedures this will not work for, although there are many that would.

  • but I wanted to keep it open to peoples imagination.
  • I know the the items “we cant” dont work but ask I what if they did.

It is often mentioned that all of these are in fact forms of variables and the recent development of the function shows how we can extend the oportunities.

  • if you have used functions as variables, filters and custom operators you get a hint of the possibilities.

I dont think what I proposed is imposible perhaps just improbable for example {{{ [[my.proc],[K],[J],[L]] }}} would;

  • evaluate the procedure after providing the parameters to it.
  • the parameters can be any valid variable or reference or literal you can use in a filter.
  • the output is then a string/title that the filter can subsequently respond to.
  • sure you could have procedures who’s output in a filter is inappropriate but there are many that would be powerful.

I guess this is the part I’m struggling with. I tend to use functions and procedures quite differently, as I tried to outline above, and off the top of my head I can’t think of any that would be both simple enough to use meaningfully in a filter and unable to be rewritten as a function - other than the now macro you mentioned. On the other hand, I do use hundreds of procedures whose output would be inappropriate for a filter. So I was hoping you could provide more examples in which a procedure and only a procedure would work.

I think I’d also worry about further blurring the line between functions and macros/procedures (it’s difficult for new users to grok already), and about the potential performance implications of wikifying procedures during filter evaluation (as we’ve historically been warned to avoid $wikify whenever possible).

The issue with the now as much as any future macros is we can pass parameters to it beyond literals. So as it stands we are limited when it comes to any macros OR function we may want to use in a filter and programmatically pass a parameter.

  • Another example is possibly the issue discussed here Converting a date from local time to UTC
  • I am keen to develop more sophisticated list/set handling where the list is stored in a variable, and suspect this may help here.
  • We could look through all core macros to see if any have an output suitable for use in a filter.
  • I am confident I can find some other examples.

I suppose my argument is this is an unnecessary limitation that constrains our opportunity to pass parameters in a filter to only functions at this point.

  • This may be an approach to overcome the need to wikify procedures before using their result in a filter. Just as a function is evaluated before the filter it is in.
  • Of course as is true already, the caveat is if your macro/procedure generates garbage, the filter using it will generate garbage.

[Post Script]
We could use the old define substitution (deprecated) or the new substitute operator, or backtick attributes to construct a filter, that is then used eg to give the parameter <now TZD> for example.

  • but hay this is seriously messy.