Inspiration

Why does building a real-time event pipeline still feel like assembling a rocket engine by hand? A developer who just wants to read a live tick stream, maintain a rolling 1-minute window, calculate an RSI indicator, and trigger a signal is forced to write nearly 100 lines of messy Kafka consumer glue code, manual circular buffer loops, timestamp parsers, and serialization logic. We asked: What if stream processing had the simplicity and elegance of a Unix pipe? Meet Deyin: a declarative, zero-dependency domain-specific language that turns 100-line streaming nightmares into 5 clean lines of code.

stream prices from kafka "binance.BTC"
  | window 1m
  | filter price > 20
  | filter rsi(14) < 30
  | map buy 10%
  | sink to stdout

What It Does

Deyin elevates streaming primitives into first-class syntax:

  1. Single Linear Operator (|): No complex builder patterns, nested callbacks, or bulky YAML configurations. Every stage (stream | window | aggregate | filter | map | sink) flows linearly.
  2. True Causal Sliding Windows: Unlike toy stream DSLs that cheat by passing all rows through without collapsing them, Deyin has real temporal windows (window 5m | aggregate avg(price) as vwap). 3,000 live ticks enter \(\rightarrow\) exactly 10 rolling aggregated windows exit.
  3. Built-in Technical & Statistical Indicators: First-class support for causal Wilder's RSI (rsi(14)), stateful Exponential Moving Averages (ema(20)), Simple Moving Averages (sma(50)), and rolling aggregations (sum, avg, min, max, count, first, last).
  4. Dual Execution Runtime:
    • Tree-Walk Interpreter: Instant causal evaluation with circular deque buffers and zero lookahead data leaks.
    • Ahead-Of-Time Compiler: Transpiles pipelines into standalone, zero-eval lazy Python (itertools.islice) or typed WebAssembly Text kernels (WAT).
  5. Static Verification Engine (R1–R8): Rustc-style diagnostics with exact line/column caret alignment (^) catching unknown fields, arity mismatches, and WASM-incompatible operations at compile time.
  6. Zero-Install Web Studio: Monaco-powered in-browser playground running the real Pyodide WebAssembly runtime with live AST DAG visualization and WebAssembly bytecode validation.

How We Built It

  • Formal LALR Grammar & AST: Defined in grammar.lark, parsed by Lark with exact source position tracking (line, col), and transformed into a strongly typed AST node hierarchy (src/ast.py).
  • Causal Visitor Interpreter (src/interpreter.py): Pure Python tree-walk visitor supporting Wilder's smoothing with proper warm-up periods, circular buffer state, and event-time duration deltas.
  • Optimizing Compiler (src/compiler.py): Features Dead Code Elimination (DCE), lazy iterator synthesis with itertools.islice, and WebAssembly stack emission (local.get, f64.const, f64.gt, i32.and).
  • Interactive Studio (playground/index.html): Monaco Editor, WebAssembly-based Pyodide environment with virtual filesystem mounting, instant JS Shunting-Yard fallback preview, and Monaco DAG flow visualization.

Challenges We Overcame

  1. True Causal Windowing without Future Leaks: Ensuring that sliding windows (window 5m) never read ahead or leak uncommitted future events while maintaining \(O(1)\) amortized memory allocation per tick.
  2. Dual-Runtime Parity: Making sure the tree-walk interpreter and the generated lazy Python pipeline produce \($100\%\) byte-for-byte identical output records across thousands of tumbling and sliding windows.
  3. WebAssembly in the Browser: Embedding a full Python runtime and Lark LALR parser in WebAssembly via Pyodide, with instant fallback JS execution so the browser playground loads in under 50ms.

Accomplishments We're Proud Of

  • 45 Automated Unit Tests with 100% Pass Rate (tests/).
  • Zero Runtime Dependencies: The entire language runtime and compiler execute on vanilla Python 3.9+.
  • Complete Developer Ecosystem: Includes an interactive terminal REPL (src/repl.py), unified CLI (cli.py), VS Code TextMate syntax extension (vscode-extension/), and complete documentation hub (docs/).

What's Next for Deyin

  • Stream-stream temporal joins on sliding timestamp windows (stream A | join stream B on timestamp).
  • Native binary .wasm artifact generation with SIMD vectorization for filtering loops.
  • Live WebSocket and distributed Apache Kafka / Redpanda broker connectors.

Built With

  • compiler
  • dsl
  • fintech
  • lalr
  • lark-parser
  • monaco-editor
  • pyodide
  • python
  • remotion
  • stream-processing
  • webassembly
Share this project:

Updates

Submission history