How to convert String to Function in Java? - java

There is a question with the same title like this on stackoverflow here, but I wanted to ask if it is possible to do something similar to this in Java.
I wanted to make something similar to desmos, just like that guy did in Javascript,but i want to make it in Java using lwjgl 2. I am new to Java and I'd like to know if it is possible to convert a piece of string into a method. Is it possible?
I have looked for possible options and I found out that your can make your own Java eval() method. But I don't want to replace the x in the string for every pixel of the window-width.
Thanks in advance.

What you need is an engine/library that can evaluate expressions, defined as string at execution time. If you wrap the evaluation code into function call (e.g. lambda function), you will get what you need.
Option 1: You can use exp4j. exp4j is a small footprint library, capable of evaluating expressions and functions at execution time. Here is an example:
Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.variables("x", "y")
.build()
.setVariable("x", 2.3)
.setVariable("y", 3.14);
double result = e.evaluate();
Option 2: You can use the Java's script engine. You can use it to evaluate expressions defined, for example, in JavaScript:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("sin(1.25)");
Option 3: Compile to native Java. With this approach, you use template to generate .java file with a class that contains your expression. Than you call the Java compiler. This approach has the drawback that has some complexity in the implementation and some initial latency (until the class is compiled), but the performance is the best. Here are some links to explore:
Create dynamic applications with javax.tools
In particular javax.tools.Compiler
Note of Caution Whatever approach you chose, have in mind that you need to think about the security. Allowing the user to enter code which can be evaluated without security restrictions could be very dangerous.

Related

How to store mathematical formula in MS SQL Server DB and interpret it using JAVA?

I have to give the user the option to enter in a text field a mathematical formula and then save it in the DB as a String. That is easy enough, but I also need to retrieve it and use it to do calculations.
For example, assume I allow someone to specify the formula of employee salary calculation which I must save in String format in the DB.
GROSS_PAY = BASIC_SALARY - NO_PAY + TOTAL_OT + ALLOWANCE_TOTAL
Assume that terms such as GROSS_PAY, BASIC_SALARY are known to us and we can make out what they evaluate to. The real issue is we can't predict which combinations of such terms (e.g. GROSS_PAY etc.) and other mathematical operators the user may choose to enter (not just the +, -, ×, / but also the radical sigh - indicating roots - and powers etc. etc.). So how do we interpret this formula in string format once where have retrieved it from DB, so we can do calculations based on the composition of the formula.
Building an expression evaluator is actually fairly easy.
See my SO answer on how to write a parser. With a BNF for the range of expression operators and operands you exactly want, you can follow this process to build a parser for exactly those expressions, directly in Java.
The answer links to a second answer that discusses how to evaluate the expression as you parse it.
So, you read the string from the database, collect the set of possible variables that can occur in the expression, and then parse/evaluate the string. If you don't know the variables in advance (seems like you must), you can parse the expression twice, the first time just to get the variable names.
as of Evaluating a math expression given in string form there is a JavaScript Engine in Java which can execute a String functionality with operators.
Hope this helps.
You could build a string representation of a class that effectively wraps your expression and compile it using the system JavaCompiler — it requires a file system. You can evaluate strings directly using javaScript or groovy. In each case, you need to figure out a way to bind variables. One approach would be to use regex to find and replace known variable names with a call to a binding function:
getValue("BASIC_SALARY") - getValue("NO_PAY") + getValue("TOTAL_OT") + getValue("ALLOWANCE_TOTAL")
or
getBASIC_SALARY() - getNO_PAY() + getTOTAL_OT() + getALLOWANCE_TOTAL()
This approach, however, exposes you to all kinds of injection type security bugs; so, it would not be appropriate if security was required. The approach is also weak when it comes to error diagnostics. How will you tell the user why their expression is broken?
An alternative is to use something like ANTLR to generate a parser in java. It's not too hard and there are a lot of examples. This approach will provide both security (users can't inject malicious code because it won't parse) and diagnostics.

Java - Efficient evaluation of user-input math functions (preparation possible, existing variables)

