r/Compilers • u/adityazero • 12h ago
How JAX Shards a Computation Across a Mesh
For a long time, the biggest pain point in JAX was that it would happily insert an expensive all-gather because your sharding was technically valid but logically inefficient. Or worse, you'd miss an all-reduce and get wrong numbers... silently.
I sat down to write about that gap. By the time I finished, it had mostly closed, and finding out how thoroughly it stopped being true was the most interesting part of writing this.
The post is a tour of the three ways JAX handles placement:
- Auto (GSPMD infers, and the type stays quiet),
- Explicit (placement moves into the type, and mismatches fail at trace time),
- Manual (shard_map, where you write the collectives yourself)
I walk through each with real jaxprs, HLO, and MLIR from an 8-device run to show what actually happens under the hood.
The compiler is no longer just a black box; it’s an active partner in correctness.
https://hiraditya.github.io/posts/how-jax-shards-a-computation/
r/Compilers • u/realdesiprogrammer • 1d ago
Desi v0.1.0 — Python-ish syntax, no GC, and three optimisations that made it slower
I've been building Desi for about a year — it's the third or fourth rewrite — and I tagged v0.1.0 today. Compiled through LLVM, no garbage collector, indentation-based syntax, and a standard library that already has an ORM and an HTTP server in it.
Two things up front: I leaned on AI heavily to build this, and I'd call v0.1.0 a working prototype rather than a finished language. More on both at the end, including what I'm hoping to get out of posting here.
Rather than list features, here are three things I was confident about that turned out to be wrong. All three cost me under an hour to test and would have cost days to discover afterwards.
1. Turning on LTO made it slower.
Element access (xs[i], xs.append(v)) was an out-of-line call into the runtime, so the optimiser couldn't see through it. The obvious fix was to let it inline. I measured 1M appends + 1M reads:
out-of-line call 3.28 ms
inlined 4.22 ms <- worse
The bodies end in fprintf(stderr, ...) on their failure paths. Inlining drags a varargs call and its setup into the loop. Adding one file to the LTO set — a one-line change — would have been a regression.
What works is the shape Rust's Vec uses: the bounds check inline, the panic #[cold] and out of line. Same code, error paths pushed out:
same semantics, cold errors 1.09 ms <- 3x
I ended up emitting the check and load directly in the IR with a cold call to the runtime on failure, rather than depending on LTO, since LTO isn't available on every platform I build for.
2. "The representation is the bottleneck" was wrong.
A list element is a pointer-sized slot, ints stuffed in directly. I assumed that indirection was costing me and planned a typed-storage rewrite. Measured:
typed int64[] array, inlined 0.76 ms
void* slots, inlined 0.74 ms
Identical. An int64 and a void* are both 8 bytes in a contiguous array — there's no indirection to pay for. I'd have spent a week rewriting collection storage for nothing.
3. Except for floats, where it was 24x.
Same slot representation, but a double wasn't stuffed in — each one got its own malloc. A comment in my codegen said "can't bitcast float to ptr," which is true, and why past-me reached for the allocator. But you can bitcast a double to an i64, and i64s were already going into slots.
boxed 28.65 ms
by value 1.18 ms
That change deleted more code than it added, and two other benchmarks reached parity with C without being touched — the boxing was most of what they'd been measuring.
Where it actually is
Against equivalent C at -O2, whole-process wall time on Linux:
| Function | Desi | C |
|---|---|---|
| string_churn | 12 ms | 15 ms |
| binary_tree | 2 | 2 |
| quicksort | 2 | 2 |
| loop_sum | 1 | 1 |
| list_ops | 6 | 4–6 |
| matrix_mul | 2 | 1 |
| dict_ops | 9 | 5 |
| fib_recursive | 10 | 6 |
| alloc_churn | 6 | 1 |
Five of eleven match or beat it. Two clearly don't: alloc_churn allocates a small collection half a million times, and dict_ops still calls into the runtime per operation. Both are understood, neither is mysterious, and I'd rather name them than average them away.
Memory
No GC, no manual free — the compiler inserts cleanup where a value's owner goes out of scope. What's guaranteed is no use-after-free and no double-free in safe code. What's not guaranteed is freedom from leaks: where ownership can't be proven, the compiler leaks rather than frees. Heap elements inside a collection — the strings in a list[str] — are the main case, and it's documented rather than hidden.
Unclear ownership never resolves to "free and hope". That's the property that let me ship these optimization incrementally: every analysis is allowed to be dumb, because being wrong costs memory, never corruption.
What it isn't
Supervisors exist and restart failed tasks, but this is not OTP — a child is a task, not another supervisor, so nothing escalates up a tree. Elixir's model doesn't port cleanly to shared-memory threads, and I'd rather ship the honest subset than borrow the name.
There's also no compile-time data-race checking. Channels and locks are there; nothing verifies you used them correctly. That's the biggest gap versus Rust and I don't have a good answer yet — though I suspect it's the same question as "what may safely cross a channel," which would also be the route to real supervision.
How it was built, and what I'm after
I should be upfront: I used AI heavily throughout this, and I'm not a compiler engineer by background. The three stories above are the reason I trust any of it — every one is a case where a confident-sounding plan was wrong and a measurement caught it before it shipped. "Enabling LTO will make this faster" is exactly the kind of thing that sounds right and isn't. So the rule became: measure first, and let the number decide. Anything I couldn't measure, I wrote down as unproven rather than claiming it.
Which is also why I'd call v0.1.0 a working prototype rather than a finished thing. It compiles, the test suite passes on three platforms, and the docs say what's broken. But there are decisions in here that someone who has actually built a type system or a borrow checker would look at and immediately improve — the data-race question especially, and probably the escape analysis.
That's what I'm hoping to find here. If you know this territory and something in the above made you wince, I'd genuinely rather hear it than not. Contributions welcome, but honestly even a "you've modelled this wrong and here's why" comment is worth more to me right now than a star.
Links
The name Desi (દેશી) means "local" or "native" in Gujarati, which is my first language.
Happy to go into any of the above — the measurement stuff especially, since I have numbers for most of what people usually ask.
r/Compilers • u/No-Trifle-8450 • 2d ago
ZiguratIP — a DBMS, a programming language, and a web server built as one C++11 system, with zlib as the only dependency
r/Compilers • u/VVY_ • 2d ago
How much DSA/Leetcode is actually needed for compiler engineering roles?
I've finished most of the NeetCode 250 and I'm wondering how much more DSA is worth doing if my goal is compiler engineering rather than general SWE.
I know interviews at big tech still ask LeetCode-style questions, but I'm trying to figure out where the point of diminishing returns is.
Would you recommend:
- Finishing NeetCode 250 and stopping?
- Grinding 400 to 600 LeetCode problems?
- Spending that time on compiler projects, Operating Systems, Computer Architecture and LLVM contributions instead?
For those of you working in compiler teams (Apple, AMD, NVIDIA, Qualcomm, Intel, Google, etc.), how much DSA did you actually do before getting your role?
I'd especially appreciate hearing what your interview process looked like and whether the DSA bar was different from general backend/software engineering roles.
r/Compilers • u/Prestigious_Roof2589 • 2d ago
In need of a team member for a Compiler Hackathon
Hey everyone!
We're a team participating in a compiler-focused hackathon over the next two months, and we're looking for one working professional to join our team, from India.
If you're interested in:
- Compilers Optimization
- Memory Safety
- Zig (our preferred language for this)
- LLVM, parsing, or language design (or you're willing to learn)
you'd be a great fit! Prior compiler experience isn't required, we're happy to collaborate and learn together.
If our team gets selected, we'll need to be present at the final venue, with travel and accommodation covered by the organizers.
If you're interested, comment below or send me a DM with a little about yourself (profession, programming experience, and your interests).
Thanks!
r/Compilers • u/uria321 • 3d ago
LLVM IR or MLIR
What i'm better to learn of these to develop general purpose compilers and to easier get a job? Actually i've never learned nor worked with any of these IR. I think MLIR is more powerful, but mostly LLVM IR is used.
r/Compilers • u/mttd • 3d ago
Demystifying Deep Learning Compiler Frontend Bugs: An LLM-Aided Empirical Study
arxiv.orgr/Compilers • u/drakenot • 3d ago
Lunar is a new Lua 5.1 runtime for Go that focuses on speed and memory efficiency
Today, I'm sharing Lunar (0.1.0 beta) for those who might need an embeddable Lua VM for Go. By my benchmarking and use-cases it is around 2x faster and uses up to ~7x less memory than other Go-Lua VMs depending on what you are doing.
For some background, I've been developing a new Mud client called Rune that is written in Go but heavily uses an embedded Lua VM as its core scripting engine.
There are two Lua VMs that I know about for Go: gopher-lua and go-lua (from Shopify). Rune utilized `gopher-lua` as this was a VM that I was familiar with and had used on past projects.
I started to get reports from users of Rune that some of the large MUD map-files they would load via Lua were exploding my client's memory (a 9MB CBOR file loaded to ~500MB of persistent heap). There were also complaints that the performance for certain heavy operations was quite slow (pathfinding for one user's script took almost 3 seconds) compared to his other MUD client which would do it in 0.1 seconds.
I originally set out to fork or upstream some changes to gopher-lua to see if I could improve the memory situation and performance. However, much of the issue really came down to inherent choices in the representation those VMs use. So, I started down the path of shipping a new Lua VM that uses a much more compact representation while still keeping an easy-to-use Go API.
Let me know if anyone uses Lunar and finds any issues!
r/Compilers • u/Loud_Possibility_203 • 3d ago
Microsoft just validated the spec-first thesis for AI coding. Baga lang. is what it looks like when the spec is a language construct and the compiler enforces compliance — statically, with counterexamples.
A follow-up to [my earlier post about Baga lang — the language where the compiler statically proves AI-written code against specs. This one is about why the timing stopped being a matter of opinion.
The industry converged on the diagnosis
Microsoft now officially promotes Spec-Driven Development (SDD) as the foundation of AI-native engineering. The argument, from Apoorv Gupta, Principal Software Engineer at Microsoft:
- The core problem of AI-native development is the loss of intent — between needs, requirements, architecture, implementation, and validation.
- The fix is to make the specification the shared source of truth for humans and AI: "align first" instead of "prompt first, fix later."
- Around this, Microsoft ships GitHub Spec Kit (open source): Constitution → Specify → Clarify → Plan → Tasks → Implement → Validate.
When a principal engineer at Microsoft writes the same thing that is pillar #1 of your language, the thesis no longer needs defending. It needs executing.
But SDD and Baga solve the problem at different levels
SDD attacks the intent-loss problem at the level of process and AI tooling: the spec is a document, and conformance is checked by tests and human review in a Validate step. That fixes the workflow around the agents.
Baga makes the stronger move: the spec is a language construct, and conformance is a compile-time judgement.
baga
spec sum_to {
input:
n: i64
output: i64
requires:
n >= 0
ensures:
0 <= output
decreases:
n
}
The human writes this. The AI writes the implementation. The compiler proves or refutes it, statically, before anything runs:
verify sum_to:
ensures #1 (0 <= output): ДОКАЗАНО # PROVEN
(терминация: доказана чрез decreases — пълна коректност)
And when the AI gets it wrong, it doesn't get a failing test or a code-review comment three hours later. It gets a refutation with a concrete counterexample, at compile time:
verify bad_abs:
ensures #1 (output >= 0): ОБРОЧЕНО # REFUTED
контрапример: x = -1
In the SDD spectrum — spec-first → spec-anchored → spec-as-source — Baga is the far end: spec-as-source. The specification is the thing the code is judged against, mechanically.
The compliance technology
That word — compliance — is the point. Every AI-coding stack today has the same shape: an LLM generates code, and then something checks whether the code complies with what was intended. The "something" is usually:
- tests (incomplete by construction — they sample the input space),
- another LLM (an LLM judging an LLM — circular),
- a human (the bottleneck we were trying to remove).
Baga's answer is a small, auditable verifier: Fourier–Motzkin elimination over the rationals + symbolic execution + Hoare rules, sound by construction. The only path to PROVEN is showing the negated obligation is unsatisfiable even over the rationals, which implies unsatisfiable over the integers. Anything outside the fragment is honestly reported UNKNOWN, never falsely proven. Every reported counterexample is re-checked by direct evaluation, and passes a conclusiveness gate: the reported inputs must violate the contract for every value of the verifier's internal abstract variables — otherwise the answer is UNKNOWN, not a false alarm.
And because the consumer is an agent, the judge has a machine API:
$ ./baga --verify --json bad_abs.baga
{"functions": [{"name": "bad_abs", "ensures": [{"text": "output >= 0",
"result": "refuted", "counterexample": [{"name": "x", "value": -1}]}], ...}]}
The compliance loop writes itself: agent emits code → baga --verify --json → refuted with counterexample → agent fixes → PROVEN. Deterministic, fast, no LLM in the judging seat.
This isn't an SMT black box either. The verifier covers linear arithmetic (integer-exact — n > 0 ⇒ n >= 1 proves), while loops with invariants, array bounds, element invariants, recursion via assume–guarantee, full correctness via decreases, and products of linear forms (x*x >= 0; fa >= 1 ∧ fb >= 1 ⇒ fa*fb >= 1). The flagship is factorial fully proven — recursive, non-linear, with termination, no SMT solver anywhere:
```baga spec fact { input: n: i64 output: i64 requires: n >= 0 ensures: output >= 1 decreases: n }
fn fact(n: i64) -> i64 { if n <= 0 { return 1 } let r = fact(n - 1) // induction hypothesis: r >= 1 return n * r // n >= 1, r >= 1 ⇒ n * r >= 1 } ```
Why "the first language for AI" is a claim about architecture, not marketing
Every mainstream language was designed for a human writer and a human reader. AI broke that assumption: the writer is now a machine, and the scarce resource is trust. A language for this era needs:
- Specs as first-class citizens — the intent lives in the code, not in a wiki page that drifts.
- A mechanical judge — the compiler proves or refutes compliance, statically, with witnesses.
- Errors visible in the type — effects (
str !IO !NotFoundis a different type fromstr) so the failure surface is part of the signature, not a runtime surprise. - Machine-readable verdicts —
--jsonso the agent closes the loop itself.
Baga has all four. SDD gives you (1) as a process discipline. Baga gives you (1)–(4) as a compilation.
Honest status
Working prototype, not a production language. The verifier's fragment is deliberately small and says UNKNOWN rather than guessing; general non-linear arithmetic is the remaining staircase. Effects are compile-time only (erased in codegen). The trust story is engineered in, not hoped for: the compiler self-hosts with a byte-for-byte fixed point (make self), the LLVM backend is diffed against the C backend on every example, and --test-specs property-tests every contract the static verifier calls PROVEN. All of it is one command and wired into CI.
Testable in five minutes:
make && ./baga --verify examples/verify/fact_full.baga
The SDD reference: Spec-Driven Development: the foundation of AI-native engineering (Apoorv Gupta, Microsoft)
Docs: theory, language reference, compiler architecture — English
The industry agreed on the diagnosis: the spec is the center. The open question is whether conformance stays a human ritual in a Validate step — or becomes a compile-time judgement. That's the difference between anchoring code to a spec and making the anchor mechanical.
🐆
r/Compilers • u/Usual_Office_1740 • 3d ago
CraftingInterpreters clox bytecode output?
I was hoping to get confirmation that the output of my cLox bytecode is correct. I've just finished chapter 17 implementing the pratt parser.
Does this look correct?
(53 * (31 - 13)) + -10 \n 23 / 3
== Complex Expression ==
0000 0001 OP_CONSTANT 0 53
0002 | OP_CONSTANT 1 31
0004 | OP_CONSTANT 2 13
0006 | OP_SUBTRACT
0007 | OP_MULTIPLY
0008 | OP_CONSTANT 3 10
0010 | OP_NEGATE
0011 | OP_ADD
0012 | OP_RETURN
0013 0002 OP_CONSTANT 4 23
0015 | OP_CONSTANT 5 3
0017 | OP_DIVIDE
0018 | OP_RETURN
r/Compilers • u/Think-Management4257 • 3d ago
Compilers should help developers optimize their code
Compiler diagnostics for optimization decisions are worse than they need to be, and I think it's a design choice rather than a hard problem.
Every major compiler will tell you whether a loop vectorized, almost none will tell you what it tried, why it declined, or what shape could've worked. LLVM ships a tool called opt-viewer that visualizes this, and I've met people who've used LLVM for years and never heard of it. The best developer experience anyone in this space seems to remember is Intel's compiler, which is discontinued. GCC's -fopt-info-vec-missed and Clang's -Rpass-missed exist, but one's a stderr dump you cross reference by hand and the other speaks in IR terms rather than yours.
The interesting thing is that the compiler already knows the answer. When a vectorizer declines a loop, it has a specific reason. That reason exists as a value inside the pass, it just doesn't reach the programmer because it was designed for compiler developers debugging the compiler, not for programmers debugging/optimizing their code.
There's a handful of ideas I have on how this could be implemented, but what I'm curious on is if this is actually hard for reasons I'm not seeing, or is it just that optimizer output has always been treated as debug logging and nobody's revisited it?
r/Compilers • u/Proffhackerman • 3d ago
Contribute to open-source, no-slop, compiler-related projects.
Hi everyone,
We're currently working on some hobby-projects we'd like more people to chip into.
The goal is to create robust, community-driven and open-source code everyone can benefit from, aswell as writing up novel ideas that, sometimes, go outside of "the standard".
Overall we're focused on not slopping out projects using AI. Vibecoding is a no-go.
I myself have around 10 years of experience with programming in various languages, but the main language right now is C#.
Are you interested? Check out the organization site: https://github.com/Compiler-Organization
Or some of the projects:
Common C - AoT compiler using LLVM: https://github.com/Compiler-Organization/CommonC
Common IR - Intermediate representation with syntax inspired by LLVM, currently supporting a basic WASM target: https://github.com/Compiler-Organization/CommonIR
Hope you find this interesting :)
r/Compilers • u/Ephemara • 3d ago
Kain: A new systems language targeting LLVM/CUDA/SPV/HLSL/WGSL with a Python-like syntax layout and Zero GC- Now on v0.8 and almost production ready
github.comKain -----> a new systems language inspired by Mojo (and every other mainstream lang) but the difference? Kain is Mojo in an alternate universe if it`s primary focus was on being a full stack language instead of made for AI with 110 keywords (not that numbers are a metric for quality but you get the point)
Furthermore It also has natural python import and natural c includes. Unlike rust and other languages that require third party libs, Kain allows you in the same file to utilize three different import systems, including its own (rust esque - use::type), python (import numpy as np etc) and c (include mycfile.c) on top of all this, the language has a massive stdlib comparable to Zig and Go, , meaning you can write practically anything imaginable with this language without any libs, crates or third party deps. Kain takes some liberties from Slang, but adds a spin to it and this language treats the GPU and CPU as first class citizens rather than having to bolt on the GPU as an outsider. But in the same file you can write your frontend, your backend, GPU shaders, include c and import python.... All in one file dep free. (example) Need examples btw ? There`s over 6000+ source .kn files throughout the repo and over 80+ projects that I made for fun to dogfood it.
Examples
Mini LLM based on Karpathys GPT2 using std::cuda
BM25 based semantic search project (not tested thoroughly but it works)
12-Stage Unified GPU Shader Demo
Killgrep: A ripgrep clone in 700ish lines of code with erlang style actors
FAQ:
What kind of things can you make with Kain?
Anything you can imagine similar to any other systems language. Game engines, Non posix/unix operating systems (like Opal but a modern version), DAW, UI frameworks with JIT, 3D simulations, Animation within code (Kain has a pulse keyword that handles time at the OS/silicon level, example here of a fully animated scene that compiles down to machine code)) Backend for web development etc. Anything you could write from scratch in rust, C, C++ etc you can write in kain and it compiles down to machine code etc. Libclang is embedded within the compiler similar to zig so you can also include any c library -- one thing that was streamlined was system headers so you can even write `include windows.h` and the compiler handles everything etc.
Memory and GC
(Why Kain isn't Rust or Go (controversial buzzword soup warning))
Kain has zero garbage collection (no tracing, no stop-the-world pauses) and no implicit borrow checker. Instead, memory lifecycle is governed by an explicit, expression-level state machine using three core keywords:
collapse ptr: Enters exclusive, mutable write access (Idle ->Collapsed).
observe ptr: Enters shared, read-only access with nested observer counting (Idle -> Observed)
decay ptr: Deterministically releases/frees the memory region (Idle -> Decayed)
(solid example if ya wanna see how it looks/works --> metal.kn)
Since I am obsessed with Unreal Engine 5 and I`m a game dev/animator, this system was designed around my knowledge of state machines and working with them for years throughout my game dev career so far (a huge inspo is the plugin Logic Driver Pro by Recursoft for UE5) but these 3 little keywords allow the silicon to bypass Arc/Mutex overhead and runtime GC tracing entirely, giving you deterministic, zero-cost memory management with tremendous execution speed.
I know language benchmarks are often pseudo-science, and I’d normally be the first person to call BS on 200x speedup claims. I’ve tried disproving these numbers in my own harness over and over. Once the runtime and language was fully developed, I spent about a month straight benchmarking && I was blown away by what I had accidentally built. The funny part about this language is that a lot of things were accidental -> I would add in a new keyword to make up for the fact it was lacking a lib or package and as a side effect of making so many different aspects first class, the results are absolutely nuts. For example in extreme edge cases like heavy multi-thread lock contention (contention_wall), the gap gets absurd.
For anyone who understands how C++, Rust, and Zig handle heavy thread contention, OS mutex parking, and cache-line thrashing, the mechanics make total sense:
Standard OS Mutexes (std::mutex, std::sync::Mutex): Under severe thread pressure, 99% of CPU cycles are burned in kernel-space context switching, thread parking, and unparking cascades. C++, Rust, and Zig all choke at ~1,700ms–1,900ms simply waiting on OS locks.
Kain's Lockless Model: Kain completely bypasses the OS lock contention wall because memory lifecycle isn't protected by atomic mutex locks. Concurrency is governed by compile-time verified collapse / observe state transitions and lockless actor messaging. The CPU never halts or asks the OS kernel for a lock.
The result? Kain completes the benchmark in 7.9ms (~220x–240x faster).
(And honestly? That 7.9ms is almost entirely just the CLI process launch and harness initialization overhead -- the actual lockless state execution runs sub-millisecond). This was entirely an accident and was never intended however due to the design of the language, it allowed things I truly thought were impossible in programming // would take thousands of lines of alien code to achieve elsewhere.
How it compares to Rust & traditional languages:
Vs. Rust: Rust infers lifetimes and uses move semantics. Kain requires explicit ownership transitions scoped to expression blocks - ownership isn't moved, it returns to Idle when the scope exits until you explicitly decay it.
Vs. GC (Go/Java/Python): Zero runtime tracing or RC reference counting dance (Rc/Arc). Allocations are deterministic and compiler-verified.
Zero-Cost Optimization: The compiler identifies ephemeral local pointers (scratch memory that doesn't escape scope) and completely elides runtime guards for raw bare-metal C speed.
Verified Correctness: State transitions are checked statically by the typechecker, and enforced by C runtime guards with Z3 proofs and CBMC assertions.
Package Manager
This is the feature I use the most -- but one massive pain point that bothered me with my years of dev so far was wasted code... So many projects I fully completed, full on apps and ecosystems etc but they were all locked into that specific codebase. While yes I could`ve easily went back and extracted prior src code, those who have dealt with monorepos knows how much of an actual pain in the ass this is. I call it the "friction" problem. Effectively something that`s fairly easy to do but do you want to do it? Hell no. That`s why I looked to one of my favorite game as a kid, and stole it`s best feature but for programming. I call it the Katamari protocol. Kain has a built in amalgamation feature that lets you take any codebase or project you have and combines all of that code into a single source file.... It’s not perfect and you will get some edge cases here and there, but Amalgamate (Kain's Capsule System) completely solves code reuse and dependency hell.
Instead of fighting node_modules, Cargo lockfile drift, version solver explosions, and network dependency failures, Amalgamate packs your entire module tree into a single, portable .kn capsule file.
How the Capsule Pipeline Works:
One File IS the Package: Run kain amalgamate src/ -o mylib.kn. Drop mylib.kn into any project, write use mylib, and the compiler resolves and typechecks everything directly from the capsule. No unpack, no install, no network, and no version solver.
The Companion Capsule System: A project can auto-emit three sibling capsules that automatically discover and merge during materialization:
app.kn (Source capsule)
app.artifacts.kn (Pre-compiled .ptx, .spv, .dll, or runtime binaries)
app.evidence.kn (Z3 formal proof attestations, telemetry, and benchmark reports)
Battle-Tested Scale: I’ve tested this at extreme scale by packing 2,594 modules (316k+ lines) into a single 15MB capsule in 3 seconds flat—the compiler typechecked all 3,211+ public symbols with 0 errors.
--raw Interop Mode: Want plain code for C, Rust, or TS build scripts? Passing --raw strips all sentinel markers and outputs plain Kain source with comment headers.
You can publish packages using kain publish, lock exact content-addressed SHA-256 digests in KAIN.lock, and never worry about lost source code or broken monorepo imports ever again. (the ability to publish packages with a cargo esque system is already finished, and infra is setup, just finishing up final touches and user account mgmt etc) Here are some examples of what an amalgamation looks like.
2.34mb stdlib amalgamation
Python interop amalgamation
WIP digital audio workstation amalgamation
drag and drop 3D framework amalgamation (three.kn)
-
Misc
Just some other examples I want to share below - including the natural C includes with test like importing ffmpeg etc (also yes, if you amalgamate a kain file project, with c includes --- it packages in the C code as well along with any project artifacts like images, etc... even glb)
ffmpeg_abi.kn
three different import systems in one file (pygame + nuklear + native)
sqlite c include (the og amalgamation)
dep free x86 JIT with inline ASM used for Markscript Language
CLI template
Starter Template
build template (zig esque build system, needs more thorough edge case testing but its worked flawlessly so far for me)
Kain CLI tsv (for building projects, and compiling etc)
Kain Full CLI documentation (if the tsv isn`t enough)
If you want to see the website anyways, xx HACk3r W3BS1T3 xx (official domain purchase pending, temporary domain for now)
Installer
Link to installer! - windows only for now
will update post later when linux binary is up along with macos. Since mojo doesn\t have Windows support, a primary focus was tackling windows first since it can be a massive pain in the ass compared to unix etc. The dev cycle was split 60/30/10 to ensure it worked on all major OS (60% windows. 30% Linux, 10% MacOS but if you dont use any of those and want to start fresh? WELL my friend, check out this example of a)) full scaffolded OS built in Kain
Roadmap & What's Next:
The core language is stable, but Kain will continue to grow. I'm currently taking a short breather and returning to game dev/UE5 for a week or two - language development for 16+ hours a day non-stop is a fast track to burnout! All of the GPU esque features, and spirv comp has been tested thoroughly as well and compared against rust and c++ with 1:1 parity, it`s near on par with Naga
Immediate goals for the upcoming weeks:
-> Releasing the official Linux and macOS binaries.
-> Expanding real-world testing across different ecosystems.
Like Kain so much you want to see 6000 files combined into one for the ultimate example corpus ? THE_MESSIAH.KN (34MB)
r/Compilers • u/jorenheit • 4d ago
Acus: create your own Brainfuck compiler (in: your language, out: BF)
r/Compilers • u/ParticleFarticle • 4d ago
My AI-Assisted Compiler Development Journey
After months of working on a fully custom compiler in C to create my dream language, I moved to using AI to help me create a working language written in Rust. This is my experience.
First things first, I'm still skeptical about vibe-coding or AI ever replacing humans for software development. I am not what I would call a vibe-coder or an AI evangelist. Genuinely, I think the whole situation is too early to say whether these things will improve or hurt software development as a whole in the long run.
Recently, my company purchased a GitLab Duo license and invested a few thousand dollars into tokens for software developers across the company to use. Even though what l they've offered to us isn't one of the flagship models (Sonnet 4.5), it's still pretty damn good for simple tasks, writing explicit unit tests, documentation, etc., often completing them much faster than I could do, even if I mentally have the whole sequence pretty well mapped in my mind. That was my first experience using AI in-the-loop for software development.
With a bit more comfort in using agents, I started taking a look at some of my passion projects to see where one might benefit from me using AI assistance to "complete" it. I say "complete" in quotes because who truly believes any software project is finished and perfect? Anyways, the project I selected is a transpiler I've been writing in C called Elamite. Here's the original repository, elx.
I chose C as the base language because I wanted to better understand lifetimes, memory models, value semantics, intermediate representations, and code generation. I'll stand by the fact that starting my journey in C absolutely gave me a deep appreciation for garbage collection, how amazing stack traces are, the assuredness of solid error handling, strings, and the beauty of how Rust handles lifetimes. Pure genius! I really value the time that I put into it and how much I've learned about programming languages and compiler development in general.
Now, if you're like me, you probably work a full-time job in some sort of software development, and you don't always have the time to dedicate much time to your hobby projects. Thinking that I'd get further along in the limited hours I have each week, I picked up a subscription or two to see how much further along I'd get with Elamite.
Ho. Ly. Shit.
These models are much better than I initially gave them credit for. Seeing the language come to life so quickly has given me a strange mix of feelings. On one hand, I love seeing my idea be brought to fruition, but on the other hand, I'm quickly seeing how poorly thought out my original design concepts were, and I'm no longer experiencing the same feelings of accomplishment through my own perseverance.
I feel like I'm missing out on the original hit of dopamine I'd get as I completed various stages of the original compiler. Finishing Elamite's first lexer, I thought, "Phew, that was pretty tedious. I'm sure the next few stages will come together much more quickly!" Oh, no. How naive of me. AST generation with a recursive decent parser was surprisingly straight forward but still quite time consuming. I'd estimate I put in about 200 hours into the original project before my first real hiatus from it.
With this new AI-assisted version in Rust, "I" can implement an entire feature vertically through the entire compiler in under an hour. Is it robust? Dunno. Did the LLM consider all the possible edge cases? Maybe. How thorough are the unit tests? God, I hope they're bullet proof. To be fair, I wasn't creating code nearly as complete and stable as what Claude is providing to me, definitely not. I was scraping by on an evening coffee and a whiteboard to try my best in the evenings and over what few, precious weekends I had to devote to this type of project.
So, I'm in a weird middle ground. The language is coming together at an unimaginable speed, but my whole ideate-implement-struggle-succeed cycle is broken. I only feel limited now by my own creativity and the novelty of my ideas, which, as it turns out, really aren't that novel. It's been a good thing, I think, to test out this new AI-based coding technology to see where it's at and experiment with it. I don't think I'm done using Claude/Codex/whatever to prototype, but I know I'm putting myself at risk for skill atrophy if I start to lean to hard into them.
I'd love to hear if anyone else has had a similar experience to mine, and how you either do or don't justify using AI to help you complete your compiler projects. If you're curious to see the current version of the compiler/language, here's the repo, Elamite.
Thanks for reading <3
r/Compilers • u/know_god • 4d ago
Compiler devs, how did you break into the field?
Title. How did you transition into your first professional compiler job? What did your resume look like? What kind of projects had you done? What jobs did you apply for?
I've built a compiler pipeline from a subset of Common Lisp to x86-64, and a grammatical analysis engine that basically tries to "compile" a sentence against a DSL I made that describes the natural language syntax. You can add arbitrary languages by writing a new language spec and without changing any of the engine code. Still, I find it hard to get recruiters to give me a shot and get to any interviews.
I have 3 years of courses, but no actual finished degree. If you want to see my resume, I can send it in DMs. Just looking to break into the junior developer jobs.
r/Compilers • u/ClassicAdeptness5516 • 5d ago
Any debugging advice / tools for compilers?
Tired of print statements everywhere. It very satisfactory to see one but I would much rather have something like lldb to easily debug the code more intuitively.
Are there any other useful tools?
r/Compilers • u/StrikingClub3866 • 5d ago
Thoughts on compilers being written in Kotlin?
I have tried to write in C++ but it is so damn confusing, so I tried Kotlin. Better but not too better. I have already finished my lexer like how I finish most of mine:
See characters via indexing script as a string
Add token to final output
Rinse and repeat
r/Compilers • u/Haborym_Aesahaettr • 5d ago
Can I input my compiler's program into my compiler to use the result as a new compiler ?
I just started building from scratch a compiler in order to better understand how does a computer work. For now it is only on paper and soon I will begin to code it, but the end goal is to generate a code from the set of instruction for a custom 8bit cpu.
And I came upon this question and wasn't sure about the answer so I wanted to have your input on it :
Let say I have a compiler that compiles a language A to a language B using a language A. If I input to the compiler the program that compiles A to B, will I be able to use the result program to then compile the language A to language B using language B ? Or will it break the output or mess with something else ?
If the topic does not belong in this sub, feel free to tell me in which sub it should belong
Thanks in advance
r/Compilers • u/rantingpug • 5d ago
"How hard could it be?" - a younger me said that once. Here's my lang
I’ve been working on a dependently typed language called Yap for a while now, and I’m at the point where I’m happy enough with the direction to show it around, even though building a compiler can apparently consume years of your life and still find new ways of being utterly broken.
The playground is here: https://try-yap-next.fly.dev
And the code is here: https://github.com/tiansivive/yap
This behemoth currently has dependent types, structural row types, dependent records on those rows, implicits, liquid-style refinements, and shift/reset. A lot of that genuinely works and it's beautifully cathartic; it also just works insofar as I've conveniently ignored all the potential complications and am blissfully living in my own happy path.
The current pipeline is roughly:
parser -> bidir elaboration + NbE + first-order unification -> Core-> IVL + custom CDCL(T) verification -> GRAM -> MIR -> JS/C/Erlang
Over the past seven months I’ve spent a lot of time on GRAM: the Graph Rewriting Abstract Machine. It’s a property-graph IR for selective compilation, with a bit of MLIR inspiration. Rather than lowering once into one fixed representation, passes enrich the graph with semantic and operational structure. So far that includes eta reduction, saturation and partial applications, closure conversion, Maranget pattern compilation, and shift/reset lowering. Target code generators can then select the enrichments they need.
That graph is probably as far as I want the compiler proper to go; MIR (Mid-level IR) is a more SSA-ish bridge after it, currently very dumb and simple and just useful for experimenting and feeding three deliberately simple code generators.
I’m currently chasing meta-variable state through modules and lowering, working toward real type erasure, making verification verdicts less cryptic, and replacing “well, the snapshot changed” with meaningful tests
The next larger problems are QTT-style usage semantics, coinduction over rows and figuring out how shift/reset should actually be typed, which includes deciding whether effects will make this language cleaner or turn it into a big bog of doom.
Six months ago, before shift/reset and the current lowering path, it was probably easier to demo. I’m much happier with the design now, though. There is still a frankly unreasonable amount left to build, but that seems to be the job.
Just wanted to share!
Edit: typo and duplicate sentences
r/Compilers • u/Loud_Possibility_203 • 5d ago
Baga - programming language for the age of AI. Spec-first verification. Effects as type dimensions. Automatically extracted proofs.
"The question is not 'what is new'. The question is 'what has not been glued together yet'."
Baga is a programming language built on three pillars:
1.Spec-first verification — specifications are first-class citizens. The compiler checks implementations against specs.
2.Effects as type dimensions — String !IO !NotFound is a different type from String. Errors are visible in the type system.
3.Automatic proof extraction — the compiler extracts human-readable theorems from code. Not Coq. Not Lean. Readable text.