Skip to main content

5 Years in the Making

· 5 min read
Anton Medvedev
Ex-SRE at Google, Ex-SWE at Aviasales

5-years.webp

It's been 5 years since I started working on Expr. It's been a long journey, and I'm excited to share some of the highlights with you.

Introduction

Five years back, at Aviasales, we were transitioning our search engine from Python to Go. Our task was to revamp our business rule engine, but we were stuck without the right language to script these complex rules. I stumbled upon govaluate, but it was like finding a boat with holes – abandoned and not seaworthy for our needs.

The Birth of a New Language

&ast.BinaryNode{
Operator: "+",
Left: &ast.IntegerNode{1},
Right: &ast.BinaryNode{
Operator: "*",
Left: &ast.IntegerNode{2},
Right: &ast.IntegerNode{3},
},
}

That's when I rolled up my sleeves. We needed a language that wasn't just about doing the job; it needed finesse – features like all() and none() predicates that you now see in Expr. So, I started from scratch, with a simple idea and ANTLR, a parser generator, as my initial tools. This first language version was basic – turning input into an AST and walking through this tree to get results. It was a humble start but it worked, and it worked well.

Evolving with Need

As we stretched the capabilities of our new language, we quickly realized its initial simplicity had its limits. A pivotal moment came when I decided to abandon the parser generator we were using. The reason? It wasn't just about its cryptic error messages, which were more puzzling than helpful. A more pressing issue was a specific bug in ANTLR's Go version, particularly on 32-bit machines. This limitation was a deal-breaker, as I envisioned Expr to be versatile, running seamlessly across various platforms, not restricted by such technical constraints.

Faced with these challenges, I took matters into my own hands. I crafted a bespoke parser from scratch. This wasn't just about fixing bugs or expanding compatibility; it was about creating something that resonated with users. My parser was designed to be clear, concise, and above all, user-friendly. It was a game-changer, transforming error messages from baffling codes into understandable, actionable insights. This shift significantly enhanced the language's usability and marked a major milestone in its evolution, setting the stage for Expr to be a versatile and accessible tool across diverse computing environments.

Chasing Efficiency

0  OpPush      <1>
1 OpPush <2>
2 OpPush <3>
3 OpMultiply
4 OpAdd

Then came the need for speed. The solution was clear – a virtual machine. I crafted a compiler to turn our AST into bytecode, and when I got this virtual machine running, it was like hitting the turbo button. Our language wasn't just faster; it was lightning-fast, encouraging more complex and extensive use at work. And soon, it wasn't just us at Aviasales using it – other companies started catching on, and my little project began to grow wings.

Community Engagement and Growth

Expr's journey has been a testament to the power of community and innovation. Beginning with blog posts and presentations at conferences like this one, Expr has captured the attention of the programming world. Today, it's thrilling to see it being embraced by a diverse and growing community, including developers and companies worldwide.

The impact of Expr has reached global proportions, with industry giants like Uber, ByteDance, GoDaddy, Philips, and Google (google3/third_party/golang/expr) integrating it into their ecosystems. This widespread adoption underscores the language's versatility and effectiveness in addressing complex programming needs.

Feedback from this vibrant community has been a cornerstone of Expr's development. Feature requests and bug reports have been particularly insightful, shedding light on how Expr is used in various contexts and what enhancements are most desired by users. This direct input has been invaluable in steering the language's evolution.

In response to every bug report, I've created a unit test, ensuring that each issue, once resolved, stays fixed. This commitment to quality and continuous improvement has been key in building trust and reliability within the Expr community.

Looking Ahead: The Future of Expr

The journey of Expr is far from over. As it gains momentum, being used by renowned companies and developers, the future looks bright and full of potential. My vision is to keep Expr dynamic, continually evolving to meet the changing demands of the tech world.

The roadmap for Expr includes several exciting features that are currently in development. These upcoming enhancements are designed to further solidify Expr's position as a powerful tool in the programming landscape, offering new capabilities that I believe will be enthusiastically received by the community.

Expr's niche focus on the Golang community and business rule engines, coupled with its growing popularity in major tech companies, positions it uniquely in the field of programming languages. As the technology landscape evolves, Expr is set to evolve with it, meeting the challenges and embracing the opportunities that lie ahead in this specialized domain.