How do we abstract complex business logic from tech code?

Arthur Mialon
PayFit
Published in
8 min readJan 7, 2019

At PayFit, we are revolutionizing how companies run their payroll and manage their human resources. We are trying to make HR Managers’ daily life a breeze. To achieve this lofty goal, we developed an internal technology to help us move our business logic away from our code.
Today, we are talking about our Internal Language,
JetLang… 🚀

📅 The state of most applications

Today, in most SaaS applications, updates related to the product must always involve one or more developers.

These developers need to know the codebase well, understand its intricacies, and anticipate all the impacts their features might have on the rest of the application, on the data, on the API…

If we look even further into the future, we might need a designer, a product manager, or even more developers in order just to finish those updates.

Updates to the product need a sequence of meetings, require a mix of different skills, and bring a lot of complexity in the product development flow.

🙃 Why is it so complex ?

Because business logic and product features are intrinsically linked to code.

- What do we do if we want to abstract the business logic out from the code?
- Wait, why do we need that in the first place?

Indeed it is quite unusual to need this kind of abstraction. At best, most people like to talk about configuration by using an admin panel. Unfortunately, they usually do not completely change the functionality of the product and are often very limited.

🙋️ What is happening at PayFit ?

At PayFit we are trying to revolutionize payroll and HRIS management in companies. We decided to start in France 🇫🇷 but we quickly found our increasingly large appetite hard to satisfy. Europe is just the start, we are proud to say that we are already revolutionizing payroll in Spain 🇪🇸, Germany 🇩🇪 and soon in the UK 🇬🇧.
The main problem (or the opportunity) comes from our core business: payroll.

Payroll management is extremely different depending on the country. We are not just talking about a configuration for each country, but really: a whole new set of logic, new formulas, different types of companies, and especially different laws.

🏗 How do we make this possible ?

How to add new features and especially variants of the same features in the simplest possible way, being more powerful and increasing the possibilities?
Forget a simple admin panel.

😒 Naive Person: OK, we’ll add some`if` statements, change 2 or 3 files, and add some new configurations! That’ll do the trick!

Well my dear, if only things were this simple! Even if the work itself is simple, it isn’t very scalable.

A couple of questions to ponder on:
What do we do when there are very similar logic in multiple places? Should we rewrite everything? Just one part? Only what changed? How do we take into account how all of the laws changed each month in each country? Does the code remain as simple and readable if you’re managing 2 countries or 50 countries? Do developers need to know the formulas for calculating a salary? A donation? How do you manage the impacts between different countries?

We can clearly see that the naive way of working will certainly not work for us in the long term.

😎 Smart person: Ok, I need to abstract all of my business logic without touching code, and without hiring a new developer. I need something automatic, which is simple, easily testable but also very powerful. What did humans invent to automate logic? Programming!

😔Non-imaginative person: So, no choice, I have to keep my logic in my code… There is no other solution…

😎 Smart person: Why not create a programming language? 🚀”

💡The big idea

Imagine a simplified language that allows you to do a subset of the operations of mathematics and logic. A bit like Excel operations. It could contain variables, conditions, and functions. Imagine a powerful engine that can understand this language and run it on a browser or on a server. Developers will just have to create the skeleton of the application and put the engine in the right place. Another payroll team will be able to create the pages and the logic. They will be able to generate lists, modals and make very complex calculations on any platform. Developers will be able to focus on core topics that are not related to business, UI, performance or security without worrying about business logic.

Spoiler! That’s what we do at PayFit!

📊 Payroll by numbers in France

Do you know how many parameters have to be taken into account when calculating a net salary in France? 🇫🇷

A dozen or fifty? If so, I guarantee you that the salary won’t be exact.
No, in France it’s necessary to involve about 7000 parameters to calculate a net salary.

Imagine writing this in JavaScript, maintained by developers who know nothing about payroll… And the net salary is just one parameter among many.

There are also hundreds of collective agreements that will potentially change all calculations. It is difficult to summarize this in a single mathematical formula. We need logical components.

At PayFit, we want to revolutionize payroll, not just make calculations but also offer a simple interface so that anyone can manage the payroll of its employees. We need a system of UI components related to our business logic.

🚀 Introducing Jetlang

Jetlang is a technology we develop internally consisting of a programming language, logical components and a development tool.

