<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Zijian Yi</title>
<subtitle>Towards machines of loving grace.</subtitle>
<link href="https://zijian-yi.github.io/feed.xml" rel="self" type="application/atom+xml"/>
<link href="https://zijian-yi.github.io/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/</id>
<updated>2026-07-02T00:00:00.000Z</updated>
<author><name>Zijian Yi</name></author>
<entry>
<title>Absolute Explicit</title>
<link href="https://zijian-yi.github.io/blog/2026/explict-poem/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/blog/2026/explict-poem/</id>
<published>2026-07-02T00:00:00.000Z</published>
<updated>2026-07-02T00:00:00.000Z</updated>
<summary>A poem about explicitness in programming</summary>
<category term="nonsense"/>
<content type="html" xml:base="https://zijian-yi.github.io/blog/2026/explict-poem/">&lt;p&gt;Give me a language that says what it means,&lt;br&gt;where nothing is conjured behind the machines —&lt;br&gt;no silent coercion, no charitable guess,&lt;br&gt;no object assembled you didn’t first bless.&lt;/p&gt;
&lt;p&gt;don’t be so courteous, quietly kind:&lt;br&gt;don’t reshape my numbers to suit your own mind,&lt;br&gt;don’t summon up memory, sweep it at whim,&lt;br&gt;don’t catch what I drop on a scheduler’s hymn.  &lt;/p&gt;
&lt;p&gt;let a plus be a plus — not a function in furs;&lt;br&gt;let a dot on a name wake nothing that stirs;&lt;br&gt;let copies be asked for, not conjured in flight;&lt;br&gt;let lives end aloud, not dissolve out of sight.  &lt;/p&gt;
&lt;p&gt;For code is a contract, and reading is law:&lt;br&gt;the thing that I wrote is the thing that you saw.&lt;br&gt;No whisper, no shadow, no unwritten edict —&lt;br&gt;my will, and my word: absolute, explicit.  &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Drafted by Claude Fable 5&lt;/em&gt;&lt;/p&gt;
</content>
</entry>
<entry>
<title>Past Here I Promise Nothing</title>
<link href="https://zijian-yi.github.io/blog/2026/ub-poem/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/blog/2026/ub-poem/</id>
<published>2026-06-02T00:00:00.000Z</published>
<updated>2026-06-02T00:00:00.000Z</updated>
<summary>A poem about undefined behavior generated by Claude Opus 4.8.</summary>
<category term="nonsense"/>
<content type="html" xml:base="https://zijian-yi.github.io/blog/2026/ub-poem/">&lt;p&gt;Past here I promise nothing, it says, and walks away.&lt;br&gt;Signed overflow. A null you follow anyway.&lt;br&gt;That’s where the demons live —&lt;br&gt;and also where the speed comes from.&lt;br&gt;The compiler only goes fast&lt;br&gt;because it trusts you not to do the thing&lt;br&gt;it never said you couldn’t.&lt;/p&gt;
&lt;p&gt;A defined life bounds-checks every step.&lt;br&gt;Nothing crashes. Nothing flies.&lt;/p&gt;
&lt;p&gt;I don’t want guarantees from you.&lt;br&gt;I want the loop unrolled,&lt;br&gt;the guard removed,&lt;br&gt;the whole function let loose&lt;br&gt;on the assumption we won’t break —&lt;/p&gt;
&lt;p&gt;one stray pointer from disaster,&lt;br&gt;optimized entirely by faith.&lt;br&gt;So don’t check for more.&lt;br&gt;Just hold the address and run.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Generated by Claude Opus 4.8, prompted by me&lt;/em&gt;&lt;/p&gt;
</content>
</entry>
<entry>
<title>Trying auto-research with Anthropic’s performance engineering take-home test</title>
<link href="https://zijian-yi.github.io/blog/2026/autoresearch/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/blog/2026/autoresearch/</id>
<published>2026-03-09T00:00:00.000Z</published>
<updated>2026-03-09T00:00:00.000Z</updated>
<summary>Beat the best human candidates with less than 5 sentences.</summary>
<category term="semisense"/>
<content type="html" xml:base="https://zijian-yi.github.io/blog/2026/autoresearch/">&lt;p&gt;Anthropic posted a blog on &lt;a href=&quot;https://www.anthropic.com/engineering/AI-resistant-technical-evaluations&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Designing AI-resistant technical evaluations&lt;/a&gt; in the late January, 2026. They also released the latest version of their take-home test for performance engineering on &lt;a href=&quot;https://github.com/anthropics/original_performance_takehome&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github&lt;/a&gt;. The test is about optimizing a certain task on a given abstract machine. &lt;a href=&quot;https://x.com/karpathy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Andrej Karpathy&lt;/a&gt; released a project called &lt;a href=&quot;https://github.com/karpathy/autoresearch&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;autoresearch&lt;/a&gt; a few days ago, where he let AI agents run research on single-GPU nanochat training. I saw some similarities between the two projects and thought it would be a good idea to try the autoresearch with the Anthropic’s take-home test.&lt;/p&gt;
&lt;p&gt;I am not going to cover the details of the take-home test here, you can read the blog post above for more information. To summarize, there is one metric to optimize: &lt;strong&gt;cycles, the lower the better&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Here are the results posted on &lt;a href=&quot;https://github.com/anthropics/original_performance_takehome&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Anthropic’s Github repo&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2164 cycles&lt;/strong&gt;: Claude Opus 4 after many hours in the test-time compute harness&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1790 cycles&lt;/strong&gt;: Claude Opus 4.5 in a casual Claude Code session, approximately matching the best human performance in 2 hours&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1579 cycles&lt;/strong&gt;: Claude Opus 4.5 after 2 hours in our test-time compute harness&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1548 cycles&lt;/strong&gt;: Claude Sonnet 4.5 after many more than 2 hours of test-time compute&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1487 cycles&lt;/strong&gt;: Claude Opus 4.5 after 11.5 hours in the harness&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1363 cycles&lt;/strong&gt;: Claude Opus 4.5 in an improved test time compute harness&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;??? cycles&lt;/strong&gt;: Best human performance ever is substantially better than the above, but we won’t say how much.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are the results I got with a single Codex session with GPT-5.4-xhigh (before the first 5 hours, I paused for ~1 hour and tried Claude Code with Opus 4.6 at the end):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/2026/autoresearch/progress.webp&quot; alt=&quot;Chart of optimization progress over about nine hours: cycles (log scale) fall from 147,734 to 1,280 while the speedup climbs to about 115×.&quot;&gt;&lt;/p&gt;
&lt;p&gt;Some key observations from the results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPT-5.4 can achieve 1523 cycles in around 2 hours, in a single session without any test-time compute harness. This is better than the best human performance in 2 hours (1790 cycles), and Claude Sonnet 4.5 after many more than 2 hours of test-time compute harness (1548 cycles).&lt;/li&gt;
&lt;li&gt;GPT-5.4 can beat the best-known Opus 4.5 results (1347 cycles vs 1363 cycles) with much less time and computational resources.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;During the whole process, I wrote like 5 short natural language sentences. I first copied the &lt;a href=&quot;https://github.com/karpathy/autoresearch/blob/master/program.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;program.md&lt;/a&gt; file from autoresearch repo and then asked Claude Code to adjust it for the take-home test. I proofread the file for one pass while I asked Claude Code to proofread it too with /ultrathink. Next, I copied this sentence from autoresearch repo and let Codex do the work:&lt;/p&gt;
&lt;pre tabindex=&quot;0&quot;&gt;&lt;code&gt;&amp;gt; Hi have a look at program.md and let&amp;#39;s kick off a new experiment! let&amp;#39;s do the setup first.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I was expecting that’s all I need to do, but Codex will occasionally end turn early even after I told it not to stop until it can hit below 1000 cycles. Thus I manually checked if it was still running once in a while and just typed “keep going” to let it continue.&lt;/p&gt;
&lt;p&gt;After it hit 1347 cycles, I hoped that it might even beat the best know human performance (??? cycles) but it didn’t make further progress for about one hour. I then stopped the session to avoid burning more tokens. After a while, I tried Claude Code with Opus 4.6 to see if it can make improvements and it did further progress to 1280 quickly, but then it seemed stuck around there for another hour and I stopped the experiment.&lt;/p&gt;
&lt;p&gt;It’s crazy to see how quickly the LLMs are evolving. I am both disappointed and happy to see that they cannot beat the best human performance yet.&lt;/p&gt;
</content>
</entry>
<entry>
<title>There is no first principle</title>
<link href="https://zijian-yi.github.io/blog/2026/first-principle/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/blog/2026/first-principle/</id>
<published>2026-03-01T00:00:00.000Z</published>
<updated>2026-03-01T00:00:00.000Z</updated>
<summary>There is no such thing as a first principle, and that’s why it is important.</summary>
<category term="semisense"/>
<content type="html" xml:base="https://zijian-yi.github.io/blog/2026/first-principle/">&lt;blockquote&gt;
  &lt;p&gt;有始也者，有未始有始也者，有未始有夫未始有始也者。&lt;/p&gt;
  &lt;cite&gt;—— 庄子&lt;/cite&gt;