In a Java program which has a variable t counting up the time (relative to the program start, not system time), how can I turn a user-input String into a math formula that can be evaluated efficiently when needed.
(Basically, the preparation of the formula can be slow as it happens Pre run-time, but each stored function may be called several times during run-time and then has to be evaluated efficiently)
As I could not find a Math parser that would keep a formula loaded for later reference instead of finding a general graph solving the equation of y=f(x), I was considering to instead have my Java program generate a script (JS, Python, etc) out of the input String and then call said script with the current t as input parameter.
-However I have been told that Scripts are rather slow and thus impractical for real-time applications.
Is there a more efficient way of doing this? (I would even consider making my Java application generate and compile C-code for every user input if this would be viable)
Edit: A tree construct does work to store expressions, but is still fairly slow to evaluate as from what I understand I would need to turn it into a chain of expressions again when evaluating (as in, traverse the tree object) which should need more calls than direct solving of an equation. Instead I will attempt the generation of additional java classes.
What I do is generate Java code at a runtime and compile it. There are a number of libraries to help you do this, one I wrote is https://github.com/OpenHFT/Java-Runtime-Compiler This way it can be as efficient as if you had hand written the Java code yourself and if called enough times will be compiled to native code.
Can you provide some information on assumed function type and requested performance? Maybe it will be enough just to use math parser library, which pre-compiles string containing math formula with variables just once, and then use this pre-compiled form of formula to deliver result even if variables values are changing? This kind of solutions are pretty fast as it typically do not require repeating string parsing, syntax checking and so on.
An example of such open-source math parser I recently used for my project is mXparser:
mXparser on GitHub
http://mathparser.org/
Usage example containing function definition
Function f = new Function("f(x,y) = sin(x) + cos(y)");
double v1 = f.calculate(1,2);
double v2 = f.calculate(3,4);
double v3 = f.calculate(5,6);
In the above code real string parsing will be done just once, before calculating v1. Further calculation v1, v2 (an possible vn) will be done in fast mode.
Additionally you can use function definition in string expression
Expression e = new Expression("f(1,2)+f(3,4)", f);
double v = e.calculate();

Should I change to scala to create a system with rewrite rules?

