“I looked at the compiler’s output and thought: this cannot be mine. I couldn’t believe what had happened. I am happier than I have been in 20 years.”

This is a long read — years of work don’t compress easily. If this is not the right moment, bookmark it and come back. I believe it is worth your time.


Prologue: A Seed Planted Thirty Years Ago

In the late 1980s and early 1990s, I was a student, and I built my first compiler. It was a modest academic project, based on materials from ETH Zürich. While it was small, something happened to me during that work — I fell in love with the intricate puzzle of transforming human-readable code into something a machine could execute.

Then life happened. Career. Responsibilities. Decades passed.

By 2023, I had been working in IT for over thirty years. I was successful by most measures. But I felt empty. My profession no longer provided what I craved: innovation. I had always seen myself as a creative person, and that creative part of me was starving.

I didn’t know it yet, but I was searching for something. And I was about to find it.


Chapter 1: The Spark

It started with a small book.

I had begun studying compiler construction again — partly out of nostalgia, partly out of a nameless hunger for something new. I worked through materials from McGill University, from a Danish university, from the Hasso Plattner Institute in Germany, and from ETH Zürich. Somewhere in there I picked up a thin volume on PL/0, the kind of minimal teaching language every compiler course starts from: a handful of keywords, but the complete essence of a compiler — lexical analysis, parsing, symbol tables, code generation. Everything a compiler needs, nothing more.

It was the smallest possible on-ramp. What I did not expect was how far past it I would drive.

When I opened that book, back in 2023, something clicked. I didn’t see a teaching exercise — I saw a path. A dream began to form: what if I could build a compiler that generates real machine code? Not a toy. A real compiler.

I chose Go as my implementation language and VS Code as my editor. I created an empty directory and started typing.

There is one coincidence I have to record, because it sits under everything that followed. Not long after I began, Niklaus Wirth — the Swiss computer scientist whose teaching languages have started generations of programmers, mine included — died quietly at home in Switzerland. He was 89. The man whose little teaching language gave me my first push was gone, just as I took my first step. I have never entirely worked out what to do with that. I say more about him at the very end of this story, where it belongs — as a personal thank-you, not as a claim on what Mica became.


Chapter 2: The Question

As the compiler grew, so did a question I couldn’t put down.

I loved code that reads — code where the structure on the page matches the structure in your head, where you can hand a function to another person and they understand it without a tour. And I respected code that gets out of the way of the machine — direct memory, predictable cost, no runtime you didn’t ask for standing between you and the hardware.

The industry mostly treats those as a trade-off. Readable languages tend to float above the machine; languages that give you the machine tend to demand constant vigilance against your own mistakes. You pick a side.

I didn’t want to pick a side. I wanted clarity and control, in the same language, with no hidden semantics — what you read is what runs.

In 2023 that was just a feeling, not a design. I didn’t yet have the idea that would eventually make Mica genuinely different from the languages it would later be compared to — that came years later, and it is the heart of this story’s second half. But the question was set: could a language be honest about the machine and still be a pleasure to read? Everything after this was, in one way or another, an attempt to answer it.


Chapter 3: Building Piece by Piece

I worked on the compiler alongside my regular job, stealing hours where I could. Piece by piece, it grew.

The scanner came first — the component that reads raw characters and groups them into tokens. Sounds simple; it’s not. Comments, string literals with escape sequences, Unicode, error recovery — I spent weeks on the scanner alone.

The parser came next — building structure from the token stream, understanding that 42 + x * 3 means “multiply x by 3, then add 42.” I implemented a recursive descent parser, where each grammar rule becomes a function. Elegant when it works, maddening when it doesn’t.

The symbol table tracked every declaration. The Abstract Syntax Tree and Semantic Analyzer separated a serious compiler from a simple one.

But there was a problem. I didn’t trust myself to write a machine code generator for AMD64 from scratch. The x86-64 instruction set is enormous, baroque, filled with historical baggage from the 1970s. So I took a different approach: I built a CPU emulator. My compiler would generate code for this virtual machine, and I could test everything without touching real hardware.

The emulator grew more sophisticated. Its output began to look suspiciously like real Intel assembly code.

