Thought

Review

In the past six months, I’ve spent a lot of time commercializing Tasmap, a project I did five years ago. I also reviewed how I designed the architecture and implemented the code five years ago. Here are some of my thoughts.

Meta is Important

Looking back, my principles and ideas were correct. Some parts could be more refined and detailed, but the reliability of my core thinking prevents me from feeling confused like “Huh? What is this? What was I doing?” even after five years. I believe organizing one’s meta is crucial. It helps you maintain a stable core when facing challenges and allows you to expand it step by step based on new experiences.

You should have your own meta too.

”Best Practices” of the Era Don’t Matter

Looking back now, the code I wrote five years ago was all “best practices” at the time, but examining it from today’s perspective, it’s no longer a “modern pattern.” When you use so-called “best practices,” you must be very clear about “Why?“. Also, trust your intuition and taste, not the words of others. In recent years (especially after 2020), the tech circle has become very commercialized, with rampant exaggeration, hype, and marketing. You need good “technical literacy” to make choices. Just like investing, dancing to someone else’s tune usually ends up with you being the sucker.

I like one of Warren Buffett’s principles: “I don’t invest in things I don’t understand.” This is even more important in technology selection because the technical environment is a more closed and rational environment, where the fundamental aspects far outweigh the cognitive aspects. Two principles:

  1. Don’t use technology you don’t understand. If you don’t roughly understand how it works, don’t use it.
  2. If it’s problematic in principle, it’s problematic in practice. There’s no black magic in computer science.

I still remember the phrase: “Dirty digest is fine.” Angular 1 taught me to question those glittering tech gurus.

Fundamentals and Market Aspects

Investing has fundamentals and market aspects; technology selection, frameworks, libraries, architectural design, and code style can also apply the same judgment framework. Fundamentals refer to the technical principles of something and some objective indicators (e.g., time complexity, space complexity, test results in limited situations). Market aspects refer to team resources, the talent market, authors, popularity, etc. When fundamentals far outweigh market aspects, it means growth potential is limited. When market aspects far outweigh fundamentals, it’s hype.

Balance and trade-offs are important.

Reinvent the Wheel

We used to say, “Don’t reinvent the wheel,” but in this era, I think we should take the wheel back and build it ourselves. The biggest reason is AI. Many established and stable implementations (like in-memory cache, image components), which were once laborious tasks for veterans and training grounds for newcomers, can now be easily completed by AI. The advantage of building your own wheel is 100% control and 100% customization capability. You can ensure that this lib is built entirely according to your needs, add whatever you want, and it won’t cause trouble for some trivial reasons (license becoming private, or some strange things being stuffed in), etc.

If my distrust of official statements comes from Angular 1, then my distrust of open-source projects comes from Ant Design. I still remember eating only half of my rice ball for breakfast that day and spending half a day trying to find out who put a “little Easter egg” in my Dashboard.

Defensive Module Design

For long-term projects, the focus of module design may not be extensibility and reusability, but defensiveness. Defensiveness here refers to:

  1. Preventing future changes
  2. Preventing uncontrollable errors

The general principle is: modules should always output predictable results. The boundaries of a module should be able to effectively control uncontrollable errors and changes within the module. As long as this goal is achieved, inconsistencies in implementation between modules are acceptable, and sometimes can even be a measure to diversify risk.

Consistency is Toxic

I’ve noticed that in recent years, “consistency” has become a very popular buzzword, but I haven’t seen it bring positive effects. Most of the time, so-called consistency is used to package the message “You do it this way for me.”

As the old saying goes, first ask “Why?“. Why consistency? What positive or negative results will consistency bring? Is this consistency suitable for this environment? I’ve seen many “architects” pursuing a flawless, ideal codebase, with a strong desire for “consistency,” ultimately destroying the product and the entire team. It’s not just architects; many managers with strong control tendencies have this problem, and consistency in such situations becomes the “righteous cause” for crusades.

Some things must have consistency: the company’s cultural principles and vision, the product’s North Star. As for other things, especially underlying execution, like code style, excessive demands for consistency will only burden the team with meaningless shackles and cause disputes. What you should use are “principles,” or the “meta” I mentioned at the beginning, not consistency.

I can’t even achieve consistency with myself from a few years ago.

Technical Debt is Not Debt

Technical debt is a very common concept and term, but it actually creates a false analogy: owing “debt” is bad and needs to be repaid. Thus, teams have many disputes over so-called “technical debt”: when to repay the debt, who owes the debt, who will repay it, and so on. In fact, trade-offs in programming are different from debt; they are more like a strategic arrangement: human resources, timing, investment period, and other factors. The key is: have you figured out what results this choice will bring at what point in time?

Another reason why technical debt is not debt is that, often, technical debt does not need to be repaid. If a module always works correctly, then I don’t really care what it looks like inside, whether it was written by Wang Chongyang or a goblin. How to “leverage technical debt that doesn’t need to be repaid” is a very interesting way of thinking.

Don’t Block AI’s Path

In Tiat, there is a feature to “search images by drawing.” Simply put, you are given a canvas, and you draw a doodle like in Paint, and use this doodle to search for images. To implement this feature, I spent a lot of time researching relevant knowledge in the CV field. Last year, an article “The Bitter Lesson” discussed recent developments in CV: human expert knowledge has become an obstacle in training, and the effect is not as good as leaving everything to the model itself.

This reminded me of something: will our programming style, architectural design, and best practices also become an obstacle? Could it be that AI could have produced better implementations, but its performance was limited because it had to accommodate some of the restrictions and guidance we added?

The current mainstream opinion is that humans are better at high-level architectural design and requirements transformation, and then leave the underlying implementation to AI. But what I’m thinking is: this premise is based on humans having an unequal amount of input. If the input amount is the same, or if a more effective input method for AI is found, will human high-level architectural design still prevail?

I tried to do “AI-first architectural design” a few months ago, and it failed. However, the process was very interesting, and I’ll share it with you when I have time.

The Magic of Extending Reality

Application is a kind of magic, a magic that extends reality. The essence of magic is “to realize the thoughts in your mind.” Want to smoothly browse millions of images, want to automatically organize all files, want to write Medium articles in Markdown, want to create a beautiful map. Application is a kind of magic, magic is for realizing your inner thoughts, and thoughts are born from life. Experience, feel, think, communicate, only in this way can a boring fireball spell be transformed into moving fireworks.

'25, May 10