QIAOPANG.COM · SELECTED ESSAYS (2013–2026) · 260 ESSAYSBrowse Chronologically (2013 → 2026) ↗
QiaoPang · Programmers LifeSelected Essays · Systems, Craft & Agentic Era
Timeline ↗
LANGUAGES & CRAFT · 70 ESSAYS

Languages & Craft

Rust, Elixir/Erlang, Python, Dart/Flutter, type systems, compilers, metaprogramming, refactoring, testing, and the craft of software engineering.

← All Columns & Series

Musings on Indirection

The line I hold in highest regard in computing is: "All problems in computer science can be solved by another level of indirection." It's easy enough to grasp—let me offer a few examples, from the operating system to the humble phone charger, and see how one extra layer turns chaos into elegance.

Book Next Chronicles (2013–2020)1,051 chars · 2 min read

On Agile

Agile has been a hot topic in software development for years, yet many who bandy the word about have never read the Agile Manifesto—let alone understood it. Adopting agile without grasping its values is like fighting a war with tactics but no strategy: failure is only a matter of time.

Book Next Chronicles (2013–2020)1,618 chars · 4 min read

How to Learn a Programming Language from Scratch

My first practical language was Visual Basic. After getting lost in handles, message loops, and MFC, VB taught me the worth of simplicity, directness, and good documentation. On choosing a first language, learning it through its history and ideas, and leveling up.

Book Next Chronicles (2013–2020)3,245 chars · 7 min read

The Languages I Chased in Those Years

Your humble programmer was young once, and the price of youth is blind devotion. From MS-DOS 6.0 through Delphi, PHP, Python, and Erlang to Go — a chronicle of the languages I chased, and what each one left behind.

Book Next Chronicles (2013–2020)4,599 chars · 10 min read

On Programming Philosophy

Programming philosophy is a vast subject. This essay sorts it into four layers — principles, paradigms, methodologies, and patterns — and argues that every software idea, however novel, ultimately aims at one thing: reducing system complexity, repetition, and code churn.

Book Next Chronicles (2013–2020)6,027 chars · 13 min read

On Python

Open any Python interpreter and type `import this`. No other language I know has woven its culture into the language itself so cleverly or so openly. The text that appears deserves careful digestion — and it leaves you wondering: what exactly is `this`?

Book Next Chronicles (2013–2020)3,814 chars · 8 min read

Face to Face with Siri's Co-Founder, Adam Cheyer

On a Silicon Valley trip, I finally attended a local meetup to hear Adam Cheyer, co-founder of Siri, speak. He shared lessons on starting companies after forty, setting verbal goals, timing the future, and doing hard things.

Book Next Chronicles (2013–2020)4,740 chars · 11 min read

On Programming

Programming is the ability to solve problems efficiently with a computer—a skill that will increasingly affect, though not determine, your ability to thrive. A teenage developer's story shows how non-CS professionals gain an edge by pairing business problems with a little code.

Book Next Chronicles (2013–2020)1,531 chars · 3 min read

Design Patterns for System Development

Separating control and data planes is a foundational networking idea: data planes forward packets at hardware speed while control planes handle slower protocol work. This essay maps similar patterns—fast paths, queues, pipelines, state machines, and watchdogs—onto systems.

Book Next Chronicles (2013–2020)3,210 chars · 7 min read

How to Master a Technology Quickly

Between us and our goals lies a river called prerequisites. Most are swept away; a few cross effortlessly, seemingly learning any technology with ease. Mastering a technology is less a talent than a method: bypass obstacles, learn what you need, practice, and seek feedback.

Book Next Chronicles (2013–2020)2,104 chars · 5 min read

The Diagramming Tools I've Chased Through the Years

A good engineer writes good docs, and good docs come with good diagrams. A tour through the tools I've chased over the years — Word, Visio, OmniGraffle, Graphviz, ditaa, and PlantUML — and why diagramming languages beat drag-and-drop.

Book Next Chronicles (2013–2020)6,603 chars · 15 min read

The Disruptor's Game: Programming Languages

