ezylang / EvalEx

EvalEx is a handy expression evaluator for Java, that allows to evaluate simple mathematical and boolean expressions.
https://ezylang.github.io/EvalEx/
Apache License 2.0
1k stars 271 forks source link

Max function for more than 2 arguments #48

Closed qwert2003 closed 9 years ago

qwert2003 commented 9 years ago

max(3.0, 2.0, 1.0) returns 2.0. The expected answer would be 3.0. min(1.0, 2.0, 3.0) returns 2.0. The expected answer would be 1.0.

Currently max expects two arguments. If more arguments are passed to the function, the last two are taken (no error). This is not obvious.

Could max (and min) be extended to accept any number of arguments (>1)?

squeek502 commented 9 years ago

Does it not throw an exception? Seems like this pull request should make max(3.0, 2.0, 1.0) throw an exception.

Anyway, to get around this issue, you could try nesting your max/min calls like so: max(3.0, max(2.0, 1.0))

qwert2003 commented 9 years ago

Indeed the current source code does throw an exception if the number of arguments other than expected. That is an important improvement! My code base was out of date. Thanks for pointing to it.

Issue

max(3.0, 2.0, 1.0) throws an exception. The expected answer would be 3.0. min(1.0, 2.0, 3.0) throws an exception. The expected answer would be 1.0.

Could max / min be extended to accept any number of arguments (>0)?

Motivation

EvalEx is used by the drawing tool Drawj2d. The tool provides the tcl-like programming language hecl, which lacks of an expression evaluator expr (compared to tcl). Drawj2d provides expr using EvalEx. Using the current EvalEx source, calling drawj2d I'll get:

~> drawj2d
puts [expr max(3.0,2.0,1.0)]
Hecl exception: {ERROR {Exception of type class com.udojava.evalex.Expression$ExpressionException: Too many numbers or variables} 1}
Error occurred. Check for error messages.

I'd obviously prefer what tcl does:

    ~> tclsh
    % puts [expr max(3.0,2.0,1.0)]
    3.0

While the example above is somehow specific, I generally think a mathematical expression evaluator should provide a maximum / minimum function for a list of values.

Question

Does EvalEx provide a way to implement user functions with variable number of arguments?

squeek502 commented 9 years ago

Does EvalEx provide a way to implement user functions with variable number of arguments?

Not currently, no. @uklimaschewski would know more, but from what I can tell, it's not currently possible because functions and their parameters are parsed independently--it doesn't keep track of which parameters belong to which function. Each function just pops its defined number of parameters off the stack.

Adding support for functions with variable numbers of arguments would take at least some restructuring.

uklimaschewski commented 9 years ago

I'll leave that open as an enhancement. It should not be a too dramatic code change, a quick google search showed up with a possibly working solution here:

Extension to the ‘Shunting Yard’ algorithm to allow variable numbers of arguments to functions

Probably, the currently fixed number of arguments in the function definition has to be changed, e.g. a -1 to flag a variable number of arguments. Backward compatibility is important here!

It will need some changes in the expression validator, too (see #47 ).

qwert2003 commented 9 years ago

Thanks a lot!