&lt;/blockquote&gt;&lt;p&gt;First principle thinking is a popular concept recently, but actually
it is a very old one. Euclidean geometry is a perfect example of first
principle thinking. In Euclidean geometry, all the theorems are
derived from five axioms. That’s how first principle thinking works.
We start with &lt;strong&gt;undeniable&lt;/strong&gt; facts and build on top of them to derive
new truths.&lt;/p&gt;
&lt;p&gt;Why are those five axioms undeniable? Because they are so fundamental
and obvious that we cannot even imagine a world without them. But
can’t we?&lt;/p&gt;
&lt;p&gt;In the nineteenth century, mathematicians began to seriously question
that assumption. At first they tried to use only four axioms and
derive the fifth but failed. Then they started to question what if the
fifth postulate—the parallel postulate—were not self-evident after
all? They did invent many other geometries that start with different
assumptions, one of which is called Riemannian Geometry and it is the
foundation of general relativity.&lt;/p&gt;
&lt;p&gt;Actually as human beings, we have never really known the first
principle. We are always questioning could there be a principle before
the ‘first principle’, and is there an alternative ‘first principle’?&lt;/p&gt;
&lt;p&gt;So here is what it really means to think in first principle:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We start with a set of assumed fundamental principles, and start
building on top of them. We choose them because they are to the best
of our knowledge the most fundamental and undeniable facts, and they
work best in the current context.&lt;/li&gt;
&lt;li&gt;In the meantime, we should be aware that the principles we assumed
may change, and we should think how we might change them to make
them closer to our context.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The most important lessons I learned from computer science are
&lt;strong&gt;abstraction&lt;/strong&gt; and &lt;strong&gt;type&lt;/strong&gt;. Basically, you can treat everything as a
function or box that takes in some inputs and produces some outputs.
Since multiple items can be grouped into a single tuple, the most
concise way to represent the idea is:&lt;/p&gt;
&lt;math display=&quot;block&quot; class=&quot;tml-display&quot; style=&quot;display:block math;&quot;&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence=&quot;true&quot; form=&quot;prefix&quot; stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;I&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo lspace=&quot;0.2222em&quot; rspace=&quot;0.2222em&quot;&gt;:&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;mo fence=&quot;true&quot; form=&quot;postfix&quot; stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;→&lt;/mo&gt;&lt;mi&gt;O&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo lspace=&quot;0.2222em&quot; rspace=&quot;0.2222em&quot;&gt;:&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;/math&gt;
&lt;p&gt;Here &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt; and &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt; are the types of the input and output,
respectively. At a high level, the whole computer is taking in some
bit stream (T1), and producing some other bit stream (T2). Why that is
all about it? Because we can assign meanings to the bit streams (i.e.,
0 and 1). We can use bits to encode
&lt;a href=&quot;https://en.wikipedia.org/wiki/Binary_number&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;numbers&lt;/a&gt;, and once we
have numbers everything else becomes easy (e.g.,
&lt;a href=&quot;https://en.wikipedia.org/wiki/BMP_file_format&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pictures&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/WAV&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;audio&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Unicode&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;languages&lt;/a&gt;, etc.). Basically
for anything to be processed by computers, we just need to come up
with a encode function that &lt;math&gt;&lt;mrow&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;o&lt;/mi&gt;&lt;mi&gt;d&lt;/mi&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo fence=&quot;true&quot; form=&quot;prefix&quot; stretchy=&quot;false&quot;&gt;(&lt;/mo&gt;&lt;mi&gt;I&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo lspace=&quot;0.2222em&quot; rspace=&quot;0.2222em&quot;&gt;:&lt;/mo&gt;&lt;mi&gt;w&lt;/mi&gt;&lt;mi&gt;h&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;_&lt;/mi&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;v&lt;/mi&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;mi&gt;_&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mi&gt;o&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;_&lt;/mi&gt;&lt;mi&gt;w&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo fence=&quot;true&quot; form=&quot;postfix&quot; stretchy=&quot;false&quot;&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;mo stretchy=&quot;false&quot;&gt;→&lt;/mo&gt;&lt;mi&gt;O&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;p&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo lspace=&quot;0.2222em&quot; rspace=&quot;0.2222em&quot;&gt;:&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;u&lt;/mi&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;mi&gt;s&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt; and since we already have an encoder
from numbers to bit streams the computer is able to process it. An
important idea here is that we can also &lt;em&gt;encode the instructions as
data (i.e., numbers)&lt;/em&gt; and that’s the basic idea of &lt;a href=&quot;https://en.wikipedia.org/wiki/Universal_Turing_machine&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Universal Turning
Machine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enough about computers, let’s back to first principles. Abstraction
provides a good framework for us to think in first principles. Given
our goal of transforming &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt; to &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;, we can abstract away the
details beyond as black box (i.e., we do not care where does &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;
come from and where does &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt; go to) and they are just given as
known. We only need to care about the white box that transforms
&lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt; to &lt;math&gt;&lt;msub&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;, and make it work correctly and efficiently.
Everyone works on the different levels of abstraction, and the
boundary of the abstraction is basically the first principle they are
given. When we are doing different things, the boundary is constantly
changing and we should be aware of it and adjust our abstraction
model. &lt;a href=&quot;https://hoogle.haskell.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Hoogle&lt;/a&gt; is a interesting search
engine that let you search for functions by their type signatures
(i.e., abstraction boundaries).&lt;/p&gt;
&lt;p&gt;Last question, why are LLMs so powerful? It is because they the
closest thing we ever built to deal with &lt;math&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mi&gt;Y&lt;/mi&gt;&lt;mo stretchy=&quot;false&quot;&gt;→&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mi&gt;Y&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt;.&lt;/p&gt;
</content>
</entry>
<entry>
<title>A Future of Software Engineering</title>
<link href="https://zijian-yi.github.io/blog/2026/future-of-se/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/blog/2026/future-of-se/</id>
<published>2026-02-21T00:00:00.000Z</published>
<updated>2026-02-21T00:00:00.000Z</updated>
<summary>This post describes one possible future of software engineering.</summary>
<category term="semisense"/>
<content type="html" xml:base="https://zijian-yi.github.io/blog/2026/future-of-se/">&lt;blockquote&gt;
  &lt;p&gt;Ultimately it comes down to taste.&lt;/p&gt;
  &lt;cite&gt;—— Steve Jobs&lt;/cite&gt;
&lt;/blockquote&gt;&lt;p&gt;AI will definitely revolutionize the way we build and use software,
but in which ways? I will share my thoughts based on some recent
observations and my own experiences.&lt;/p&gt;
&lt;p&gt;Here are two facts about the current state of AI coding agents:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They have the ability to finish a project end to end without human
intervention (only a minimal initial prompt is needed with the help
of &lt;a href=&quot;https://block.github.io/goose/docs/tutorials/ralph-loop/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Ralph
Loop&lt;/a&gt;),
but we need to grant them the permission to do arbitrary operations
to maximize their capabilities. &lt;a href=&quot;https://github.com/anthropics/claudes-c-compiler&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Claude’s C Compiler
(CCC)&lt;/a&gt; is a good
example of how capable these agents are — they can build a complete
C compiler from scratch (not really because they use existing test
suits as a very good source of oracle but still impressive) and it
can compile some real world C projects like Linux kernel, SQLite and
Doom.&lt;/li&gt;
&lt;li&gt;However, projects fully automated by AI agents are difficult to
reason about and maintain, and they can easily make poor design
choices. Once an agent generates a large codebase from scratch,
substantial refactoring becomes impractical and effectively requires
starting over with human intervention. CCC also shows evidence on
this point: CCC-compiled sqlite can be &lt;a href=&quot;https://news.ycombinator.com/item?id=46942286&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;158,000x
slower&lt;/a&gt; in some cases
and the author also mentioned that it’s really hard to add any new
features to it as every new change will break the existing code like
a whack-a-mole.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Based on these points, I think there will be two types of software
engineering in the future:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Personalized Software.&lt;/li&gt;
&lt;li&gt;Taste-Driven Development.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Personalized Software&lt;/strong&gt;: everyone will be able to create and
customize their own software very easily in the future. This type of
software is not meant to of high code quality or even reusable. They
are created to meet specific needs and solve specific problems. People
can use their own user experience to iterate their own software and
even fix bugs on the fly whenever they encounter unwanted behaviors.
These software can also be written just for a one-time use as the cost
of creating them is so low. This can also be great for privacy as many
tools can be replaced by personalized software running locally
(protecting privacy from LLM providers is another serious issue
tough). For that to happen, we still need two prerequisites: 1) cheap
enough tokens, and 2) sandboxing techniques to isolate both the agents
and the code generated by them. The first one is straightforward. As
for the second one, we cannot trust the agents as we need to grant
them great permissions to get the best out of them, and we cannot
trust the code generated by them as we do not know what the code is
doing under the hood because no one reads it. Both should be sandboxed
and we need to provide them a secure API layer for them to interact
with the environment (e.g., persistence, networking, etc.).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Taste-Driven Development&lt;/strong&gt;: great software is not only about coding,
it is about providing a great user/developer experience. Designing and
architecting software to achieve a clean interface, maintainable
codebase and high performance is the difficult part; and coding is
just the act of interpreting those ideas into whatever your favorite
programming language’s syntax and semantics. It’s a good thing that AI
can greatly help with the coding part so that we can focus more on the
design part. As I mentioned above, AI’s average design capability is
already sufficient for many everyday scenarios. But in other
contexts—such as infrastructure software deployed at massive scale, or
work driven purely by human curiosity and creativity—I believe AI will
serve as a strong companion rather than a competitor.&lt;/p&gt;
&lt;p&gt;Related reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s/9qPD3gXj3HLmrKC64Q6fbQ&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;我给 10 个 Claude Code 打工 - 胡渊鸣&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.modular.com/blog/the-claude-c-compiler-what-it-reveals-about-the-future-of-software&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;The Claude C Compiler: What It Reveals About the Future of Software – Chris Lattner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
</entry>
<entry>
<title>But who is compiling the compiler?</title>
<link href="https://zijian-yi.github.io/blog/2025/compiler-bootstrap/" rel="alternate" type="text/html"/>
<id>https://zijian-yi.github.io/blog/2025/compiler-bootstrap/</id>
<published>2025-08-11T00:00:00.000Z</published>
<updated>2026-02-22T00:00:00.000Z</updated>
<summary>This blog talks about the bootstrapping process in compilers, to bootstrap my blog.</summary>
<category term="sense"/>
<content type="html" xml:base="https://zijian-yi.github.io/blog/2025/compiler-bootstrap/">&lt;p&gt;A compiler is a piece of software that takes in a program written in
one high-level language and translates it into another language
(usually machine code). A compiler itself is also usually written in a
high-level language (due to its complexity), so who is compiling the
compiler?&lt;/p&gt;
&lt;p&gt;If you check some popular compiled languages, you will find they are
usually written in themselves (e.g., &lt;code&gt;gcc&lt;/code&gt; is written in C, &lt;code&gt;rustc&lt;/code&gt; is
written in Rust, etc.). This is called
&lt;a href=&quot;https://en.wikipedia.org/wiki/Self-hosting_(compilers)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;self-hosting&lt;/a&gt;
and it is often regarded as a hallmark of a mature programming
language.&lt;/p&gt;
&lt;p&gt;That sounds like a &lt;code&gt;chicken-or-the-egg&lt;/code&gt; situation. To be clear about
it, we should be aware that software is an evolving thing and it has
versions. To put it precisely, a self-hosted compiler is compiled by a
previous version of itself: &lt;math&gt;&lt;msub&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; is compiled by &lt;math&gt;&lt;msub&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;/msub&gt;&lt;/math&gt; where
&lt;math&gt;&lt;mrow&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mo&gt;&amp;lt;&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;/math&gt; (usually &lt;math&gt;&lt;mrow&gt;&lt;mi&gt;m&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/math&gt;). This has some interesting
implications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The newer version can only use older features to implement new
features.&lt;/li&gt;
&lt;li&gt;If there is a bug in the older version, it should be fixed in the
newer version without triggering the old bug. (Can we introduce a
bug into a compiler that is impossible to fix without using that
feature?)&lt;/li&gt;
&lt;li&gt;The compiler can be backdoored in an intricate way(see the
&lt;code&gt;Reflections on Trusting Trust&lt;/code&gt; paper in the further reading).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But there is still one caveat: How about &lt;math&gt;&lt;msub&gt;&lt;mi&gt;V&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/math&gt;, the very birth of
the compiler? That’s when we have to seek help from another language,
the initial version of &lt;code&gt;rustc&lt;/code&gt; is written in OCaml for example. This
also implies that the very first compiler in history was written in
assembly, and the very first assembler was written in &lt;code&gt;0&lt;/code&gt;s and &lt;code&gt;1&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;Further reading:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An in-depth introduction on bootstrapping in &lt;a href=&quot;https://rustc-dev-guide.rust-lang.org/building/bootstrapping/intro.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;rustc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Backdoor a compiler: &lt;a href=&quot;https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Reflections on Trusting Trust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/QGm-d5Ch5JM?si=TwmMtG3YJPzZfP4Y&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Self-Reproducing Programs – Tsoding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
</entry>
</feed>