🗣 The language

The language is very simple. Variables, conditions and mathematical expressions can be used.

The variables can be inputs of the user or calculated automatically from other variables in parameters.

# Example of Jetlang code
# variable1 -> firstName
# variable2 -> lastName
# Let's compute the fullNameNotIn( null ; variable1 ; variable2) # If the variable is filledConcat( variable1; " " ; variable2) # Let's concat values

🖌+ 🐘 Components and Actions

The principle of Components is quite special. They allow you to manage the interface but also to manage complex logic on a page.
Each component works differently due to having its own configuration.
From there, creating complex logic trees becomes child’s play.
The last concept we have is what are called Actions. It can be seen as a page, or as a script, because we need to run it on any platform including browsers and servers.

Our own IDE. We create a really simple Action and its Components. All Variables look like (xx.xxx)
Jetlang in action in the browser.

Imagine all the types of components we can create and complex logic that can be written. It’s infinite and very powerful.
We can make lists, loops, calls to APIs, hook into event systems without directly touching JavaScript code, etc.

The main idea is simplicity. Users of this language and tools are not developers. They are Jetlang Masters.

Thanks to this kind of system we can develop Payroll Management in several countries in a very fast and extremely efficient way. The base is already there, simply rewrite the different logic related to the payroll laws of the country in question. The rest is done automatically.
We can create X Jetlang Master teams distributed in each country and keep a single tech team in one place.

🎼 The engine

A programming language does not work alone. It’s usually just a grammar, a parser, an interpreter. It takes a motor and a conductor to do the calculations in a specific order.

This amounts to solving complex graphs of dependencies between variables, components and condition trees. A ton of research on graph algorithms exist, and we were able to inspire ourselves and find the right way to do our calculations without reinventing the wheel.

The engine will use our parser, generate an AST (abstract syntax tree) and make sure to calculate the whole graph as quickly as possible to update the variables used. It must be fully tested and easily maintainable so that the slightest syntax error is understandable for the Jetlang Master.

🏎 The Runner

Does the engine also need to handle state changes? User inputs, call APIs?
No.

We decided to create a complex state manager based on a well known library: Redux. We will not go into detail here, but the runner is aware of the component tree. It’s the runner that manages the flow of data.
It will communicate with the engine only when it needs it. This makes it possible to really separate the calculation logic from the state logic.

It can work with UI libraries like React, React-Native or even Vue and AngularJS. It can also run on a server. We can send the runner precise commands (redux actions) without necessarily using a UI. It will take care of updating the states of the components and ask, if it is necessary, for the engine to make new calculations.

💪 Let’s talk a little bit about performance

Creating a new layer between the user and the browser can have a huge impact on the performance of an application. Indeed we have to parse, transfer a lot of data and potentially calculate millions of variables very quickly.

Performance improvement is the number one priority for some teams within PayFit, making sure to be more powerful while remaining as fast as possible for our users.

Thanks to the creation of Jetlang, developers can stay focused on this famous performance. They can spend time analyzing and improving algorithms. Having this existing abstraction also allows us to turn to very advanced technologies like WebAssembly with Rust for example.
We can discuss it in more detail in a future article.

👪 Our dear Jetlang Masters

Again, Jetlang Masters are not developers. It is important for the development teams working on the engine and the Runner to know their “users” and especially to understand how they work.

The goal is to find new tools to make their lives easier and more productive. We can imagine tools for deployment, integration tests, debugging, monitoring, and tracing.

All these tools are there so that the Jetlang Masters can fix their errors themselves without needing the intervention of the technical team. This lets them stay focused on their logic and the product features.

There is still a lot to say about Jetlang. That’s why this article will fit into a more global series currently being written.
We know that this kind of tool can’t adapt to all the cases of the world and can’t solve all the problems but makes it possible to separate the business logic of the tech code in a very effective way. We wanted to share our experience.
😊

Growing product in a scalable and healthy way is not easy. This requires making choices that are not very obvious upstream of development. The benefits of this kind of architecture are reflected in the daily lives of developers and our ability to evolve product features. 💪

Jetlang Masters all over the world: Thank you for making our developer life better and really challenging. 🇫🇷🇬🇧🇪🇸🇩🇪🌍

--

--