Click to change color scheme

Notes on codes, projects and everything

Re-implementing a rule engine in Javascript (Introducing Ruler)

Sometimes, letting a piece of code evolving by itself without much planning does not usually end well. However I was quite pleased with a by-product of it and I am currently formalizing it. So the by-product is some sort of DSL for a rule engine that I implemented to process records. It started as some lambda functions in Python but eventually becomes something else.

A simple rule in the record processing script may be, if record A has fieldA with value X, then change fieldB to Y. The condition check rule, where fieldA has value of X can be written as

lambda record: record['fieldA'] == 'X'

This worked fine for a while, but when I tried to make work run concurrently Python refused to pickle lambda functions. So I had to restructure all these lambda functions into real functions, and use partial function to allow certain function parameters to be left empty. However, as the ruleset grows, I decided to further simplify it to something that can be represented in JSON.

["_equals", "fieldA", "X"]

The syntax itself very much resembles lisp, as I personally find it simple enough. While the implementation was not perfect (there’s no formalization or whatsoever done to the petit DSL), it did work well. Also since it could be represented in JSON then developing a web UI to populate it is possible, somehow.

Recently I am building a game that is somehow similar to game of life. While the hobby project is probably going to take forever to complete, I have just re-implemented the parser in Javascript as the game needs one. The API is not really finalized, and I am still trying to formalize the schema to make it feels consistent.

The script itself requires underscore.js, and currently recognizes some of the functions already. For instance, the previous case is now written as

["condition.Equal", "fieldA", "X"]

In order to chain multiple rules together, one could write

["boolean.And", ["condition.Equal", "fieldA", "X"], ["condition.Equal", "fieldB", "Y"]]

In order to parse this and turn it into a proper function

func = ruler.parse(["boolean.And", ["condition.Equal", "fieldA", "X"], ["condition.Equal", "fieldB", "Y"]])

Then, to execute it

func({fieldA: "X", fieldB: "Y"})

It should yield true.

The code is named Ruler, and the first draft of code can be found here, I will populate the README with more examples probably later today.

leave your comment

name is required

email is required

have a blog?

This blog uses scripts to assist and automate comment moderation, and the author of this blog post does not hold responsibility in the content of posted comments. Please note that activities such as flaming, ungrounded accusations as well as spamming will not be entertained.