Who do you write code for?

“No matter what people tell you, words and ideas can change the world.”
— Robin Williams

I’ve always taken pride in my ability to write code that is clear, concise, and efficient.
This skill didn’t come solely from years of formal education or professional training — it also grew from experience, trial and error, and countless quiet realizations along the way.

But at some point, I came to understand something simple yet profound:
The code I write is not for compilers or interpreters. It’s for people.

That realization didn’t arrive overnight — it took reflection and time.


The Compiler-Driven Phase

During my early years of learning, my main goal was just to get the code to run.
A single misplaced character could waste hours of debugging.
My focus was on eliminating red underlines, deciphering error messages, and making sure my syntax pleased the compiler.

Even when my program finally executed, the results often didn’t match my expectations.
Back then, it felt like I was writing code to appease the machine — trying to earn its approval, not understanding the logic behind it.


The Clever-But-Confusing Phase

As I moved past the beginner stage, I learned to avoid those basic mistakes.
I switched to an English input method, relied on smarter IDEs, and grew confident in my use of algorithms and data structures.

But soon, I picked up another kind of bad habit — writing code that was too clever for its own good.
My variable names became cryptic. My syntax, overly ornate.
I thought I was being sophisticated, but when I revisited my own work later, I could barely recognize what I’d written.

I was writing code as if it were disposable — a one-time product to be abandoned after it ran successfully.


The Rule-Following Phase

To fix that, I turned to the classics — books and best practices that the programming community holds in high regard.
It was slow work, but rewarding. These texts were full of time-tested wisdom, and I learned to appreciate the clarity of rules:

  • Keep methods under 20 lines.
  • Avoid more than three levels of if-else nesting.
  • Apply the right design pattern in the right scenario.

I began to live by these guidelines, no matter what language I was using.
But over time, I realized something troubling: I had become enslaved by them.

When I couldn’t find a best practice that matched a real-world problem, I started to believe the problem itself was “wrong.”
I was so focused on elegant code that I forgot the purpose behind it.
My work was technically perfect but spiritually hollow — a kind of self-righteous idealism disguised as professionalism.


The Realization

Eventually, I learned a truth that sounds simple but takes years to truly understand:
We don’t write code for the sake of writing code. We write code to solve real problems.

The tools, languages, and rules are all just means to an end. They are not the goal.
I realized that many of us — developers across the world — get lost in endless debates about frameworks, naming conventions, or the “right” design pattern.
We’re all hunting for the sharpest axe, but we’ve forgotten what trees we’re actually supposed to cut.

This realization was uncomfortable.
It meant acknowledging that everything I had mastered — the habits, the syntax, the conventions — were just temporary tools.
They could be replaced tomorrow, and the world would keep turning.

Sometimes, solving a problem doesn’t even require code.
Sometimes, it just requires two people talking face-to-face.


The Identity Crisis

After coming to terms with that, I felt lost.
As a professional programmer, my job is to solve real-world problems through code — problems often defined by others, usually the people paying for the solution.

That made me question myself:
What happens when there are no more trees to cut? When no one needs my axe?

It dawned on me that everything I did was to fulfill someone else’s needs.
But what about my needs?
What do I want to build, and why?


The AI Wave

Just as I was wrestling with that question, the wave of AI — fueled by large language models — crashed into the world.
Suddenly, AI systems could learn in minutes what had taken me years to master.
They could write “perfect” code almost instantly, adhering to every best practice I had painstakingly learned.

Machines didn’t need readable syntax or human-friendly structures.
They could transform natural language directly into executable software.

And for the first time, I felt despair.
If code no longer needed to be read by humans, then what was left for me — the human coder?


The New Understanding

In that moment of chaos and powerlessness, one thought anchored me:
If I can no longer be the one holding the axe, then I must become the one who decides which forests need to be cleared.

And perhaps even more importantly —
I must become the one who understands why the forest should be cleared in the first place.