The users of programming languages are programmers, and their demands are simple: usable, bug-free, fast to develop with, easy to write high-quality code in, performant, scalable, easy to deploy, with a complete ecosystem, and so on. But the programming-language market is unusual — no one owns more than 20% of the head, and the long tail stretches out hundreds deep.

Book Next Chronicles (2013–2020)5,158 chars · 11 min read

The Timeless Allure of Immutability

Every programmer meets the variable right after hello world — and with it, mutable state: the root of undo/redo nightmares, race conditions, and untraceable bugs. Yet today's most successful systems, from git to Docker to React, win precisely by embracing immutability.

Book Next Chronicles (2013–2020)3,198 chars · 7 min read

Musings on Software Design

In an era where Lean and Agile sweep all before them, design feels marginalized and cycles leave little room for thought. MVP has become a totem and a perfect excuse—build first, design later—but serious projects still demand design, or endless rework will make you weep.

Book Next Chronicles (2013–2020)7,394 chars · 16 min read

Embracing Constraints

Lately I've been using DynamoDB at work, and its brutal restrictions on querying are maddening — until you realize that the constraint itself is the design. A meditation on why limitations make for better systems, APIs, and architectures.

Book Next Chronicles (2013–2020)4,271 chars · 9 min read

Musings on Software

Software is first a servant of business, then a craft. From Greenspan's Tenth Law to the internal martial arts of programming languages, notes on paradigm shifts, fundamentals, and why business vision trumps elegant code.

Book Next Chronicles (2013–2020)3,437 chars · 8 min read

How to Happily Write an Interpreter

In my recent essay 'Random Thoughts on Software,' I casually remarked that the age of lex/yacc and bison/flex is over. Readers pushed back: aren't those just for compilers? Here I explain why every programmer can use them to parse structured text.

Book Next Chronicles (2013–2020)6,374 chars · 14 min read

How to Learn a New Language (and Make It Production-Ready)

The past three weeks I've been using Elixir flat-out, building two systems: a production-ready policy engine and a 1,500-line activity stream PoC. Here's what it actually takes to carry a new language from proof of concept to production ready.

Book Next Chronicles (2013–2020)5,342 chars · 12 min read

Mind Games: Asynchronous Handling in EventEmitter

Node.js's EventEmitter decouples event producers from their handlers — but its fire-and-forget nature collapses the moment you need ordering, error propagation, or sequenced async hooks. A monkey-patched emitAsync, built on Promises and RxJS, restores that control.

Book Next Chronicles (2013–2020)3,991 chars · 9 min read

Boundary

Much of system design is drawing boundaries—between functions, modules, services, and applications. Clear boundaries make code rigorous and clean: the inside is a black box, entered through known interfaces, where impure external data is validated and transformed into pure data.

Book Next Chronicles (2013–2020)2,039 chars · 5 min read

On Object-Oriented Programming

Functional and object-oriented programming are both fine paradigms pursuing the same goal: code that gets reused. Rather than ranking them, this essay argues that what actually matters is interface-oriented design — and why the classic Bird-and-Duck example leads beginners astray.

Book Next Chronicles (2013–2020)3,513 chars · 8 min read

Programmers and Hand-Pulled Noodles

Making hand-pulled noodles is backbreaking work, and a programmer who can turn out a good plate of them probably writes decent code too. From charting the recipe to gathering ingredients, from pipelines to exception handling, the kitchen mirrors the codebase.

Book Next Chronicles (2013–2020)2,187 chars · 5 min read

The Way of Refactoring

Refactoring has a Way and a Technique: the Way demands automated tests as its precondition and demands refactoring at every moment you write code; the Technique is best left to Fowler. Notes on code smells, team discipline, and refreshingly strict lint rules.

Book Next Chronicles (2013–2020)4,327 chars · 10 min read

Software Development Patterns You Should Avoid

After over a decade in software, I've met every kind of developer and witnessed every bizarre development pattern imaginable. This essay walks through these patterns and their telltale symptoms — from IDE dependence to debugger addiction to the eternal rat race.

Book Next Chronicles (2013–2020)3,677 chars · 8 min read

