Write Python.
Run native code.
This live demo shows how Chalk compiles Python feature resolvers into native, vectorized expressions without ever running your code. It is for ML and data engineers who write features in Python and need them to serve fast in production. Type a resolver or pick an example, and you will see each line marked as compiled or falling back to Python, the native expression it becomes, and the exact reason any line stays in Python.
Compare a compiled function with a Python fallback
The analyzer explains what can become a native expression without executing the submitted code.
Try this experiment · expected results
1Start with Arithmetic
Read the highlighted Python and the generated expression beside it.
Expected: Supported lines become native expression nodes; branches become conditionals.
2Choose an unsupported example
Switch to Unsupported library or Untraced builtin and inspect the highlighted stop line.
Expected: The analyzer identifies why tracing stops and Python execution is still needed for that resolver.
Does this Python function become a native Chalk expression, or need Python at query time? Choose an example and compare the highlighted code with the compiler’s verdict.
Analyzing the function…
The analysis runs live on a Chalk scaling group serving the Rust port of Chalk’s static accelerator. Your code is parsed and executed symbolically, never run. Parameter types come from the annotations: int, float, str, bool, bytes, list[...] and Optional[...].
Built on Chalk
Python is the right language to write features in and the wrong one to run them in, row by row, at serving time.
No Python on the hot path
A compiled resolver runs inside Chalk's native engine, a column at a time, instead of calling a Python function once per row.
Python semantics, kept
Division by zero, math domain errors and None handling compile to the same failures Python would raise, so a compiled resolver can't quietly disagree with its source.
Exact fallbacks
When a line can't be lowered, the interpreter points at it and says why. Fix that line, or leave it: the resolver still runs, in Python.
Written in Rust
This demo runs the Rust port of Chalk's static accelerator. It needs no Python interpreter, and it checks a typical resolver in about a millisecond.
Nothing to opt into
Write resolvers the way you already do. Chalk tries to compile every Python resolver when it plans a query, and the ones that compile run natively without a code change.
In ChalkSQL, a Python function body goes through the same compiler, so a helper you write once in Python runs as a native SQL function. The analyze endpoint behind this page is there too, if you want to check a function from a script.
from chalk import online
from chalk.features import features
@features
class Transaction:
id: int
amount: float
is_international: bool
fee: float
# Plain Python. When Chalk plans a query, it traces the body and, if
# every line has a native equivalent, runs it as a vectorized expression.
@online
def processing_fee(
amount: Transaction.amount,
is_international: Transaction.is_international,
) -> Transaction.fee:
fee = amount * 0.029 + 0.30
if is_international:
fee = fee + amount * 0.01
return feeImplementation details
How the example works
Parse
The resolver's source and its parameter types are all the interpreter needs. It parses the function; nothing in it ever runs.
Execute symbolically
Each statement is evaluated over symbolic values instead of data: branches become conditionals, loops become list functions, and Python's own error cases become guards.
Lower to an expression
The result is a typed Chalk expression that runs vectorized over a whole column. If any line has no native equivalent, the resolver keeps running as Python, and you get the line and the reason.
More capabilities
Modules in scope
math, re, json, datetime, hashlib and statistics resolve without an import, along with the string, list and dict methods resolvers lean on.
Same compiler in SQL
CREATE FUNCTION ... LANGUAGE PYTHON uses this compiler too, so a Python helper becomes a native SQL function rather than a UDF.
Keep writing Python
Let Chalk turn it into native code where it can. Talk to an engineer about your feature pipelines.