I didn’t realize it then, but I was setting the stage for something unexpected.


Chapter 4: The Night Everything Changed

I remember that night vividly. My emulator generated output that looked like this:

    mov     rax, 42
    push    rax
    mov     rax, [rbp-8]
    pop     rbx
    add     rax, rbx

The assembly shown above is from those early days — a naive stack-based approach. The code Mica emits today is far more sophisticated.

This was almost valid Intel x86-64 assembly. My emulator executed this internally, simulating a CPU. But the syntax was so close to real assembly that I wondered: what if I just fed it to a real assembler?

I installed GCC on my Ubuntu machine. I took the assembly output from my compiler and fed it to the GNU Assembler. Then I linked it with the GNU linker.

I ran the resulting binary. It worked.

I ran another example. It worked. I ran all my test programs. They all worked.

I sat there in the middle of the night, staring at my screen, trying to process what had just happened. My compiler — my hobby project built from an empty directory — was generating real, executable Linux binaries.

That was the breakthrough.


Chapter 5: A New Name, A New Identity

After that night, everything accelerated. I refactored the compiler fundamentally — implementing a proper AMD64 code emitter, restructuring the entire architecture. And I realized: this was no longer a teaching exercise. This was something new.

Following the tradition of Linus Torvalds, I derived a name from my own first name, Michael: Mica. Beyond the personal connection, mica is also a mineral — known for its layered structure, its transparency, its resilience.

The question that had been growing in my mind came roaring back: clarity and systems control — together?

The first real answer was the System V AMD64 ABI.

I could have invented my own calling convention. Many academic compilers do. Instead, I decided to implement full compliance with the standard Linux calling convention. The payoff: zero-overhead C interoperability. A Mica binary and a C library binary are the same kind of object. They link together directly. No adapter layer. No runtime bridge. No reimplementation required. Every C library on the system became, in principle, reachable from Mica — and because it goes both ways, C code can call Mica routines just as directly.

I then implemented DWARF v5 debug information — the latest standard — enabling professional source-level debugging in GDB and VS Code. This is rare for any new language, let alone a solo project, and it meant something concrete: you can set a breakpoint in Mica code, step across a call into C, inspect variables on both sides, and step back — one debugger, one stack, two languages.


Chapter 6: Into the Valley

Then came the darkest period.

Functions and procedures existed, but they couldn’t take parameters. No arguments. Nothing passed in, nothing passed out. This might sound minor. It’s not. Parameter passing is the backbone of any useful language.

For Mica, it was especially hard because of nested functions. Mica supports functions defined inside other functions, with access to the enclosing scope. This requires static links — pointers chaining stack frames together so inner functions can reach outer variables. The compiler must pass links implicitly alongside regular arguments, generate code following link chains at arbitrary depth, and make all of this work with recursion — while remaining ABI-compatible with C.

The compiler stopped working. Not partially — completely. Every compilation ended in a crash. For weeks, I couldn’t produce a single working binary. I had lost control of my own creation.

I want to be honest: there were moments when I sat in front of my computer and felt like I was failing. Decades of IT experience, and I couldn’t make this work.

The parameter passing crisis was a turning point in more ways than one. It forced a decision I had been avoiding for months.


Chapter 7: First Encounters with AI — The Hard Way

For a long time, I had resisted using AI tools for serious code work. My concerns were real: code quality. Loss of control. Software engineering is not just about producing code that compiles — it is about producing code that is correct, maintainable, and reflects the architectural decisions of someone who understands what they are building.

But eventually, the pain was too great. I was one person with a full-time job, a personal life, a growing codebase, and a vision that was running faster than I could carry it alone. I could not stop — I am full of ideas and I had a goal now written in a roadmap. But I could not continue as before either.

So I began. Slowly. Cautiously. Skeptically.

The first months were genuinely frustrating.

Without consistently giving the AI deep context about Mica’s architecture, design principles, and established conventions, the generated code was wrong in ways that were hard to articulate. It compiled. Sometimes it even ran. But it felt foreign. It did not reflect how I think about code. The naming was off. The structure was off. The code solved the immediate problem but violated the spirit of the surrounding system in subtle ways that only became apparent later.