The Power of Abstraction

Abstraction is what separates a junior code monkey from a seasoned engineer. From children counting grapes to solving equations, this essay lays out four levels of abstraction in code — functions and general solutions, contracts and Maybe types, and finally metaprogramming.

Book Next Chronicles (2013–2020)5,183 chars · 12 min read

Refactoring: Writing Competent Code

Refactoring is not just about when to do it; it is about how to turn bad code into competent code. This essay defines competent code through clarity, side-effect control, appropriate comments, and, above all, interfaces that are sensible, conventional, and hard to misuse.

Book Next Chronicles (2013–2020)4,602 chars · 10 min read

Building Your Own LEGO Bricks

Memory is your L1 cache, notes your L2, and books your main memory — and the same holds for code. A programmer's craft is assembled like LEGO: by copying, curating snippets, boilerplate, control blocks, and utility belts until you can build anything.

Book Next Chronicles (2013–2020)4,295 chars · 10 min read

Metaprogramming 101: A Gentle Introduction

After being told my last essay lacked substance, I'm serving up the real thing: a plain-language introduction to metaprogramming and macros. Using Clojure and Elixir, it clarifies ASTs, syntax quote/unquote, and the mental shift from functions to macros.

Book Next Chronicles (2013–2020)6,724 chars · 15 min read

Reactive Programming

No new essay this week — instead, I'm sharing the talk I gave to my team today on reactive programming, or more precisely, spreadsheet-like programming: why the spreadsheet's automatic dependency propagation remains one of the great unsolved models in general-purpose software, and how hoplon, meteor, and mobx each chase it.

程序人生 (2015–2019)2,869 chars · 6 min read

From Pipe to Flow

We once praised the beauty of the pipe: break a complex transactional job into small components and chain them together. Here I ask what happens when that pipeline must truly run in parallel — across cores or a cluster — without paying the operational tax of a message queue.

Book Next Chronicles (2013–2020)2,672 chars · 6 min read

Naming in Code: A Monk Knocks at the Moonlit Door

Jia Dao weighed “push” against “knock” for a single moonlit line. Naming is just as hard—and just as important—in code: good names reveal intent, abstractions, and a programmer’s craft, while careless names turn readable code into an obfuscator’s output.

Book Next Chronicles (2013–2020)5,299 chars · 12 min read

The Pros and Cons of GraphQL

Facebook has marked GraphQL production-ready and GitHub has opened early access to its GraphQL API. This essay weighs GraphQL against REST, highlighting its type system, schema flexibility, and the security, performance, and caching trade-offs teams must manage.

Book Next Chronicles (2013–2020)4,542 chars · 10 min read

Technical Debt: The Good, the Bad, and the Tao

Technical debt is the price we pay for shipping under real-world constraints. This essay sorts it into good debt, bad debt, and a tao: embrace MVP, outsource non-core work, hire the best, heed Conway's Law, limit debt at interfaces, and treat code as renewable tissue.

Book Next Chronicles (2013–2020)4,421 chars · 10 min read

Rails, Django, Phoenix: You're All Wrong

Writing a title like this is bound to draw fire. Rails, Django, and Phoenix are the pillars of Ruby, Python, and Elixir — yet in making web apps easy to build, they trap developers inside a tiny MVC box and quietly bury the business layer.

程序人生 (2015–2019)2,787 chars · 6 min read

How to Approach TDD the Right Way

TDD has long been a coveted ideal, yet doing it in a way that genuinely benefits a project is hard. This essay unpacks the common pitfalls — tests handed to QA, more tests than sense, skipping design — and shows how to approach TDD the right way.

Book Next Chronicles (2013–2020)7,496 chars · 17 min read

Let It Crash: Misunderstood, Therefore Misused

Strictly speaking, I am a dabbler in Erlang: I have never shipped production Erlang code. But I have written two thousand lines of Elixir in production, with thousands more on the way, so I flatter myself that I understand Let It Crash well enough to discuss it.

Book Next Chronicles (2013–2020)4,825 chars · 11 min read

It's Time to Think About How to Delete Code

