Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split named arguments before evaluation #14

Merged
merged 4 commits into from
Dec 27, 2024

Conversation

Derugon
Copy link
Contributor

@Derugon Derugon commented Dec 10, 2024

Motivation

The #ueswitch parser function and various list parser functions accept named arguments. Arguments are provided to the parser functions as preprocessor nodes, and all these functions analyze an argument node N the same way:

  1. Evaluate N into a string "k=v", then
  2. Split "k=v" into a key and value.

Then, both of these values may be trimmed, unescaped, or post-processed in any other way.

The #switch parser function analyze an argument node N the other way around:

  1. Extract from N a key node K and value node V.
  2. Evaluate both K and V into strings.

Benefits of the #ueswitch approach

= escaping

With the #ueswitch approach, the full key/value pair can be the result of a single computation, e.g. the following expressions give the same result:

{{#ueswitch: X | {{#if: Y | a=1 | b=2 }} }}
{{#if: Y | {{#ueswitch: X | a=1 }} | {{#ueswitch: X | b=2 }} }}

It can be useful to simplify expressions in some edge cases, but I assume this is a pretty niche usage.

Benefits of the #switch approach

= escaping

Assume both #switch and #ueswitch are given a case a {{=}} b = c.

Because the #switch approach relies on the preprocessor tree to split argument names from values, #switch assumes the key is a = b and the value is c, while #ueswitch splits evaluated argument strings and assumes the key is a and the value is b = c.

This may be seen as a strange inconsistency for the #ueswitch function since keys can be any wikitext, but on the other hand this is not a real issue with list functions since parameter keys are known strings (and none of these contain any = symbol).

Laziness

With the #switch approach, after splitting we get a key node K and value node V, so we can evaluate the key node without evaluating the value one. This allows (and is necessary) to lazily evaluate keys and values of named parameters, as introduced for #ueswitch in #3.

Proposed changes

Change the way #ueswitch and the list parser functions (with ParserPower::arrangeParams) analyze their arguments to use the same approach as #switch.

This PR does not propose to change which parameters are lazily evaluated, only the evaluation process, so the = escaping differences listed above should be the only end-user differences and breaking changes of this PR.

What other extensions do

In other parser function extensions, both approaches are used, but the ParserPower one is mostly used in extensions (I am aware of) that manage named arguments.

  • Some extensions would not benefit a lot from the other approach (like Cargo or PageForms) since all parameters will be evaluated and the laziness capabilities would be mostly irrelevant.
  • Some other extensions (like DPL3) may have a use for laziness. I can't find any discussion about this matter, so maybe the question never really arose.
  • A few extensions use the #switch approach (like GeoData, RandomSelection, or ReplaceSet), but they mostly do not use any laziness.

The 1st argument is always evaluated, so we still have to check whether arguments are strings or PPNodes.
Only the 1st argument may be already expanded, so no need to check for the type of every argument
@alex4401 alex4401 merged commit 34af568 into wiki-gg-oss:master Dec 27, 2024
@Derugon Derugon deleted the arg-split branch December 27, 2024 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants