ISibboI / evalexpr

A powerful expression evaluation crate 🦀.
GNU Affero General Public License v3.0
320 stars 52 forks source link

Are multiple parameters for functions supported? #2

Closed ISibboI closed 5 years ago

ISibboI commented 5 years ago

No they are not. They can be defined, but there is no way to call a function with multiple arguments as of now.

sweihub commented 1 year ago

Will you reopen this issue, how can we implement a custom function to accept multiple parameters?

1 + f(a,b)

ISibboI commented 1 year ago

Functions can take a tuple, that looks like multiple parameters, but internally is just one. So the example you showed works today already, if your function f tales a tuple of length two as parameter.

On Wed, 16 Aug 2023, 11.10 Alex Wei, @.***> wrote:

Will you reopen this issue, how can we implement a custom function to accept multiple parameters?

1 + f(a,b)

— Reply to this email directly, view it on GitHub https://github.com/ISibboI/evalexpr/issues/2#issuecomment-1680158440, or unsubscribe https://github.com/notifications/unsubscribe-auth/AASATXVMQFLFWW5NKCT7IYDXVR6AZANCNFSM4G7PFJCA . You are receiving this because you modified the open/close state.Message ID: @.***>

sweihub commented 1 year ago

OK, I checked again your example avg(2, 4) that solved the issue, thanks! I left it here for later comers

Example to take multiple parameters with evalexpr

fn test_eval() -> anyhow::Result<(), anyhow::Error> {
    let mut context = HashMapContext::new();

    context.set_value("a".into(), 100.0.into())?;
    context.set_value("b".into(), 2.0.into())?;
    let _ = context.set_function(
        "f".into(),
        Function::new(|args| {
            let inputs = args.as_tuple()?;
            if let (Value::Float(a), Value::Float(b)) = (&inputs[0], &inputs[1]) {
                Ok(Value::Float(a + b))
            } else {
                Ok(Value::Float(0.0))
            }
        }),
    );

    let f = build_operator_tree("a * b + f(a, b)")?;
    let result = f.eval_with_context(&context)?;
    println!("result = {}", result);

    Ok(())
}
ISibboI commented 1 year ago

Great! Note that there is also as_fixed_length_tuple(2) (or so) that also checks if the length of the tuple is correct.

On Thu, 17 Aug 2023, 6.15 Alex Wei, @.***> wrote:

OK, I checked again your example avg(2, 4) that solved the issue, thanks! I left it here for later comers

Example to take multiple parameters with evalexpr

fn test_eval() -> anyhow::Result<(), anyhow::Error> { let mut context = HashMapContext::new();

context.set_value("a".into(), 100.0.into())?;
context.set_value("b".into(), 2.0.into())?;
let _ = context.set_function(
    "f".into(),
    Function::new(|args| {
        let inputs = args.as_tuple()?;
        if let (Value::Float(a), Value::Float(b)) = (&inputs[0], &inputs[1]) {
            Ok(Value::Float(a + b))
        } else {
            Ok(Value::Float(0.0))
        }
    }),
);

let f = build_operator_tree("a * b + f(a, b)")?;
let result = f.eval_with_context(&context)?;
println!("result = {}", result);

Ok(())}

— Reply to this email directly, view it on GitHub https://github.com/ISibboI/evalexpr/issues/2#issuecomment-1681547529, or unsubscribe https://github.com/notifications/unsubscribe-auth/AASATXX2TA3YUNQS7DQY67LXVWEF7ANCNFSM4G7PFJCA . You are receiving this because you modified the open/close state.Message ID: @.***>