I have some classes that I developed that I am using in a Android application. I have about 6-7 classes in that core, some of them are abstract classes with abstract methods. Those classes were created to provide a API to extend my Android Application.
Now I want to create an extensible system that accepts rewrite rules. Those rules are useful to replace some components at runtime. Imagine a system with mathematical operations where you see all the sums, multiplications, etc. Now you can zoom out and I want to simplify some operations dependending on the zoom level.
My system was built in java, but I belive that scala, with pattern matching, will simplify my problem. However, everytime I look at scala I see a lot of time I have to spend and a lot of headches configuring IDEs...
My classes are built to create structures like this one:
I want to be able to write rules that create a block that contains other blocks. Something like:
Integer Provider + Integer Provider -> Sum Provider
Sum Provider + Sum -> Sum Provider
Rules can be created by programmers. Any element of my structure can also be built by programmers. I don't know if scala simplifies this rule engine system, but I know that this engine, in java, can be boring to build (probly a lot of bugs will be created, I will forget some cases, etc).
Should I change all my system to scala? Or there is away to use only this feature of scala? Does it worth it?
PS: For more information on the structure please see this post at User Experience.
Yes, it is easy to write such rules in Scala, and, in fact, there have been some questions on Stack Overflow related to rule rewriting systems in Scala. Also, there are some libraries that may help you with this, related to strategic programming and nlp, but I haven't used them, so I can't comment much.
Now, I don't know exactly where these classes are coming from. If you are parsing and building them, the parser combinator library can trivially handle it:
sealed trait Expr { def value: Int }
case class Number(value: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr { def value = e1.value + e2.value }
object Example extends scala.util.parsing.combinator.RegexParsers {
def number: Parser[Expr] = """\d+""" ^^ (n => Number(n.toInt))
def sum: Parser[Expr] = number ~ "+" ~ expr ^^ {
case n ~ "+" ~ exp => Sum(n, exp)
}
def expr: Parser[Expr] = sum | number
}
If you have these classes in some other way and are applying simplifications, you could do it like this:
def simplify(expr: List[Expr]): Expr = expr match {
case expr :: Nil =>
List(expr) // no further simplification
case (n1: NumberProvider) :: Plus :: (n2: NumberProvider) :: rest =>
simplify(SumProvider(n1, n2) :: rest)
case (n: NumberProvider) :: Plus :: (s: SumProvider) :: rest =>
simplify(SumProvider(n, s) :: rest)
case (s: SumProvider) :: Plus :: (n: NumberProvider) :: rest =>
simplify(SumProvider(s, n) :: rest)
case other => other // no further simplification possible
}
The important elements here are case classes, extractors and pattern matching.
As a lone developer, Scala is expressive and powerful, so once mastered can be satisfying to write less and do more -- less boilerplate code, more compact idioms.
However, the power of Scala does come at a cost: it is a totally different language, with different (and I'd say more complex) idioms and syntax from Java. Java was designed to be intentionally simple, with the idea being that in larger organizations with more code being shared among developers, explicitness and syntax simplicity are more valuable than brilliantly concise code.
Java made an intentional choice to provide a smaller toolset to make it as quick and easy as possible for one developer to pick up where another left off, so in that sense it's geared towards team development. Scala however gives you a bit more rope to make concise but less immediately obvious constructs, which can be a minus for large enterprise environments.
Currently, Scala also has a smaller developer pool than Java, which means fewer examples and a smaller talent pool if you ever intend to hire a development team.
But as a lone developer on a solo project or in a small tight-knit team, Scala can be fun and fast to code with once you get over the significant learning hump.
If you are switching to Scala switch to it for everything you can. There is hardly a point in using Java.
Is it worth the investment? From what one can read on the web (and my own impression) you won't become faster with Scala, but you will learn a lot.
So if you are only concerned with development speed: ignore Scala.
If you want to learn: Scala is a great choice as the next language to learn and use.

Looking for an expression evaluator

I'm looking for an evaluator for simple condition expressions.
Expressions should include variables (read only), strings, numbers and some basic operators.
E.g. expressions something like this:
${a} == "Peter" && ( ${b} == null || ${c} > 10 )
So far i implemented a rather "magical" parser that returns an AST that i can evaluate, but i can't believe that i'm the first one to solve that problem.
What existing code could i use instead?
Have you looked at MVEL? They provide a getting started guide and performance analysis.
Here's one of their simple examples:
// The compiled expression is serializable and can be cached for re-use.
CompiledExpression compiled = MVEL.compileExpression("x * y");
Map vars = new HashMap();
vars.put("x", new Integer(5));
vars.put("y", new Integer(10));
// Executes the compiled expression
Integer result = (Integer) MVEL.executeExpression(compiled, vars);
assert result.intValue() == 50;
Also (answering my own question) MVEL seems to provide some support for bytecode generation.
Other alternatives, culling from the above answers and my own:
Java Expression Parser (JEP) -- and note there is an old version available for free
Apache Commons JEXL
With regard to Rhino, here's a dude who did some arithmetic evaluation in that context (looks messy)
Sounds like JEXL might work well for you. Check out its syntax reference.
What about SPEL (Spring Expression Lang); http://static.springsource.org/spring/docs/3.0.x/reference/expressions.html
Why don't you use Rhino? It's a JavaScript engine already present inside the JDK.
It can evaluate whatever you like to write in JS.. take a look here
This simple recursive descent parser evaluates constants as named functions having no parameters.
A very simple and easy to use alternative with a lot of built in excel functions for string, date and number formatting.
The library also allows easy addition of custom functions. A lot of examples available on the git page. A simple example using variables
ExpressionsEvaluator evalExpr = ExpressionsFactory.create("LEFT(City, 3)");
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("City", "New York");
assertEquals("New", evalExpr.eval(variables));
Here is a little library I've worked on that supports expression evaluation (including variables, strings, boolean, etc...).
A little example :
String expression = "EXP(var)";
ExpressionEvaluator evaluator = new ExpressionEvaluator();
evaluator.putVariable(new Variable("var", VariableType.NUMBER, new BigDecimal(20)));
System.out.println("Value of exp(var) : " + evaluator.evaluate(expression).getValue());

JSTL/JSP EL (Expression Language) in a non JSP (standalone) context

Can anyone recommend a framework for templating/formatting messages in a standalone application along the lines of the JSP EL (Expression Language)?
I would expect to be able to instantiate a an object of some sort, give it a template along the lines of
Dear ${customer.firstName}. You order will be dispatched on ${order.estimatedDispatchDate}
provide it with a context which would include a value dictionary of parameter objects (in this case an object of type Customer with a name 'customer', say, and an object of type Order with a name 'order').
I know there are many template frameworks out there - many of which work outside the web application context, but I do not see this as a big heavyweight templating framework. Just a better version of the basic Message Format functionality Java already provides
For example, I can accomplish the above with java.text.MessageFormat by using a template (or a 'pattern' as they call it) such as
Dear {0}. You order will be dispatched on {1,date,EEE dd MMM yyyy}
and I can pass it an Object array, in my calling Java program
new Object[] { customer.getFirstName(), order.getEstimatedDispatchDate() };
However, in this usage, the code and the pattern are intimately linked. While I could put the pattern in a resource properties file, the code and the pattern need to know intimate details about each other. With an EL-like system, the contract between the code and the pattern would be at a much higher level (e.g. customer and order, rather then customer.firstName and order.estimatedDispatchDate), making it easier to change the structure, order and contents of the message without changing any code.
You can just use the Universal Expression Language itself. You need an implementation (but there are a few to choose from). After that, you need to implement three classes: ELResolver, FunctionMapper and VariableMapper.
This blog post describes how to do it: Java: using EL outside J2EE.
StringTemplate is a more lightweight alternative to Velocity and Freemarker.
I would recommend looking into Apache Velocity. It is quite simple and lightweight.
We are currently using it for our e-mail templates, and it works very well.
You can use Casper very similar to jsp and easy to use : Casper
The idea of using EL itself outside of Java EE was advocated by Ed Burns and discussed on The Server Side. Tomcats implementation ships in a separate JAR but I don't know if it can be used outside the server.
I would go for the Spring Expression language:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html
A few examples which demonstrate the power (the first two are from the documentation):
int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context);
String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context);
// weekday is a String, e.g. "Mon", time is an int, e.g. 1400 or 900
{"Thu", "Fri"}.contains(weekday) and time matches '\d{4}'
Expressions can also use object properties:
public class Data {
private String name; // getter and setter omitted
}
Data data = new Data();
data.setName("John Doe");
ExpressionParser p = new SpelExpressionParser();
Expression e = p.parseExpression("name == 'John Doe'");
Boolean r = (Boolean) e.getValue(data); // will return true
e = p.parseExpression("Hello " + name + ", how are you ?");
String text = e.getValue(data, String.class); // text will be "Hello John Doe, how are you ?"
You might want to look at OGNL which is the kind of library you are after. OGNL can be reasonably powerful, and is the expression language used in the WebWork web framework.
Re: Jasper and Juel being built for 1.5: And then I discovered RetroTranslator (http://retrotranslator.sourceforge.net/). Once retrotranslated, EL and Jasper works like a charm
Freemarker would do exactly what you need. This is a template engine with a syntax very similar to JSP :
http://freemarker.org/
AAh. Whereas with MessageFormat, I can do
Dear {0}. Your order will be dispatched on {1,date,EEE dd MMM yyyy}
where parameter #1 is a Date object and it gets formatted according to the pattern, there is no equivalent in EL.
In JSP, I would have used, perhaps, a format tag. In this standalone example, I am going to have to format the Date as a String in my code prior to evaluating the expression.

Categories