We happily maintain and pile up millions of lines of code, yet we almost never ask whether code should be deleted. Drawing on biology's metabolism and on modularity, layering, and service decoupling, this essay asks a radical question: what if we designed architecture with the code's future deletion in mind?

Book Next Chronicles (2013–2020)3,307 chars · 7 min read

Phoenix 1.3: Toward the Right Path

After a long wait, Phoenix 1.3 arrives in RC form with a new directory structure that thins the web layer, separates business logic from web delivery, and supports umbrella projects. It is a painful but necessary step beyond its Rails inheritance.

程序人生 (2015–2019)4,227 chars · 9 min read

How to Read a Codebase

Reading source code is like reading a book — but how do you actually read a codebase, from a few thousand lines to a few hundred thousand? Three scenarios, three methods: crack-the-case bug hunting, theory-confirming deep dives, and the energy-level jump that transforms your career.

Book Next Chronicles (2013–2020)10,068 chars · 22 min read

Why Should We Read Source Code?

Programmers work with code every day, yet few truly read it—and fewer still understand the source of large projects. This gap comes from education, which teaches us to write but not read, and from work, which exposes us to only a narrow slice of a system.

Book Next Chronicles (2013–2020)3,503 chars · 8 min read

On State Machines

Starting from finite state machines, this essay explores how they recognize patterns, why DFA and NFA tradeoffs matter, and how these ideas power regex, protocols, and business systems.

Book Next Chronicles (2013–2020)3,893 chars · 9 min read

Red: Neither Red Nor Expert, But Sexy

Red 0.6.3 has shipped with OSX GUI support, yet it barely registered even on Hacker News. A look at a language that is lisp and golang at once — homoiconic, DSL-friendly, cross-compiling into a single megabyte — and at the lone-wolf ambition behind it.

程序人生 (2015–2019)3,823 chars · 8 min read

React's Achilles' Heel

When Facebook refused to relicense React, Apache projects that depended on it found themselves caught between community norms and legal risk. This essay examines the BSD+Patents clause, Category X, and the hidden cost of React's licensing.

程序人生 (2015–2019)1,021 chars · 2 min read

Stop, Catch Your Breath, and Reinvent the Wheel

Since last Thursday I've spent 50–70% of my time building a wheel — a tool called merlin. The lesson: every so often you should pause, step away from the daily chores, and build something from scratch.

Book Next Chronicles (2013–2020)2,921 chars · 6 min read

Never Underestimate the Power of bash

Parsing tens of gigabytes of gzipped logs on S3 doesn't always need a Spark cluster. With a few lines of bash, well-placed pipes, and xargs-based parallelism, a small script can outperform a much more elaborate streaming solution.

Book Next Chronicles (2013–2020)3,135 chars · 7 min read

Abstraction Revisited

In 2016 I wrote about the ability to abstract, using a feed parser as a case study. This follow-up argues that code abstraction is technique while requirement abstraction is the Way—and shows how a week of lazy thinking turned a Merlin upgrade into a library, a gen server, a framework, and an app.

程序人生 (2015–2019)7,303 chars · 16 min read

The Method of Research

Today I want to share my personal method for doing research — a system that has followed me for years and is still being refined. It's how I enter a new field quickly and put down roots. Read on; I hope it sparks at least a little something in you.

Book Next Chronicles (2013–2020)5,356 chars · 12 min read

No Silver Bullet

A tree too broad to embrace grows from a single sprout; a nine-story tower rises from the first basket of earth. Watching my daughter grind through piano practice, I realized the same truth governs learning to write code: no silver bullets, only deliberate practice.

Book Next Chronicles (2013–2020)2,955 chars · 7 min read

On Data Structures

Wirth famously said that programs equal algorithms plus data structures—but on the right side of that equation, the data structure carries more weight. This essay dissects how arrays, lists, maps, and trees are actually implemented beneath the surface.

Book Next Chronicles (2013–2020)2,759 chars · 6 min read

What I Gained from the Past Month

