Thanks Edmond for the feedback, and Alessio as well who replied also.

I know all of the expressions at once, although they can change as the 
application runs, so it is possible to combine them into one class, but I would 
then be constructing source code myself, which is a little bit of a concern, 
and having to call methods dynamically via reflection (rather than through an 
interface like I’d do if each one turned into a Closure), which ups the 
complexity compared to SPEL. The expressions may also repeat, which is 
something I should consider (I know some of the Groovy scripting utility 
classes will “cache” the code and handle this).

The data is a set of business rules tables, today we have something like this, 
let’s say I have a store selling mobile phones and I’m offering conditional 
discounts that can change on the fly.

Attribute, Low_value, high_value, discount%
Vendor, Apple, , 25%
Vendor, Samsung, , 20%
Total_price, 500, 1000, 10%

You can see such a table is awkward (because it represents the expressions 
‘vendor  == Apple’ gives 25% discount and ‘price >= 500 && price <= 1000’ gives 
10% discount in the same format). I’m very limited to the conditions I add, and 
if I want to add different types of conditions, such as don’t allow selling 
Apple and Samsung phone on same mobile plan, it can get very complicated (many 
columns) to impossible very quick. We’re not quite to the point where we want 
to build some dedicated microservice or ability to hotswap JARs on the fly yet 
to allow changing this quickly without redeploy, but beyond the point where 
straight tables can get us. So I am looking to see if we can use a simple 
expression language. And we use Groovy very extensively today, as well as 
Spring.

I think the conclusion is that I should just test the performance to see how it 
works out and how well it will scale over time. There is obvious benefits in 
that Groovy allows “unlimited” potential compared to SPEL. But “unlimited” 
could get us into trouble because I don’t want to be making REST API calls and 
defining classes in an expression 😊, so do I really need anything more than 
what SPEL gives to me. I know in Groovy I do like the possibility to consider 
command chains that read better than SPEL: “when vendor is ‘Apple’” -> 
when(vendor).is(‘Apple’)

When I think about SPEL it actually should be efficient, too. I realize 
template systems like Thymeleaf are based on this and evaluate many expressions 
to render a single page. Likewise Groovy server pages / Grails does it not do a 
similar thing? But maybe all of those closures get mapped to a single class 
like JSP does.

Jason Winnebeck



Sensitivity: Internal
From: Edmond Kemokai <ekemo...@gmail.com>
Sent: Tuesday, October 27, 2020 11:08 AM
To: users@groovy.apache.org
Subject: Re: Groovy as expression parser

CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you recognize the sender and know the content 
is safe.

Hi Jason,

I am working on a product that uses Groovy as a dynamic scripting language 
within a Java web app and have been contending with this concern as well.

Some things to consider:

Is it possible to consolidate these 100s of expressions into a fully qualified 
named class?
With this approach you could then create a singleton of such a class and retain 
that in memory via the java web app session. You could then map the expression 
evaluation to some sort of naming scheme (basically a bunch of if/else blocks), 
or just map each expression to a unique function.

This of course takes away some of the flexibility of being able to run 
arbitrary code.

As to the overhead of constantly compiling these expressions, I can't speak to 
actual numbers but there is definitely an overhead, you'll probably need to do 
your own jvm performance profiling to determine whether it is an actual problem.

In my case I am using the java scripting API to evaluate Groovy code, with that 
API it is possible to obtain a compiled instance of the code ( 
javax.script.CompiledScript ) that can be rerun multiple times without 
recompiling. This is an alternative way to address compilation overhead.

Hope this helps.

Regards
Edmond


Reply via email to