Skip to content

Allow VariableReference as NamedArgument value#379

Open
eemeli wants to merge 1 commit intomainfrom
variable-named-args
Open

Allow VariableReference as NamedArgument value#379
eemeli wants to merge 1 commit intomainfrom
variable-named-args

Conversation

@eemeli
Copy link
Copy Markdown
Member

@eemeli eemeli commented Jan 2, 2026

This proposed syntax change would require the release of a new Fluent version, probably 1.1. It's forwards-incompatible, i.e. while all Fluent 1.0 content is valid Fluent 1.1, not all Fluent 1.1 content would be considered valid by a Fluent 1.0 processor.

Effectively, this would allow for usage like:

-term = the { $foo } term
msg-1 = This message includes { -term(foo: $term) }.
msg-2 = This message formats { NUMBER($n, minimumFractionDigits: $fd) }.

Not all inline expression values are supported as named arguments, so e.g. { -term(foo: -bar) } would continue to be a syntax error. My sense is that the strong, active desire is only for variable references, and that other uses are much more limited.

I'll be sumitting PRs for fluent.js and python-fluent to showcase the impact on implementations. From #325 I gather that fluent-rs might already support this, or that it's likely to be relatively straightforward to add there.

We'll need to consider carefully how to handle this in Pontoon, as we may need a per-project configuration of the supported Fluent version, or we need a solution for #208.

In Firefox, we'll need to review the capabilities of the fluent-rs version we're using.

@juliancoffee
Copy link
Copy Markdown

juliancoffee commented Mar 24, 2026

-creature-singular = { $creature ->
   [bonedragon] Bone Dragon
   [griffin] Griffin
   *[other] ??
 }
 
-creature-plural = { $creature ->
   [bonedragon] Bone Dragons
   [griffin] Griffins
   *[other] ??
}

# … Hundreds more ... for each

battle-log-attack-perish =
    { $attacker_count ->
        [one] The { -creature-singular(creature: $attacker-name) } does
       *[other] The { -creature-plural(creature: $attacker-name) } do
    } { $damage_points } damage. { $perish_count ->
        [one] One { -creature-plural(creature: $defender_name) } perishes.
       *[other] { $defender_count } { -creature-plural(creature: $defender_name) } perish.
    }

I believe this also enables something like this from #80 (comment), although in a bit roundabout way ^^'
But with tooling supporting asymmetric terms (not all do, I know Weblate doesn't support that WeblateOrg/weblate#9895), this should be doable for all the languages

Resulting in:

The Bone Dragon does 46 damage. 2 Griffins perish.
 The Griffin does 46 damage. 2 Griffins perish.

But I haven't tested it yet, just judging from an example.

To quote from the same issue:

I think we should do this, the use-cases look good enough. Localizers' life will be hard in these cases, but less hard than with the alternative.

@juliancoffee
Copy link
Copy Markdown

juliancoffee commented Mar 24, 2026

Or even something like that, from the same issue?

-creature-genus = { $creature ->
    [elf] Maskulinum
    [fairy] Femininum
    *[other] ??
}

-creature-akkusative = { $creature ->
   [fairy] Fee
   [elf] Elfen
}

you-see =
    Du siehst { -creature-genus(creature: $object) ->
       *[Maskulinum] einen { -creature-akkusative(creature: $object) }
        [Femininum] eine { -creature-akkusative(creature: $object) }
        [Neutrum] ein { -creature-akkusative(creature: $object) }
    }.

Even if the original version is prettier, because you can pack everything together.
#80 (comment)

I guess you can do it with selectors, too?

-creature-db = { $creature ->
     [elf] { $attr -> {
         [singular] Elf
         [plural] Elfen
         [nominativ] Elf
         [akkusativ] Elfen
         [genus] Maskulinum
         *[other] ??
     }
     [fairy] { $attr -> {
         [singular] Fee
         [plural] Feen
         [nominativ] Fee
         [akkusativ] Fee
         [genus] Femininum
         *[other] ??
     }
}

you-see =
    Du siehst { -creature-db(creature: $object, attr: "genus") ->
       *[Maskulinum] einen { -creature-db(creature: $object, attr: "akkusativ" }
        [Femininum] eine { -creature-db(creature: $object, attr: "akkusativ" }
        [Neutrum] ein { -creature-db(creature: $object, attr: "akkusativ" }
    }.

@eemeli
Copy link
Copy Markdown
Member Author

eemeli commented Mar 25, 2026

-creature-singular = { $creature ->
   [bonedragon] Bone Dragon
   [griffin] Griffin
   *[other] ??
 }
 
-creature-plural = { $creature ->
   [bonedragon] Bone Dragons
   [griffin] Griffins
   *[other] ??
}

# … Hundreds more ... for each

battle-log-attack-perish =
    { $attacker_count ->
        [one] The { -creature-singular(creature: $attacker-name) } does
       *[other] The { -creature-plural(creature: $attacker-name) } do
    } { $damage_points } damage. { $perish_count ->
        [one] One { -creature-plural(creature: $defender_name) } perishes.
       *[other] { $defender_count } { -creature-plural(creature: $defender_name) } perish.
    }

This doesn't work for languages with more than two plural forms, and it's mixing up terms that should be translated separately. You should instead do something like:

creature-bonedragon = { $count ->
    [one] Bone Dragon
   *[other] Bone Dragons
 }
 
creature-griffin = { $count ->
    [one] Griffin
   *[other] Griffins
}

battle-log-attack-perish =
    { $attacker_count ->
        [one] The { $attacker } does { $damage_points } damage.
       *[other] The { $attacker } do { $damage_points } damage.
    } { $perish_count ->
        [1] One { $defender } perishes.
       *[other] { $defender_count } { $defender } perish.
    }

where $attacker and $defender are separately formatted creature-* strings.

@juliancoffee
Copy link
Copy Markdown

juliancoffee commented Mar 25, 2026

where $attacker and $defender are separately formatted creature-* strings.

Yep, that's what we do right now 😅

As for that

This doesn't work for languages with more than two plural forms, and it's mixing up terms that should be translated separately. You should instead do something like:

Yes, obviously. That's why I said that it would require allowing different languages define their own terms.
So it could be -creature-one, -creature-few, -creature-other for all number variants specific language needs. Even if round-trip via formatting is probably a better solution.

And I agree that it's rather clunky, that's why I showed second example with one big selector.
And example with cases and genus wouldn't work that way, because only that language can say what gender certain creature has.
Not to mention cases, which are wildly different in different languages.

I'm not sure what's the best way to handle more complex situations, especially if you need gender, plurality and grammatical case all at the same time.

But I still wanted to give examples what seems possible with this MR.
Sorry, if it was more of a noise ^^'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

forwards incompatible Old parsers won't parse newer files. syntax

Projects

None yet

2 participants