-
Notifications
You must be signed in to change notification settings - Fork 18
Home
- What is Opel?
- When it can be useful?
- Why use Opel instead of other languages?
- Feature list
- A Brief Example
Opel is a simple asynchronous expression language - or rather - a library which allows creating simple custom secure asynchronous expression languages.
Opel can be useful when you need simple customizable expression language, and you want to give it to your users. It will be a nice fit when asynchronous expression evaluation is desirable as it uses CompletableFuture as output as well as input.
Opel was created with security and asynchronism in mind.
We needed to give our users a possibility to configure the system using expression language, but without possibility of making harm to our system. In Opel you can add custom functions and values and limit method calls, creating very small language (DSL?) that fits your domain and exposes no dangerous features to users.
Also, we wanted expression evaluation to be a part of CompletableFuture's processing, and with Opel it is natural.
- primary math and string operations (i.e.
2+2*2
,'Hello' + 'world !'
) - relational and equality operators (i.e.
2 == 3
,2 > 1 != false
) - logic operators (i.e.
true && false
,false || true
) - simple map element access (i.e.
map.field
ormap['field']
) - simple list element access (i.e.
list[index]
) - object method calls (i.e.
'Hello, World!'.length()
) - if expressions (i.e.
if (2 > 3) 'a' else 'b'
) - defining local constant values (i.e.
val x = 2+2*2; x * x
) - registrable implicit conversions (i.e.
2 + '2'
or'Hello, World!'.myMethod()
) - registrable functions (i.e.
myFunction('Hello, World!')
) - registrable constant values (i.e.
'Hello, ' + WORLD_VALUE
)
When evaluating simple expressions, opel uses only OpelEngine
class and eval
method.
Remember that opel
always returns CompletableFuture.
OpelEngine engine = OpelEngineBuilder.create().build();
String expression = "2 * 3 + 4";
engine.eval(expression)
.whenComplete((result, error) -> System.out.println(result));
this expression is transformed to equivalent code:
CompletableFuture.completedFuture(2)
.thenCombine(CompletableFuture.completedFuture(3), (l, r) -> l * r)
.thenCombine(CompletableFuture.completedFuture(4), (l, r) -> l + r)
.whenComplete((result, error) -> System.out.println(result));
As you see, opel
efficiently hides boilerplate of the CompletableFuture API.