~ / projects / esque

esque

A statically typed, tensor-first systems language that compiles to native x86-64.

status: active kind: language #Go#x86-64#SIMD#tree-sitter#LSP

Why I built it

I built esque as a learning project. I studied language design, machine language, and compilers in college but never actually implemented one, and it took me a while to admit that my understanding was almost entirely theoretical. I knew the vocabulary, parsing, IRs, codegen, optimisations like SIMD and loop unrolling, but I had never built the thing the vocabulary describes. esque is me building it, one pass at a time, all the way down to hand-emitting x86-64 and AVX2 SIMD with no LLVM underneath.

It was also my way into purely functional, tensor-primitive languages, which I had wanted to explore for a long time. I spent years in Python doing machine learning and lost far too many hours to bugs that came down to the language having no real notion of tensor shapes or controlled side effects. esque is the opposite by design: shapes live in the type system, and side effects are tracked through @io. My goal is to grow it into a language that genuinely suits machine learning and data processing, so that one day it can carry real ML work.

What it is

esque is a statically typed, tensor-first systems language that compiles to native x86-64 Linux binaries. Tensors are first-class values and their shapes are part of the type, so a shape mismatch is a compile-time error rather than a runtime surprise. The surface syntax covers @io and @kernel attributes, scalar types like f64, i8, and u8, pattern matching, generics over tensor shapes, and a set of large-N loop primitives (tabulate, scan, iterate, iterate_until, each) alongside elementwise and reduction operators over tensors. Those tensor operations are where esque earns its keep: elementwise math and reductions on f32 tensors lower to packed AVX2 and SSE SIMD (256-bit eight-wide, or 128-bit four-wide) with a scalar tail, so the obvious numeric code compiles straight to vectorised machine code.

The toolchain

Three repos, all public under the esque-lang GitHub org:

RepoRole
esquecThe compiler, written in Go. It runs the whole pipeline: parse, type-check, then lower through its own IRs down to native x86-64 Linux ELF.
tree-sitter-esqueThe grammar plus queries for highlights, locals, and symbol tags.
esque-lspThe language server: hover, completion, go-to-definition, and document symbols.

The grammar and language server drop into any editor with tree-sitter and LSP support, so wiring esque into an editor is configuration rather than a bespoke plugin.

Example

Linear regression by gradient descent. The slope a is the only state the training loop carries, and every quantity in the step is whole-tensor, no per-element indexing:

# Learn a slope `a` such that y ≈ a·x for a small noisy dataset.

@io fn show(p: f32) -> f32 = print_f32(p)

@io fn main() -> i32 = {
    let xs = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
    let ys = [2.10, 3.92, 6.05, 8.10, 9.95, 12.00, 14.05, 16.00];
    let lr = 0.005;

    # 32 gradient-descent steps; the state is the scalar slope `a`.
    let a = iterate(32, 0.0, |a|
        let av  = tabulate(8, |_i| a)  in   # broadcast a to a length-8 tensor
        let res = (av .* xs) .- ys     in   # residuals, elementwise
        let g   = +/(res .* xs)        in   # gradient: sum of res · x
        a - lr * 0.25 * g
    );

    print_f32(a);                            # learned slope, converges to ~2.0
    each(tabulate(8, |_i| a) .* xs, show);   # predictions
    0
}

esquec is the whole toolchain, a single static binary. Type-check it, compile it to a native ELF, and run it:

esquec check linreg.esq            # type-check only, no codegen
esquec build linreg.esq -o linreg  # compile + link to a native x86-64 ELF
./linreg                           # prints the slope, then 8 predictions

esquec build linreg.esq --emit=asm # peek at the emitted machine code (incl. SIMD)

Status

Pre-1.0 and actively developed. The compiler, grammar, and language server are public at github.com/esque-lang, and the language spec is published at esque-lang.github.io/esquec.