I hated those sessions.

I kept asking myself: is this actually helping, or am I creating a maintenance problem I’ll spend months untangling? I rejected large amounts of what was generated. I rewrote sections entirely. Some weeks, the AI collaboration felt like it cost me more time than it saved.

What was missing, I eventually understood, was context. Not technical context alone — the kind of context that conveys not just what the code needs to do, but what the code needs to be. How it should feel. What principles it must not violate. Where it fits in a system that has been built by one person with very specific values over years.

That took months to figure out. Not weeks. Months.

I slowly found that AI collaboration worked reliably in specific modes: writing documentation for code that already existed; reviewing a function and finding the edge cases I’d missed; reading and translating the hundreds of pages of ABI and DWARF specifications; completing regular, verifiable tables of instruction patterns; and root-cause analysis when I was too deep in frustration to see straight.

What I learned over those long months is that AI is not a shortcut. It is a tool that requires enormous investment of context and judgment to use well. And learning that took time I did not have, and patience I had to force myself to find.


Chapter 8: The Hardest Stretch

I had been working toward something ambitious: transforming the single-file compiler into a full multi-file compilation platform. Cross-compilation-unit symbol resolution. A global namespace registry. Import and export across source files. Static library creation. The ability to build real programs from multiple Mica files, each compiled independently, linked together as proper ELF objects.

This was not a feature. It was a fundamental architectural rework of the entire compiler.

I was also deeply frustrated. The parameter passing rework had been relentless, and the complexity had simply kept growing. The volume of source code — the compiler itself, the standard library, the VS Code extension, the tutorials, the documentation that all needed to stay consistent — had grown to a size that no longer fit comfortably in one person’s head.

I remember sitting at my desk one night with tears in my eyes. Not from sadness, exactly. From the particular frustration of being on the edge of losing control of something you have poured yourself into for years.

The multi-file rework had broken things I had thought were solid. Regressions appeared in code that had passed tests for months. The compiler, which had felt like mine — which I could navigate in my sleep — had become a stranger again.

I was at the corner of stopping. Not giving up on the vision. But stopping, and accepting that Mica would never become what I had hoped.

I did not stop.


Chapter 9: 4.0.0 — Telling No One

I made version 4.0.0 a reality.

The codebase had more than tripled compared to where it had been. Multi-file compilation worked. Cross-compilation-unit imports worked. Static library creation worked. The compiler could build real, multi-file Mica programs and link them cleanly. It was an extremely hard release to achieve — perhaps the hardest single milestone in the project.

I told four people. Three of them were friends who are not technical. They nodded, smiled, said encouraging things. I don’t think any of them understood what had actually happened. But they saw that something mattered to me, and they supported that. In a project this solitary, that kind of quiet emotional support is what keeps you going when there is no one else watching.

Around this same time, my wife and I formally founded Mica Development UG. This was a decision about commitment as much as about structure. The project had grown beyond a hobby.

There is something I have not written before: there were people who reached out to me during this period who wanted to use Mica for real development work. Actual developers. I discouraged them. I took no money. I was not certain the project would survive long enough to be useful, and I would not have people depending on a compiler that might not make it. I could not take responsibility for other people’s work when I did not yet trust my own.

That is where version 4.0.0 lived: between private pride and honest uncertainty.


Chapter 10: The Wall

Some obstacles you see coming from a distance. Then there are walls — the ones you only discover when you walk straight into them.

A general-purpose programming language needs aggregate types. Records. Arrays. Structures within structures. Packed memory layouts. The ability to pass a ten-field record through three function calls, return it by value, classify it correctly under the ABI, annotate it with debug information, and behave consistently across every combination of nesting and packing.

The System V AMD64 ABI has seventeen pages of rules for aggregate passing alone. Small structs go in registers. Large ones go in memory with a hidden pointer. Mixed structs with float and integer fields get split across register classes. Packed records compress the field layout, removing alignment gaps — which changes every offset calculation downstream. And then there is the recursion: structs containing arrays of structs.

I ran the numbers in my head. The semantic analysis alone would take months. The code generation would take months more. Testing every combination would take… I could not complete the estimate.

I was one person. I had a day job. I had a life. The math did not work — alone.

But something was about to change.


Chapter 11: A Coincidence of Time and Pain

There are moments when the timing of external events aligns in a way that feels almost designed. I am cautious about that kind of thinking. But I also know what that period felt like when it arrived.

The AI services I had been using — cautiously, frustratedly, incrementally — made a step change in their capabilities. Not incremental improvement. A visible, meaningful shift in what they could do with complex, context-heavy work. I had been using them for many months by then. I knew what they could and couldn’t do. I could see the difference clearly.

I made a decision: invest properly. I subscribed to the highest-quality tiers from both OpenAI and Anthropic. It is not cheap. For a solo engineer with a day job, it is a real monthly cost. But I had a vision and a goal I could not abandon. The question was not whether I could afford it. The question was whether I could afford not to.

What followed was a transition that I now describe as moving from AI assistance to AI co-development.

The difference is not about the AI. It is about me.

AI assistance is using an AI to help with a specific task. You remain the sole programmer. AI co-development is a collaboration model where I bring the vision, the architecture, the design principles, and every judgment call — and the AI brings tireless implementation capacity, broad technical knowledge, and sometimes ideas I hadn’t considered. I review every line. I reject what doesn’t fit. I push back when I disagree. But I am no longer carrying the implementation burden completely alone.


Chapter 12: A New Kind of Partnership

I was working on peephole optimization — post-generation cleanup that removes inefficiencies from assembled code. Redundant mov instructions. Dead stores. Back-to-back push/pop pairs that cancel out. I had planned perhaps three passes. I thought of them as optional polish.

Instead, I described the problem in detail: Mica’s instruction representation, the properties I cared about, the patterns I had seen in the generated assembly. Because the context was rich and the problem was well-defined, what came back was also well-structured — a uniform interface for optimization passes, a contract every pass would satisfy so they could be composed and measured and extended without touching each other.

I reviewed every line. I asked questions. I pushed back on structural choices I disagreed with. The result was mine — designed by me, reviewed by me, integrated by me — but I was no longer writing every line from scratch.

We built seventeen optimization passes. In weeks.

I stood back and looked at what we had built, and I felt something I had not expected: unease. Not about the code quality — it was clean, carefully designed, reviewed line by line. The unease was philosophical. Was this still my compiler?

I sat with that question for a while. And then I arrived at an answer.

Every line passed through my eyes. I accepted nothing I did not understand. I rejected suggestions I disagreed with. The architecture remained mine — the design principles, the direction, the values. The AI was not replacing me. It was multiplying me.

The question is not whether AI contributed code. The question is whether I remained responsible for the outcome. Whether I understood it. Whether I could debug it, defend it, extend it.

The answer to all of those was: completely yes.


Chapter 13: Spectra — Naming the Light

Around this same time, I did something that surprised me with how much it mattered: I gave the intermediate language a name.

Every serious compiler has an intermediate representation — a language that sits between the source code a programmer writes and the machine instructions a CPU executes. Mica’s had been nameless for years. “The IL.” An implementation detail.

The name I chose was Spectra.

When a prism intercepts white light, it doesn’t destroy it — it reveals it. White light looks uniform, monolithic, simple. The prism shows you that it is not. It makes visible what was always there, hidden inside apparent simplicity.

Spectra does the same thing to a Mica program. A source line like result := (base + offset) * 2 looks simple. But Spectra reveals what it actually is:

m1.1:int32 = load v1.1:int32
m1.2:int32 = load v1.2:int32
m1.3:int32 = add m1.1:int32, m1.2:int32
m1.4:int32 = literal 2:int32
m1.5:int32 = multiply m1.3:int32, m1.4:int32
store m1.5:int32, v1.3:int32

Every temporary has a name. Every operation is explicit. Every type is annotated. Spectra carries enough information for the emitter to produce correct machine code, and enough structure for optimization passes to reason about what the program does — not just what instructions it emits.


Chapter 14: The Lego System

By this point, the AI co-development model had settled into a rhythm I could describe in one word: Lego.

Lego bricks come in standard shapes with standard connectors. They don’t know what you’re building. They only know how they fit together. The architecture — the structure, the purpose, the vision — is yours. The bricks are the implementation.

When I needed a new feature, I could describe the shape of the missing brick — what it needed to accept, what it needed to produce, which existing bricks it needed to connect to. The AI could draft that brick, in Go, following the established patterns of the codebase. I reviewed it, tested it, corrected it, integrated it.

But here is what made it work — and this surprised me more than anything else: the quality of the existing code determined the quality of what could be added. When the interfaces were clean, new bricks fit cleanly. When the architecture was clear, extensions were clear.

The discipline I had applied over years of solo development — the strict separation of phases, the habit of never letting complexity accumulate without a forcing function to clean it up — suddenly paid dividends I had not anticipated. A good architecture doesn’t just organize existing code. It makes future code better.

The aggregate type implementation that I had estimated would take most of the year was no longer impossible. It was a set of bricks to build. One at a time. Connected to existing bricks. Tested as each piece arrived.


Chapter 15: The Test Fortress

In the middle of all this, the test harness grew into something I had not planned — and could not imagine working without.

The dark months had taught me what it costs to work without a complete safety net. I had been there. I would not go back.

The harness has four layers, each validating a different truth about the compiler. Execution tests compile a Mica program, link it, run it, and compare the output against expected text — byte for byte — proving the complete pipeline is correct. Error tests verify that invalid programs are rejected with the right diagnostic, at the right source location, with the right message. IL tests capture the Spectra output and check it lowers to exactly what I intended. Assembly tests do the same for generated machine code.

What began as a few hundred cases has grown past 4,500 — across roughly 740 test programs, exercised in every compiler configuration. They are not regression tests bolted on after the fact. They are the specification of what the compiler can do.

I think about what this harness would have meant in the dark months, when the parameter passing implementation broke everything and I spent days tracing crashes in the dark. With this harness, every regression surfaces within seconds. The test fortress does not prevent bugs. Nothing does. But it makes bugs impossible to hide for long — and it gives you the courage to make large changes, because you know immediately whether something broke.


Chapter 16: Closing the Aggregate

The thing I had believed was impossible.

Aggregate types — records, arrays, packed records, packed arrays, nested combinations of all of the above — are fully implemented in Mica. End to end. Scanner through DWARF v5 debug information.

Not “work for simple cases.” They work. Full field selection through multi-level selector chains. Multi-dimensional array indexing. Pass by value. Return by value. The seventeen-page ABI classification for mixed integer and float fields. Packed layouts. DWARF type descriptions that GDB reads with correct field names, offsets, and nesting.

There is a specific moment I want to record. Not the final green test run — those come after the work. I was testing a function that takes a record with four fields and returns a different record with two. The first time I ran it, a field was off by four bytes. Earlier in the project, I would have spent days on this. Now, I added an IL test for that exact function, saw the wrong field offset in the Spectra output, located the layout calculation in forty minutes, fixed the off-by-four, and ran the full suite.

Green.

The moment when you have enough infrastructure that debugging a genuinely hard problem feels manageable — that is a different kind of milestone than shipping a feature. It means the architecture has matured enough to support itself.

That was version 4.5: a clean, structured, fast-enough language with a real type system. And it was exactly here that I made my mistake.


Chapter 17: The Fourth Path

When I tried to explain Mica to other developers, I led with what I had: it’s readable, it’s structured, it compiles to fast native code, it talks to C. Every time, I watched the same thing happen. People nodded, mentally filed Mica next to languages that already do that, and asked the question that deflates you: “So why wouldn’t I just use what I already have?”

They weren’t wrong to ask. At 4.5, I hadn’t yet built the thing that made Mica worth choosing. I’d been describing the body of the language and calling it the point. The point didn’t exist yet. So I built it.

Version 5.0.0 is where Mica stops being “another readable systems language” and becomes its own thing. It rests on two pillars I’d been circling for years.

First: speed, measured honestly. I stopped guessing about performance and started measuring it against gcc -O2, instruction for instruction. Early on, Mica was 3.8 to 11 times slower. I pulled the optimizer apart and rebuilt the middle and back end properly: IL inlining, a control-flow graph, SSA construction, dataflow and liveness analysis, graph-coloring register allocation, and a per-architecture peephole pass. The numbers moved. Today, on core benchmarks, Mica runs at gcc -O2 parity — Mandelbrot executes below gcc’s retired-instruction count on both x86-64 and ARM64; a numerically heavy benchmark sits at cycle parity; and a hundred-thousand-line program compiles, fully optimized, in about five and a half seconds.

Second — and this is the real one: memory safety the compiler proves. There are only three known ways to handle the heap, and each pays a different price. Garbage collection pays at runtime — pauses, overhead, timing you don’t control. A borrow checker pays in the type system — lifetimes to annotate, a checker to satisfy. Manual malloc/free pays in safety — leaks, use-after-free, the debugger at 2 a.m.

Mica takes a fourth path. The same flow machinery the backend already runs to schedule registers, I turned on lifetimes. Every heap allocation creates an obligation that the compiler must see discharged on every path through your function — by freeing it, by handing it to an owner, or by returning it to the caller. If a path would leak it, the program does not compile. Use-after-free and double-free are compile errors too, inferred the same way. No garbage collector. No borrow checker. No lifetime annotations to write.

And here is the part I am proudest of, because it is the honest part. Where a pointer’s flow runs past what the analysis can follow, Mica does not guess and it does not pretend. It tells you — in plain source order — exactly which allocations it could not prove, and a checked build turns any residual mistake into a loud, source-located trap instead of silent corruption. The guarantee is precise: a leak of a tracked allocation is inexpressible; everything else is caught, never hidden. Conservatism costs you a keyword — never a miscompilation, and never a rejected correct program.

I won’t pretend this came out clean. The plan for the heap grew enormous — axes, tracks, tiers, a dozen design documents, more than one night where I genuinely lost the thread of my own roadmap. But the discipline held where it counted: I rolled the safety contract out as a warning first, let the entire test corpus rehearse against it, and only then flipped it to a hard error — a one-line change, because everything was already green. What looked like chaos in my planning notes produced something solid in the compiler.

This is the answer to “why not just use what I already have.” It is not a slogan. It is a category the mainstream doesn’t occupy, and you can clone the repository and watch a four-line program refuse to compile because it would leak.


Chapter 18: Coming Out of Silence

I am more than sixty years old. I started the project of my life, and for most of the time I have been building it, I have been silent. No public posts. No progress updates. A handful of friends who supported me without understanding what I was doing.

Part of the silence was practical: the compiler was not ready. Part of it was something else. For a long time, I felt a kind of guilt about the collaboration with AI. Was I being honest when I described this as my compiler?

I have worked through that question carefully. My answer is: yes. Mica is mine.

Every design decision is mine. Every architectural judgment is mine. I review every line that enters the codebase. I reject what doesn’t fit, what I don’t understand, what violates the principles I have been building toward. The AI services I work with don’t have a vision for Mica. I do.

These days I no longer think of myself purely as a solo developer. I think of myself as the lead of a development team with very unusual members — ones who are available on Sunday mornings, in the middle of the night, at whatever pace the problem demands, without impatience and without ego. I still review and approve every single line. I still control every direction. But I am not carrying the full implementation weight alone anymore. That is the honest version of the story, and I am done being quiet about it.

I am writing now because I believe there is a version of this conversation — about AI co-development, about what it means for software authorship, about how a single engineer can take on an ambitious long-range project in the second half of life — that is worth having honestly. The Internet has plenty of fear and plenty of hype. I have neither. I have many months of hard experience, a lot of frustration, and a compiler I am proud of.

That is why I am coming out of silence.


For Niklaus Wirth

I need to end with something personal.

Professor Niklaus Wirth died, quietly, at home in Switzerland, at 89. Most of the world gave him a few polite lines and moved on. I noticed.

He was a role model from my student years. His little teaching language is what put me back in front of an empty directory in 2023, more than thirty years after my first compiler. I never met him, and he never knew I existed — but the way any student can feel connected to a teacher who shaped their thinking, I feel connected to him.

I want to be clear about what this is and isn’t. Mica is not a continuation of his languages, and I am not claiming his mantle. Mica is its own language, with its own ideas, and it has to stand or fall on those. This is simpler than a lineage. It is a thank-you.

He made me want to start. The rest is mine.


Where the Story Doesn’t End

Mica 5.0.0 is a complete, tested, optimizing native compiler for Linux x86-64 and ARM64. It produces real ELF binaries with DWARF v5 debug information, links directly against any C library on the system, runs at gcc -O2 parity on core benchmarks, and proves heap memory safe at compile time. The road ahead is still long.

Finishing 5.0. Rounding out the heap for owned data structures, and the dynamic-data and string surface — the last of the language-completion work.

The standard library. The full surface a developer expects, built on the principle that has guided the whole project: Mica does not try to replace the C and POSIX ecosystem — it opens it. The libraries already exist, already tested, already running on billions of machines; the goal is to reach them safely from readable Mica source.

The AI track — version 6.0, targeted for late 2026. This is the long-range direction, and I will describe it as exactly what it is: a plan, not a present feature. Built-in vector and matrix types with compile-time shape checking, CPU SIMD lowering, and compiler-native automatic differentiation — the connection between structured, readable, explicitly-typed code and the numerical work that machine learning demands. It is where I believe a fast, memory-safe, honest language can earn a place that today’s general-purpose languages have left empty. It is not finished. The foundation under it is.

I hope Mica finds its way into real use. I hope it builds a community of people who want to understand what their compiler is doing — people who believe clarity and power are not opposites. That community does not exist yet.

This is its first honest invitation.


Technical Summary

ParadigmStatically typed, compiled, procedural, with compile-time generics
Memory safetyHeap lifetimes proven at compile time by flow analysis — leaks, use-after-free, and double-free are build errors; no GC, no borrow checker, no lifetime annotations; runtime-checked backstop for what flow cannot prove
Type SystemStrong, ABI-aware: integers, floats, booleans, characters, enumerations, subranges, sets, records, arrays, pointers, files; compile-time generics
Performancegcc -O2 parity on core benchmarks (Mandelbrot below gcc’s retired-instruction count on both architectures)
C InteropZero-overhead and bidirectional via the platform ABI; JSON contract model; cross-language Mica↔C debugging
Intermediate LanguageSpectra (typed three-address code)
OptimizerIL inlining, CFG, SSA, dataflow/liveness, graph-coloring register allocation, per-architecture peephole
Compiler~100,000 lines of pure Go, zero external dependencies, no LLVM, no GCC backend
Test Harnessover 4,500 cases across execution, error, IL, and assembly layers
TargetLinux x86-64 (System V AMD64) and ARM64 (AAPCS64); ELF + DWARF v5; static (.a) and shared (.so) libraries
Scale2,799 commits since 2023; current version 5.0.0 (in development)
LicenseMCL-1.0 (non-commercial; commercial licensing available)

Resources


Timeline

The student years   First compiler — a student project
     ↓
A career in IT      Decades in the profession
     ↓
2023                A return to compiler construction — the journey begins
     ↓
The early builds    First working compiler, AST, semantic analysis
     ↓
The breakthrough    Native x86_64 code generation works
     ↓
The long road       Full x86_64 + DWARF v5; the parameter-passing crisis; the multi-file rework
     ↓
A platform          v4.0.0 — multi-file compilation; Mica Development UG founded
     ↓
AI co-development   Spectra IL named; the optimizer; the test harness matures
     ↓
v4.5                Control flow complete, aggregate types closed — a clean structured core
     ↓
2026 · v5.0.0       gcc -O2 parity; ARM64; the heap and compile-time-proven memory safety
     ↓
The road ahead      Stdlib and data types; then the 6.0 AI track — vector/matrix math, SIMD, autodiff

If you have a dream you have been putting off — something that seems too big, too late, too impossible — I hope this story encourages you to start anyway. The wall you are afraid of might be the one that teaches you something you cannot learn any other way.