Skip to main content

FAQ

Why no for and while?

Because every numeric loop you would write with them is one of a few named patterns in esque (tabulate, scan, iterate_until, each, +/). Naming them makes the program self-explaining and makes the compiler's job easier. See Loop primitives for the full pitch.

Why no LLVM?

Two reasons. First, the compiler is small enough that an LLVM dependency would be the largest line item in the build. Second, the backend's job is narrow — emit good x86-64 for tensor kernels — and it benefits from owning isel, regalloc, and encoding end-to-end. LLVM would actually make some of the work harder.

Why Linux-only? Why x86-64-only?

Time. The encoder is hand-written, the ELF writer is hand-written, the syscall stub is hand-written. Adding macOS / Windows / aarch64 is straightforward but real work; nobody has done it yet.

Where does memory come from?

esque has no heap allocator today. All values are stack-allocated or in .rodata. Tensor literals and constant folds end up in .rodata. Local tensors live in stack slots managed by the register allocator. Dynamic-shape tensors will need an allocator; that comes with the linear types work.

Not yet. The backend does not produce a libc-aware object — the _start stub bypasses libc entirely. FFI is on the long-term roadmap but is gated on having effect typing first.

What does __N mean in function names?

Monomorphisation. dot__3 is the specialised copy of dot[N] for N=3. The compiler emits one copy per shape it sees at call sites.

Why does my tensor literal end up in .rodata?

Because constant tensors are placed there by the MIR pass, with appropriate alignment, and referenced from .text via R_X86_64_PC32. The single lea is faster than per-element stores on every call.

What if I want to print a tensor?

each(v, print_i32) will print one element per line. There is no "print this whole tensor as a vector" intrinsic; once general I/O lands you can build it.

Where is string?

String literals ("...") work as of v0.12 and can be passed to print_str. The full string surface (concatenation, slicing, length, byte access) is still planned.

Where is i64 codegen?

i32, i64, u32, i8, u8, and f64 all codegen end-to-end today. The remaining widths (i16, u16, u64) type-check but the backend rejects them with a forward-pointing diagnostic; see extended numerics.

Where is broadcasting?

Not yet. Element-wise ops require matched shapes today. Broadcasting is on the roadmap and will likely arrive with the kernel-DSL work.

Where can I see the spec?

Reference → Specification.

Where is the public roadmap?

Reference → Planned features → Roadmap.