In a world where developers can get a lot of help from Copilot, ChatGPT, StackOverflow, etc., there are still certain coding skills that characterize the best software developers. As just one example, real developers use data types in a way that makes their code cleaner and more reliable -- they define types like "heightInCm" or "widthInPixels" instead of floats and ints, and suddenly code is 10x easier to reason about.

In your opinion, what are some other hallmarks of top 1% developers?

@spolsky Interesting. Do you think heightInCm and widthInCm are two separate types? I am more inclined to think you want one type, distance
InCm, and two variables of that type, height and width.
@mike Maybe - depends on the scenario - I try to use different types when assigning from one to the other is always an error.

@spolsky I stole this from someone else and it pairs nicely with tagged types: use XfromY() instead of YtoX(). That aligns the types in the name of the function with the types of the parameter and return.

varInKm= kmFromCm(varInCm)

The two โ€œkmโ€ are touching.

@jkaniarz @spolsky

Good ideas. Just a few observations:

I think that var in the name is redundant. For these, I would use value types that are immutable and, if available, references that cannot be resigned. My Smalltalk tick calms when I use the more fluent parameter-names-type expressions, again avoiding redundancy:

val square = squareFrom(heightInCm)

In most modern languages, this could be overloaded for different types, both parameter and answer, or type matched (eg, Haskell).

@spolsky Carefully crafted commits with commit messages that tell the story of why this code happened. The code will change, but the commit history is forever.
@spolsky They care for the API theyโ€™re exposing in their classes/components/packages: from naming to consistency to conciseness.
@spolsky they're picky about their dependencies.
@JasonPunyon @spolsky sometimes thatโ€™s beyond your control ๐Ÿ˜ž
@spolsky Any code is testable if you have an AI that can generate a test of arbitrary complexity, but writing code that is testable in a way where you can also easily understand the test is an art!
@spolsky being able to decipher BA gobbedlygook to usable technical requirements and translate that to good architecture
@spolsky providing advice that appeals to others on the facts - using inclusive, friendly, and collaborative language.
@spolsky fixing what's broken as a priority, routinely paying off technical debt and fighting entropy
@spolsky also caring deeply about their own productivity and constantly tuning and optimizing the tools and systems they use, fighting friction, noise and red tape
@spolsky Keeping code close to its place of use, using DRY but not fanatically, writing code first for humans - not for computers, not using high-level abstractions that even you won't fully understand a week later, do not over-engineer and last but not least: KISS ๐Ÿ˜š
@spolsky Parity matching the complexity of the architecture to complexity of the application. I've lost count of the number of times I've seen essentially, data collection web forms with heavyweight dependency injection framework. Sometimes a homebrew one. It's the middle stage of developer maturity - using trendy patterns because you know how, not because you need it.
@spolsky I think understanding where a project is heading in terms of added features and being able to futureproof is really important. Basically being able to anticipate when/what abstractions, frameworks, patterns, etc. will be necessary in the future.
@spolsky Being able to identify what the customer actually needs, what is important and what isnโ€™t and being able to focus on that in the code.

@spolsky all people who write code are "real developers".

A characteristic of professional developers I know we both appreciate is habitual use of specifications. Without a spec, how do you know when the code is right? Or when it's done?

@spolsky I don't know about if it's about being a great programmer, but I love using type aliases for other classes or tuples, so the code may be more readable
@spolsky it's not an artifact you can see. Being able to read code and understand it is a good steo, but being able to read diffs, not just in terms of the line changes but to understand what changed, how it will impact other parts of the files that changed and how a bug could have been introduced is something that takes time to get.
I think it is a skill that senior Devs take for granted but if you are taking to a mid or junior you really need to point out what is happening even then they struggle.

@spolsky telling people 'no'...

AI will just take your bad idea and run with it.

@spolsky Knowing that complexity is the enemy and Gallโ€™s Law is your gospel.
@spolsky error messages that tell you what is wrong, and how you can fix the problem.
@spolsky being able to reproduce most/all problem on your local dev environment.
Lesser experienced developers painfully deploy, try manually, or just wait many times per day while with some effort they could simulate whatever bug they try to fix in a unit test.
@spolsky clean API surfaces on every internal object.
@dan Sure... but what makes them clean? Non-leaky?

@spolsky well a lot certainly has to do with just naming things well as you said. Other things I can think of - proper getters and setters. And as the great Colin Moock once said โ€œif your function is longer than like 5 lines, you probably should have 2 functionsโ€

Other thing is just following the language conventions. As Iโ€™ve learned Swift in the past few months, thereโ€™s def a Swifty way of doing things such as accepting variables and using modifiers correctly.

@spolsky kind of cracking me up that this and lots of the responses are essentially rewriting your 2005 blog post about making wrong code look wrong. (And that's not a bad thing, I still point some new fresh out of college developers I work with to it.)
@JaredCrookston yep! Although - as the tools (compilers and linters and unit tests) have gotten better, itโ€™s less important to specifically make wrong code look wrong, and more important to generally just make the dang code look like itโ€™s doing what itโ€™s meant to be doing
@spolsky not trying to outsmart the compiler
@jbaert How do you mean? like, premature optimization that the compiler will do anyway?
@spolsky Yes, and in the process inadvertedly making things *harder* for the compiler.
@spolsky giving your pull request or merge request an accurate but short description, so someone without all surrounding context can glance at it and quickly understand what it is about.
@jaanus @spolsky ๐Ÿ’ฏ This is probably one of my top pain points in my daily work.
@jaanus @spolsky If you invested hours crafting a good PR, it should be possible to add a few extra minutes to help your reviewers with a good description.

@jaanus @spolsky That's a good recommendation, but there is a caveat.

PR/MR description doesn't always survive. Better to put this information into commit messages, and _then_ copy it into the PR/MR description or just write "Details are in the commit message."

The commit message is three clicks away in IDEs, available even offline (in a DVCS), and the commit message is always tied to the code changes in the commit, so it remains relevant longer that code comments.

@spolsky The ability to do more than just code. Communication, empathy, product understanding.
@spolsky knowing when to explain to the customer that their problem can be solved without more code; in short knowing when programming is not the answer

@spolsky Approaching debugging and problem solving with the scientific method: attempt to disprove your theory/assumptions before acting on them. Learning this has saved me countless hours of work.

https://www.youtube.com/watch?v=vKA4w2O61Xo

The Most Common Cognitive Bias

YouTube
@spolsky what about code review and/or refactoring? being willing to submit to that...would it be a blow to one's ego as a dev?