Skip to content(if available)orjump to list(if available)

Developer Philosophy

Developer Philosophy

24 comments

·February 3, 2025

neves

The author cited this quote:

> he first 90% of the job takes 90% of the time. The last 10% of the job takes the other 90% of the time.

When I report my work done I always prefer the ironic version:

> I've already did 90%, now there's just the other 90%.

It is fun, but most importantly, for non developers, it reports a reality of our work. To do the simplest case, is almost easy, but when you have to factor in taking care of exceptions, errors, usability, log, robustness, security etc. there's a lot of "unexpected" work.

zurfer

"I apologise for writing such a long letter, but I didn't have time to write a short one."The quote, " is generally credited to Blaise Pascal, a French mathematician and philosopher. In his work "Lettres Provinciales" (Provincial Letters), published in 1657, Pascal wrote in French: "Je n’ai fait celle-ci plus longue que parce que je n’ai pas eu le loisir de la faire plus courte," which translates to, "I have made this letter longer than usual because I lack the time to make it shorter."

parpfish

the last three entries are great and need to be drilled into folks head. too much of CS training (and leet-code driven interviewing) encourages people to get clever. but reading somebody elses clever code sucks.

write code that's meant to be easily read and understood. that's not just about algorithms and code comments -- variables/functions named descriptively, formatting is consistent, things don't get too nested, design things to be modular in a way that lets you ignore irrelevant sources of complexity, etc

zikzak

Kernighan's Law - Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

marcosdumay

That, of course, is only valid if you are using your cleverness to optimize for something that isn't readability.

bilekas

I feel as an outlier to this I need to make a comment.. Debugging (with source) to me at least, it’s so much more easier as you have all of the stack with you along the chain.. It’s very rare, not impossible though, to find crazy behavior during correct debugging.. This law is new to me though.

bilekas

A great rule of thumb I found useful while learning under great tutorship (way back when) was, look at your check-in, (svn at the time) if you think you will remember it in 5 months in less than 15 mins then it’s okay.. But still have someone put eyes on it before clicking. SVN made us careful maybe..

LegionMammal978

I'd be a bit wary of taking 'simplicity' as a goal. Some people read that and think to write shorter, cleverer code instead of longer, more straightforward code which might have a few redundancies. (E.g., people often praise FP languages and Lisp-like languages for their very flexible control flow, but adding custom abstractions can result in shorter code that is difficult for newcomers to understand.)

On the other hand, too much modularity and factored-out code can also obscure the behavior of a program, even if each module has a well-defined role and satisfies its interface. (E.g., big Java programs can have hundreds of classes with small method bodies and lots of calls to other classes and interfaces. If you see an interface call, but the object came from somewhere several classes away, then good luck figuring out which implementation gets called.)

I'd say that the ultimate moral is "Keep the flow of logic and data relatively linear (or at least, no more complex than it needs to be to solve the problem). Avoid dicing it up between a dozen different spots, or performing crazy stunts with it, so that only an expert can understand what's going on. And just because some logical constructs (like dynamic dispatch) are unwritten doesn't mean they don't create mental load."

bilekas

> but adding custom abstractions can result in shorter code that is difficult for newcomers to understand

I’ve worked at places where the lead would abstract everythiNg possible, it made tracing the flow not just difficult but almost intentionally obfuscated. When calling him up on it he would sing the principles and say it’s the source of robust code. I’m sure out 100 customers appreciated that.

I do appreciate your comment on keeping the flow right, I would add to that I guess by making sure you’re domains and boundaries are well established and respected.. mistakes will always happen, but if they’re “gated” by domains, the person who fixes it will definitely buy you a beer/coffee.

datadrivenangel

"By the time the ground-up rewrite starts to seem like a good idea, avoidable mistakes have already been made. "

This is the wisdom of devops. Do it well, and things will go smoothly.

tra3

Someone below already commented [0]

> I think any attempt to distil hard earned experience and domain awareness will eventually devolve into misplaced generalisms.

Ground up rewrites are a gamble. Classic Spolksy essay [1] about Netscape losing their lead to Internet Explorer is a must read.

Briefly:

1. You think you know how to build the new version, but you really don't. Years of improvements of the old version, years of bug fixes, years of business knowledge are below the surface.

2. The new version is going to have new bugs.

3. While you're rebuilding everything from scratch your competition is improving their product.

0: https://news.ycombinator.com/item?id=42921426

1: https://www.joelonsoftware.com/2000/04/06/things-you-should-...

datadrivenangel

All abstractions are leaky, and all pithy sayings have a contradictory and equally pithy counter-saying.

True wisdom is knowing which wisdoms to look at and when.

hintymad

This reminds me of Joel Spolsky's test and true article on rewrite: https://www.joelonsoftware.com/2000/04/06/things-you-should-...

gchamonlive

I think any attempt to distil hard earned experience and domain awareness will eventually devolve into misplaced generalisms.

This isn't to say that the article isn't good. It's well written and the teachings are valuable.

This comment is for the inexperienced dev that arrives at theses posts looking for ideological prescriptions: don't.

Give yourself time. Let yourself fail and learn from your mistakes. Keep reading the masters work like Clean Code, SICP, Working effectively with legacy code, software architecture the hard parts, mythical man month etc... but don't let anyone prescribe to you how to do your job.

Developing is ultimately managing an unmanageable and ever evolving complexity and making it work. Developing is art and experience. Developing requires great peace of mind.

parpfish

generalisms are fine as long as you don't try to turn it into a hard and fast rule.

generalisms contain knowledge that generally applies, but i think it's well understood that there will always be times where it doesn't apply.

spit2wind

The author has a few words about Clean Code https://qntm.org/clean

A better recommendation is "A Philosophy of Software Design" by Osterhaut.

omoikane

These are all good ideas, particularly the last 5 which are mostly technical. The first 2 are often influenced by things beyond developers' control. For example, developers might be pushed on a schedule that encourages accumulation of technical debt, leading to the inevitable bug bankruptcy and ground-up rewrite.

I think every developer should strive to do the right thing, and also be flexible when the right outcome didn't happen.

Kinrany

Same qntm that wrote There Is No Antimemetics Division

robwwilliams

Great hard-won insight! Looking forward to many HN comments on this thread.

AnimalMuppet

Well, there's a gauntlet being thrown down if I ever saw one.

For me? Maybe something like:

1. All rules have exceptions - have places that should be exceptions. Rigidly enforcing a rule may be better than having no rule, but thoughtfully following the rule (almost all the time) is even better. Know your rules, know why they're the rules, and know when it might be reasonable to make an exception. (Maybe this says that "rules" are really more like "guidelines".)

Rules often come in opposite pairs. I think of it like this: In Zion National Park, there's a hike called "Angel's Landing". You wind up going up this ridge. On one side is a 1000-foot drop-off. On the other side is a 500 foot drop-off. The ridge isn't all that wide, either. If you look at one cliff, and you think "I need to be careful not to fall off of that cliff", and you back too far away from it, then you fall off of the other cliff.

I think software engineering can be like that. There is more than one mistake that you could make. Don't be so busy avoiding one mistake that you make the opposite mistake. This takes thoughtful understanding, not just blindly following rules.

2. In general, don't repeat yourself. Early in my career, a coworker and I learned to ask ourselves, "Did you fix it everyplace?" It's even better if there's only one place.

But... It is common that things start out the same, and then become slightly different (and it gets covered with an "if"), and then become more different (and now we have several "if"s), and then become even more different. Eventually it can become better to decide that these are actually different things, and split them. Knowing when to do so is an art rather than a science, but it's important.

3. The most general problem cannot be solved. The trick is to do something simple enough that you can actually finish it, but hard enough that it's actually worth doing. You cannot address this just by changing the lines of code you write; the problem is at the specification level (though it can affect the specification of a module or a function, not just a project).

4. Code that is "close to perfect", delivered now, may well be better than code that is absolutely perfect, an uncertain amount of time in the future. It depends on how many imperfections there are, how likely they are to be hit, and how damaging they are when they are hit. Code that is close to perfect may be perfectly usable to many people; code that hasn't shipped yet is currently usable to nobody. (Note well: This is not an excuse for sloppiness! It is an excuse for not going completely hog-wild on perfectionism.)

5. You've got a perfect design? Great. As part of delivering the design, deliver an explanation/roadmap/tour guide for it. (If it were an electrical design, it might be called a "theory of operation".) Consider checking it in to the version control system, right beside the code - like, in the top level directory.

6. All these things take maintenance. You have to revisit your "don't repeat yourself" decisions. You have to revisit what is within scope and out of scope. You have to revisit which bugs are tolerable and which are not. You have to update your design documents. Take the time and do the work. If you don't, your program will slowly become more and more brittle.

skrebbel

Seeing the domain name I really hoped this was some way-out there SF story about computers philosophising about their developers or sth.

wduquette

"Nobody cares about the golden path. Edge cases are our entire job."

This is an obvious exaggeration; if you ignore the golden path, the code doesn't solve the problem it's meant to solve. But yes; writing reliable code is all about the edge cases. Eliminate them if you can; code for them if you can't.

AnimalMuppet

Back in the 1970s, when I was just a high school kid reading computer magazines, I saw references to a study (I believe by IBM), that said in production code, that 70 or 80% of the lines of code was error handling; only 20% or 30% was the "golden path". I'm not sure I saw an actual reference, even then, and I certainly cannot give a reference now.

Does anybody know the study in question? (I have never seen another study on the topic. Does anyone else know of one?)

This was almost certainly either done in assembly or PL/I or Algol or something. Do more modern languages change it? Exceptions? Dual-track programming (options or Maybes)?

Regardless of exact numbers, yes, error cases are something you have to think about all the time.

atq2119

Maybe this applies to Go code?

Snark aside, I am somebody who is very concerned about edge cases, but those ratios seem completely wrong to me for the kind of code I write. And perhaps one should say "corner cases" instead of "error cases". Corner cases aren't necessarily errors. What I find is that a good algorithm that is properly "in tune" with the problem space will often implicitly handle corner cases correctly. While an algorithm that was hacked together by somebody who is "coding to the test" without really understanding the problem space tends to not handle corner cases, and then the developer tries to handle them by adding if-statements to patch their handling.

In the end, devoting 70% or 80% of thinking time to corner cases seems entirely plausible to me. 70% or 80% of lines of code dedicated to corner cases may be a smell.