Expr
Expr is a Go-centric expression language designed to deliver dynamic configurations with unparalleled accuracy, safety, and speed.
// Allow only admins and moderators to moderate comments.
user.Group in ["admin", "moderator"] || user.Id == comment.UserId
// Ensure all tweets are less than 240 characters.
all(Tweets, .Size <= 240)
Features
Expr is a safe, fast, and intuitive expression evaluator optimized for the Go language. Here are its standout features:
Safety and Isolation
- Memory-Safe: Expr is designed with a focus on safety, ensuring that programs do not access unrelated memory or introduce memory vulnerabilities.
- Side-Effect-Free: Expressions evaluated in Expr only compute outputs from their inputs, ensuring no side-effects that can change state or produce unintended results.
- Always Terminating: Expr is designed to prevent infinite loops, ensuring that every program will conclude in a reasonable amount of time.
Go Integration
- Seamless with Go: Integrate Expr into your Go projects without the need to redefine types.
Static Typing
- Ensures type correctness and prevents runtime type errors.
out, err := expr.Compile(`name + age`) // err: invalid operation + (mismatched types string and int) // | name + age // | .....^
User-Friendly
- Provides user-friendly error messages to assist with debugging and development.
Flexibility and Utility
- Rich Operators: Offers a reasonable set of basic operators for a variety of applications.
- Built-in Functions: Functions like
all
,none
,any
,one
,filter
, andmap
are provided out-of-the-box.
Performance
- Optimized for Speed: Expr stands out in its performance, utilizing an optimizing compiler and a bytecode virtual machine. Check out these benchmarks for more details.
Install
go get github.com/antonmedv/expr
Documentation
- See Getting Started page for developer documentation.
- See Language Definition page to learn the syntax.
Expr Code Editor
Also, I have an embeddable code editor written in JavaScript which allows editing expressions with syntax highlighting and autocomplete based on your types declaration.
Examples
package main
import (
"fmt"
"github.com/antonmedv/expr"
)
func main() {
env := map[string]interface{}{
"greet": "Hello, %v!",
"names": []string{"world", "you"},
"sprintf": fmt.Sprintf,
}
code := `sprintf(greet, names[0])`
program, err := expr.Compile(code, expr.Env(env))
if err != nil {
panic(err)
}
output, err := expr.Run(program, env)
if err != nil {
panic(err)
}
fmt.Println(output)
}
package main
import (
"fmt"
"github.com/antonmedv/expr"
)
type Tweet struct {
Len int
}
type Env struct {
Tweets []Tweet
}
func main() {
code := `all(Tweets, {.Len <= 240})`
program, err := expr.Compile(code, expr.Env(Env{}))
if err != nil {
panic(err)
}
env := Env{
Tweets: []Tweet{{42}, {98}, {69}},
}
output, err := expr.Run(program, env)
if err != nil {
panic(err)
}
fmt.Println(output)
}
Who uses Expr?
- Aviasales uses Expr as a business rule engine for our flight search engine.
- Wish.com uses Expr for decision-making rule engine in the Wish Assistant.
- Argo uses Expr in Argo Rollouts and Argo Workflows for Kubernetes.
- Crowdsec uses Expr in a security automation tool.
- FACEIT uses Expr to allow customization of its eSports matchmaking algorithm.
- qiniu uses Expr in trade systems.
- Junglee Games uses Expr for an in house marketing retention tool Project Audience.
- OpenTelemetry uses Expr in the OpenTelemetry Collector.
- Philips Labs uses Expr in Tabia, a tool for collecting insights on the characteristics of our code bases.
- CoreDNS uses Expr in CoreDNS, a DNS server.
- Chaos Mesh uses Expr in Chaos Mesh, a cloud-native Chaos Engineering platform.
- Milvus uses Expr in Milvus, an open-source vector database.
- Visually.io uses Expr as a business rule engine for our personalization targeting algorithm.
- Akvorado uses Expr to classify exporters and interfaces in network flows.