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

Ability to parametrise arguments #268

Open
juliancoffee opened this issue Aug 6, 2022 · 6 comments
Open

Ability to parametrise arguments #268

juliancoffee opened this issue Aug 6, 2022 · 6 comments

Comments

@juliancoffee
Copy link
Contributor

juliancoffee commented Aug 6, 2022

Blocked on projectfluent/fluent#80


As far as I know in Fluent we can't parametrise arguments. In a sense that this code will be impossible to parse.

skeleton = {$case ->
  [genitive] Skeleton
  [possessive] by Skeleton
}
cultist = {$case ->
  [genitive] Cultist
  [possessive] by Cultist
}
shoot = { $victim } has be shoot { $attacker(case: "possessive") }

This is obviously not a problem for English, but it is a problem for other languages with grammatical cases, for example, Slavic ones.
(I translated the bear was killed by another bear to Polish and got niedźwiedź został również zabity przez innego niedźwiedzia. You can see the difference between niedźwiedź and niedźwiedzia)

So to solve it, I was thinking about adding EVAL function, which would take its first parameter as a term and pass args to it.
shoot = { $victim } has been shoot { EVAL($attacker, case: "possessive") }

Doing it externally would require allocating the bundle on the heap so we can capture its address in closure. But the reference to the bundle is always here when we call function, as all functions are stored in the bundle, so this may be some built-in.

@juliancoffee
Copy link
Contributor Author

So, I was trying to create a function for EVAL but lifetimes were stronger than me :)
But I was able to add another branch to ResolveValue impl (and WriteValue) and it seems to work.

            Self::FunctionReference {
                id: ast::Identifier { name: "EVAL", ..},
                arguments,
            } => {
                let (resolved_positional_args, resolved_named_args) =
                    scope.get_arguments(Some(arguments));

                let key = if resolved_positional_args.len() == 1 {
                    match &resolved_positional_args[0] {
                        FluentValue::String(s) => s,
                        _ => return FluentValue::Error,
                    }
                } else {
                    return FluentValue::Error
                };

                let msg = if let Some(msg) = scope.bundle.get_message(&key) {
                    msg
                } else {
                    return FluentValue::Error
                };

                let pattern = if let Some(pat) = msg.value() {
                    pat
                } else {
                    return FluentValue::Error
                };

                FluentValue::String(scope.bundle.format_pattern(
                    pattern,
                    Some(&resolved_named_args),
                    &mut Vec::new()
                ).into_owned().into())
            }

@juliancoffee
Copy link
Contributor Author

@zbraniecki how feasible would it be to get something like that?

@juliancoffee
Copy link
Contributor Author

Oh, I just found this proposal which is basically does the same thing projectfluent/fluent#80

@zbraniecki
Copy link
Collaborator

Yep, this is being now added to MessageFormat 2.0 (successor of Fluent) and may be backported to Fluent - see projectfluent/fluent#349

What I'd be against is adding a Rust only extension to Fluent feature/syntax. If you want it in Fluent, please suggest it in https://github.com/projectfluent/fluent repo and let @eemeli decide (he's the maintainer of the spec now).

@juliancoffee
Copy link
Contributor Author

juliancoffee commented Aug 7, 2022

Makes sense, yes. Keeping this open, because in theory this problem is still not solved.

@juliancoffee juliancoffee changed the title [Question] Make EVAL function (or builtin?) [Feature Request] Ability to parametrise arguments Aug 7, 2022
@juliancoffee
Copy link
Contributor Author

(Also I think that using an idea from projectfluent/fluent#80 is better than ad-hoc function, so renamed this issue)

@gregtatum gregtatum changed the title [Feature Request] Ability to parametrise arguments Ability to parametrise arguments Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants