drools.js: Towards a Polyglot Drools on GraalVM (with Bonus Tech-Lead Prank)
Blog: Drools & jBPM Blog
Different programming languages are better for different purposes. Imagine how hard would it be to query a database using an imperative language: luckily, we use SQL for that. Now, imagine how useless would a rule engine be, if defining rules were not convenient! This is the reason why Drools comes with its own custom language, the DRL. The Drools Rule Language is in a so-called domain-specific language, a special-purpose programming language specifically designed to make interaction with a rule engine easier.
In particular, a rule is made of two main parts, the condition and the consequence.
The condition is a list of logic predicates, usually pattern matches, while the consequence is written using an imperative language, usually Java.
An Abstract Rule Engine
Rules are what really make a rule engine. After all, that’s what a rule engine does: processing rules. Thus, it might sound kind of logical for the engine to be a bit entangled with the language for rule definitions. Our engine is not specially tied to the DRL; but it used to.
In the last year or so, we spent a lot of time unbundling the innards of the DRL from the guts of the Drools core. The result of this effort is what we called the Canonical Model
; that is, an abstract representation of the components that make up a rule engine, including rule definitions. Incidentally, this also paved the way for supporting GraalVM
and the Quarkus
framework; but our goal was also different. We wanted to abstract our engine from the rule language
Internally, the DRL is now translated into the canonical representation; but, as we said previously, this canonical model is described using Java code. While this representation is not currently intended to be hand-coded, it is very possible to do so. The following is a simple rewriting of the previous DRL rule.
As you can see, although the rule definition is now embedded
in a Java “host” language, it still shows the main features of a DRL definition, namely, the logic condition
and the imperative consequence
(introduced by the on…execute
pair) In other words, this is a so-called embedded or internal domain-specific language
A small disclaimer applies: the code above works, but our translator takes extra steps for best performance, such as introducing indexes. In fact, one of the reasons why we do not intend this API for public consumption is that, currently, a naive rewrite like this may produce inefficient rules.
A Polyglot Automation Platform
As part of our journey experimenting with our programming model, we wanted to see whether it was feasible to interact with our engine using different programming languages. DRL aside, the canonical model rule definition API is pure-Java.
But GraalVM is not
only a tool to generate native binaries
: in fact, this is only one
of the capabilities of this terrific project. GraalVM is, first and foremost, the one VM to rule them all
: that is, a polyglot
runtime, with first-class support for both JVM languages and many other dynamic programming languages, with a state-of-the-art JIT
compiler, that easily compares or exceeds the performance of the industry standards
makes it terribly easy to write your own, and fine-tuning it to perfection.
And here’s a picture of Mario screaming in fear at the monster we have created
Jokes aside, this experiment is a window over one of the many possible futures of our platform. The world of application development today is polyglot. We cannot ignore this, and we are trying to understand how to reach a wider audience with our technologies, be it our rule engine, or our workflow orchestration engine; in fact, we are doing the same experiments with other parts of the platform, such as jBPM.
jBPM provides its own DSL for workflow definition. Although this is, again, work in progress, it shows a lot of promise as well. Behold: jbpm.js!
The DRL has served its purpose for a very long time, but we are already providing different ways to interact with our powerful engine, such as DMN and PMML; but power users will always want to reach for finer tuning and write their own rules.
The canonical model API is still a work-in-progress, and, above all, an internal API that is notintended for human consumption; but, if there is enough interest, wedo plan to work further to provide a more convenient embedded DSL for rule definition. Through the power of GraalVM, we will be able to realize an embedded DSL that is just as writable in Java as any other language that GraalVM supports.