Because writing code, at its core, is not about syntax, patterns, or even problem-solving.
It’s about understanding.

And that, I believe, is something no machine can ever truly replace.


English version translated and refined with the assistance of ChatGPT (GPT-5).

本文英文原文的润色与翻译由 ChatGPT (GPT-5) 协助完成。



一直以来,我都很自豪于,我有能力能够写出清晰、简洁并且足够高效的程序代码。这个能力不仅来自于我接受了多年的专业教育及训练,也得益于我多年的职业生涯中大量的编写代码,以及从中归纳总结并吸收。

不太确定是什么时候,我意识到了,我所写的程序代码,并不仅仅是为了让编译器或者解释器顺利识别,更多的是为了让我自己或者读到这些代码的人类所理解。或者更为极端地表达,我所写的程序代码,就是为了让“人”所理解。

意识到这一点确实不是一蹴而就的,我确实花了一段时间的思考。

在接受系统教育及学习的阶段,编写可以顺利通过编译器或者解释器的代码似乎更为重要。因为仅仅一个字符的错误就可能让我花费更多的时间来定位并排除这个低级的错误。所以注意力似乎都花费在了查看IDE是否有各式各样的下划线或者其他形式的可能错误提示,以及我所编写的字符是否是英文字符等等这些“表面”功夫上。但往往运行程序之后,才发现结果与预期不一致,甚至完全毫不相关。这个阶段的我,似乎是在为了讨好编译器或者解释器来编写代码。

当度过这个菜鸟阶段,我似乎规避或者彻底解决了这些恼人的低级错误。比如我会使用全英文的输入法来写代码,这样完全解决了作为非英语母语开发者,在多个语言输入法之间切换可能导致使用了不同编码的字符导致的错误。也与越来越智能的IDE之间配合默契,减少了纯手动修改代码,比如修改变量名称,或者重构方法等等,这样,我又规避了一些错误。这个时候,我的注意力及精力,更多地放在了算法及数据结构的正确实现上。作为还没有能力创造自己的数据结构和算法的初学者,往往需要从各种教科书或者开源代码中学习别人的聪明才智。可很不幸的是,我所接触的教科书都较为“学术”。其中的算法及数据结构实现代码,往往较为洒脱,思维跳跃地让我无法捕捉到其中的精妙。而我也是学会了这些“坏习惯”。代码中往往充斥着一些不明所以的变量以及方法命名,以及一些毫无必要的某种语言特性使用的自以为是。当经过多次调试之后终于可以正确地运行程序之后,等再次打开这段代码,我似乎与它毫不相识。满篇都充斥着陌生面孔,以及当初的自以为是,我需要花费更多的时间来确定某些特殊写法是什么意思,以及它们的执行顺序以及对最终结果的影响等等。而这个阶段,我似乎就是为了书写一次性的消耗品来编写代码。

度过这个自以为是的阶段确实不太容易。我花费了更多的时间来阅读一些被奉为圭臬的经典著作,以及时常学习达成了共识的最佳实践。做这些所花费的时间确实比预想要长,但我觉得所获得的也不少,起码不算一笔亏本的投资。我所阅读及学习的经典往往都是对其思考的讲述,娓娓道来地讲述一些经过时间验证的思想。而我所学习的最佳实践,其往往是一些“应该怎么做”和“不应该怎么做”的类似黑白名单的集合。思想的传递往往更困难,可能因为不同的人类语言之间的隔阂,也可能自然语言不够准确而产生的歧义,或者就是作者和读着之间没能达成有效的沟通,导致思想没法正确地传递。而最佳实践这类“条条框框”反而更为容易传播。这个阶段,我记住了方法体最好不要超过20行,以便于可以在一屏内一览无余;我记住了如果if-else嵌套超过3层,就需要提前退出或者其他方式,将嵌套层数减少;我也记住了当遇到某种场景,就需要使用某种设计模式等等。。。。。。我花费了很多时间来学习这些“条条框框”的最佳实践,而且是不限制编程语言的,也试图从中找到共性并汲取。但后来我意识到,我好似陷入了这些“条条框框”的牢笼里。我对于需要实现的东西,往往想要从某些最佳实践中找到那些最适合的东西,这算是一种削足适履的想法。但我意识到还有更为严重的问题,那就是当我没有找到一个合适的最佳实践来适配现实的问题时,我就觉得这个现实的问题是不应该存在的,起码是不应该被以编程的方式来解决。当我意识到我陷入了这种想法中时,确实吓了一跳,这不仅仅是陷入了一个狭窄的茧房中,更是另一种自以为是的唯心主义。而这个阶段中,我所编写的代码,似乎就是为了拟合最佳实践,尽量漂亮地无以复加,但却只活在自己想要活在的世界中。