The greatest reward was my interview with old Joe — truly priceless. I hope that at sixty I too will be as wise and clear-eyed about the world, leaving everyone who talks with me with the feeling Frodo had when praising Sam: Tyr the thinker.

程序人生 (2015–2019)4,913 chars · 11 min read

The Darkest Hour

When Goku stands broken before Frieza and Helm's Deep teeters on the brink, the darkest hour reveals what courage really is. From Sima Qian to Churchill, a reflection on enduring despair — and on the lost causes still worth fighting for.

Book Next Chronicles (2013–2020)1,964 chars · 4 min read

How to Improve Code Quality?

Good programmers, like great strikers, are made by the body of work and the mind behind it. This essay shows how to lift code quality across products, interfaces, metrics, logs, clarity, and complexity — from naming things worth remembering to letting linters discipline your soul.

Book Next Chronicles (2013–2020)5,322 chars · 12 min read

Thinking in Tools

Paul Graham argues in Hackers & Painters that programming is a perfect profession because it is both measurable and leverageable. But an outstanding engineer is not simply worth several mediocre ones; with the right tools, they can multiply a whole team’s output—or their own.

Book Next Chronicles (2013–2020)4,173 chars · 9 min read

Code is Law

If you thought this piece was about Ethereum or smart contracts, I'm sorry to disappoint. It's about engineering practice: how we encode process as code at Arcblock, so workflows become reusable, composable, testable — and genuinely painless.

Book Next Chronicles (2013–2020)6,443 chars · 14 min read

How to Move with Ease Across Dozens of Repos

Sindre Sorhus is a programmer I've long followed and admired. How can one person work across dozens of repos in a single month, producing hundreds of commits? Lessons from three months spent deep in elixir, ansible, terraform and javascript.

Book Next Chronicles (2013–2020)7,776 chars · 17 min read

The Myth of Software Supply Chain Management

Why do software projects have no supply chain management? What would a software BOM look like, what security risks would it carry — and what did leftpad and event-stream teach us about how fragile the whole thing is?

Book Next Chronicles (2013–2020)5,455 chars · 12 min read

Great Craft in the Smallest Details

During a code review, a seemingly harmless snippet of Elixir turns out to carry two deeper flaws: a commission calculation welded into a balance update, and no bound on the function's range. One small habit — writing the math down — goes a long way toward fixing both.

程序人生 (2015–2019)3,059 chars · 7 min read

Rediscovering Git in 10 Minutes

Fascinated by Git’s internals, I built a bare-bones Rust and RocksDB object store for blobs, trees, and commits—avoiding scattered filesystem objects and packfile delta encoding. Before detailing its pitfalls, I revisit Git’s core ideas and object types through hands-on examples.

Book Next Chronicles (2013–2020)4,055 chars · 9 min read

How to Make Educational Videos: My Journey of Exploration

Since last September I've taught my daughter for an hour every night — history, math, Scratch, science, films, geometry. Friends kept urging me to turn those lessons into videos, and after many false starts I finally found a workflow worth sharing.

Book Next Chronicles (2013–2020)3,618 chars · 8 min read

Flutter: Impressions After One Week

Flutter had been burning hot for over a year and I still hadn't tried it — my indifference came down to ignorance of Dart. After a week of video courses, source code, and hands-on work, here are my reflections on its Skia-based rendering engine, its cross-platform ambitions, and why Dart was the right choice.

Book Next Chronicles (2013–2020)5,806 chars · 13 min read

Dart: What Is Lost in the East Is Gained in the West

A month ago, Dart would have ranked among the languages I least respected. Google's structured web language failed to replace JavaScript, yet its design choices later made it the foundation of Flutter—a redemption story of technical bets paying off in unexpected ways.

Book Next Chronicles (2013–2020)7,431 chars · 17 min read

Time to Meet jj: Git's Next Evolutionary Step

Git has ruled version control for twenty years, but its staging area, brittle rebases, and blocking merge conflicts are becoming liabilities in the AI era. jj rebuilds the mental model from the ground up — while staying fully Git-compatible. Here's why it deserves your attention.

New Hope (2025–2026)5,588 chars · 12 min read