再后来,我终于意识到,我写代码,目的是为了解决那些真正存在的问题,而不是为了写这种叫做“代码”的东西。意识到这些,确实花费了我不少时间。现在看来,这似乎是个很简单的因果关系。但我却花了不少时间来找出什么才是目的,什么只是达成这个目标的方式。我想陷入这种误区的人应该不在少数,而不仅仅是我。因为在各色的论坛、讨论组以及社交平台上,每天都充斥着为了这些“方式”来交锋、辩护或者仅仅只是友好交流的内容。我们都迷失在了为了砍树而寻找趁手工具的路上了。度过这个阶段,老实说不好受,尤其是当我得意于我对高深的技术细节有着清晰的了解,我有着良好代码书写习惯等等时。这些都需要我投入大量的时间,并且长期磨练才能习得。当要度过这个阶段,就意味着我要认识到自己所习得的这些东西,仅仅只是达成目标时临时需要掌握的工具使用方法。而这些方法一点都不重要!而且其可替代性太强了,或者不客气地说,它们都不是必须的。比如要达成的目标,可能只需要人们面对面握个手就可以解决,而不用花费那么长时间面对电脑来书写自己脑中的秩序。

度过上述的阶段后,我有点迷茫了。在上述阶段中,作为职业程序员,我所理解的程序员,就是通过编码来解决现实中真是存在的问题。而这些现实中存在的问题,往往是由“别人”来发掘并提出的,而这些人往往是为解决这个问题而付钱的人。而作为程序员,需要的是将这些现实的问题,抽象并体现在计算机这个虚拟的环境,然后再去寻找其解域来解答这个问题。所以在这个阶段中,我将自己定位在了专业的问题终结者,也就是专业的使用斧子的伐木工。但当我伐完一片密林之后,在休息时间突然意识到,如果没有人雇佣我来伐木了怎么办?原来我所做的东西,都是为了别人的需求,我的代码,就是为了实现别人的需求而写。那么我的需求呢?我想要什么?

不巧的是,在这个迷茫期,以大语言模型为首的AI浪潮朝岸边徘徊的我袭来。当各大公司的大语言模型进行军备竞赛时,我看到的是AI可以很短时间学会我之前花费大量时间来学习的各类经典内容,并且可以瞬间写出遵循各类最佳实践的“完美”代码,而且它们还是用高级语言写成的,它们原本可以使用机器语言来做。对于计算机而言,0和1总比人能看懂的字符来得直接于方便,所以AI之后可能会成为编译器,将自然语言的需求直接变成可执行的软件。此刻,我不单单是迷茫了,我甚至有点绝望,似乎仅剩的空间也被剥夺了。我再也不用写那些可以被人类看懂的代码了。。。。。。

在这个混乱绝望的环境中,我似乎毫无还手之力。我脑海中只有一个念头,那就是成为找到需要被砍伐林子的人。甚至,我应该成为那个知道为什么要砍伐林子的人。而不仅仅只是停留在思考,我该使用斧子还是油锯来砍伐一颗歪脖子树。

dark
sans