
The traits of a proficient programmer - kiyanwang
https://www.oreilly.com/ideas/the-traits-of-a-proficient-programmer
======
jcbeard
Probably the most important bit of the entire article, which you can probably
get from many self help career books (applies to all, not just programmers):
"Ask others to explain why they do things, but don't just accept dogmatic
reasoning. Demand examples and inquire about context, so that you can try to
imagine what it is like to be in their shoes. Doing this is tremendously
valuable because it allows you to see the strengths and weaknesses of ideas in
their natural habitats."

One thing I can add is always question. There's a reason kids ask tons of
questions, they want to know. Asking questions not only increases your own
knowledge, and that of the person answering, but it also creates a culture
where complacency is extinct. The one thing I hate more than people that
litter are people that say "oh, well, that's the way I've always done it."
There's lots more I dislike above that, but...complacency is the death of
innovation. Then again, sometimes things just work....but that shouldn't stop
you from trying to improve it.

~~~
sbov
Sure. Sometimes. Othertimes, you have to recognize that you aren't an expert,
and that the real "why" is beyond your reach. If you're in this situation,
you're probably better going with the herd.

I run across this sometimes with my boss. He asks why we do X, can't we do Y?
I respond: X is common and a well vetted practice, I don't know the security
implications of Y. Then he says: lets use Y unless you can think of a concrete
reason not to.

In the meantime, I'm not really qualified to analyze Y in the way X has been
analyzed. I would rather stick with X, even if my reason is dogmatic.

~~~
jacobolus
> _Othertimes, you have to recognize that you aren 't an expert, and that the
> real "why" is beyond your reach. If you're in this situation, you're
> probably better going with the herd._

Yep. And as a society we are _great_ at this, which makes it almost impossible
to improve any part of our culture basic enough to be taken for granted.

That’s how we end up with a base ten number system, a weird irregular
calendar, really silly spelling rules, suboptimal mathematical abstractions,
inflexible shoes, office furniture and computer input devices which cause
serious injuries, roughly the same computer architecture since the 60s, or the
marvelous absurdity that is the modern web software stack, not to mention
bloody centuries-old feuds between neighboring tribes.

Also the main reason advertising and propaganda work so well. “Everyone else
does it, so you should too” is an incredibly effective way to shortcut
reasoning.

~~~
dasil003
I think you're conflating cargo culting with pragmatism though. The
generalized reason that everything is messy is because it's too much work to
gather all the knowledge and consider all the angles and do a big reset, and
even when you do, you run into unforeseen issues that may end up being just as
bad (see Gall's Law).

Consider a pet peeve of mine: The Turkish Problem. Specifically, when Turkish
was latinized almost a century ago, they had the brilliant idea to use
lowercase i and capital I as separate letters, and then introduce their
counterparts İ and ı as new letters. This now means you can't upcase or
downcase the letter i/I unless you know the language. Note that it took 11
years for Firefox to handle this correctly
([https://bugzilla.mozilla.org/show_bug.cgi?id=231162](https://bugzilla.mozilla.org/show_bug.cgi?id=231162)),
and even then you have fractal complexity if you're dealing with an
internationalized site. I had the pleasure of working on a film site that was
localized to Turkish, where I realized that it is not enough to know the
language of the document, you must indeed know the language of every string in
the site. In the case of film titles for instance, many films in Turkey are
known by their English title, and in that case you must use normal
capitalization rules, so now every film title has to have the original
language flagged. This is not a small issue because if you are a Turkish
speaker it _just looks wrong_ if you don't get it right.

Why do I go into this digression? Because from a programmers perspective, this
is insane. In retrospect it would have been infinitely better just to invent a
new letter or use an accent or something that fit the alphabetical semantics
of other latin languages. But they didn't. This decision went into effect in
1929 when the concept of character encodings was something only maybe a
handful of engineers and mathematicians had even considered, and the concept
of Unicode would have been beyond science fiction; it probably seemed a
perfectly reasonable hack at the time. If we were to reverse it now in order
to ease technical concerns think about all the fallout with all the existing
documents and printed materials. It's just too big a price to pay. The world
is full of these things, there's just not a big enough ROI to justify
overhauling these old systems.

That's very different from the more actionable problem of people who go
through the motions without ever questioning how they do things.

------
yawz
A competent programmer knows that tomatoes are fruits. A proficient programmer
doesn't put tomatoes in a fruit salad. :)

~~~
the_watcher
I like this. It can be applied in a much broader range of professions than
just programming, but it's a nice, memorable analogy.

~~~
Noseshine
I'm missing an option for the guy who could not care less whether or not a
tomato is a fruit or not, because he knows it does not matter at all for his
purposes. IMHO the _real_ expert knows what knowledge is relevant and what
knowledge is for forum discussions that are just used to kill time.

~~~
st3v3r
How does it not? When making a fruit salad, the knowledge that tomatoes don't
go in fruit salad seems pretty relevant.

~~~
Noseshine
If you don't have any arguments you downvote, you stupid troll?

You don't have to know that tomatoes are fruit for that? Your reply makes no
sense at all. I say "you don't need to know H" and your reply is "but you do
need to know Y"! Not to mention that specifically your reply is something only
worth knowing when when does know that tomatoes are fruit, and not when one
doesn't.

------
Rexxar
I'm maybe too cynical but I always think the main motivation of such articles
is to pretend the author is a very good programmer with the implicit
assumption that "if you have an opinion about what make a good programmer, you
necessarily should be a very good programmer".

~~~
acbabis
My criticism of the article would be that there isn't really anything to
disagree with. Most STEM people already understand that analytical ability is
more important than knowledge; and the people struggling with this are
unlikely to gain that understanding from an article.

From that perspective, I think you might be right. The article won't
accomplish much except make the writer look good. But you're also right that
this is cynical. If we're optimistic, this article could serve to give people
already possessing some analytical ability a friendly nudge to learn and
dissect a new concept.

~~~
rimantas
Most STEM people should know, that analytical ability relies a lot on
knowledge. You cannot analyse how something is made up unless you are able to
recognise parts, their relationships and dependences. You need those chunks,
patterns in your brain only then you can see them elsewhere and understand the
working of the whole.

------
mgrennan
This is where the use of "Older" IT people would help. Take all the new ideas
and innervation and filter it through the 60 year old IT guy (Knowledge
experts).

Explain your ideas well with examples. Lesson how that problem has been solved
before. Don't build new ideas on old code. Find shortcuts to the results.

Don't be naive. Ignorant is better.

Naive is not knowing your don't know.

Ignorant is knowing your don't know.

~~~
makmanalp
I've worked with some older folks with a ton of experience (think: programmed
in the 80s or earlier) before, and I have huge respect for those folks who can
see a disaster coming miles away, or have been around the block enough times
to have formed solid opinions on many subjects.

\---

Although, while more often than not true (perhaps partly due to survivor
bias), I do think that it's not a given that old programmers are wonderful.
Some older folks do seem very set in their ways and unwilling to experiment in
a way newer programmers aren't.

The natural example is that you hear a lot of "ah it's like <blah> all over
again" where blah is something like winforms or activeX or CORBA or lisp or
OSGI or what have you, but it's frustrating to come into everything with that
baggage.

Yes it might be the same idea, but it might be executed quite a bit better!
Perhaps much wider platform support, perhaps lower total cost of ownership,
perhaps increased viability under current conditions, perhaps much larger
community of people and tools!

The cycle turns much quicker than it used to, and using older, more mature but
inferior technology sometimes does have a big effect on the bottom line or
provides a disadvantage over competitors in a way that I don't think it did as
much earlier on. Granted, this isn't always the case and knowing when it is
also matters.

I think "strong opinions loosely held" is a great motto, and a lot of these
folks follow that motto to wonderful effect.

\---

It is also entirely possible do essentially the same project over and over in
a multi-decade long career, and learn nothing material from it all, and I've
seen that happen too.

\---

In conclusion, I think older programmers can be a great asset to your team,
and are often overlooked for no good reason. But they're also people like
everyone else.

~~~
BaronSamedi
An historical perspective, which older programmers at their best bring to a
project, is important in my view. When you look at the history of software
systems you see that the better technology rarely wins in the marketplace. A
lot of things contribute to the success of one system over another--technical
excellence is not one of them.

Also, the significance of fad and novelty cannot be underestimated. When I see
yet another new language or framework that is only trivially different from
the existing ones, yet touted as the next big thing I can only grumpily roll
my eyes.

~~~
mgrennan
We all have hopes that new things like languages will make things better or
easier. Mostly it does. Today's hardware beats the 4004 CPU I started with.

Technology will move forward but building tech on back tech is a bad idea.

------
Namrog84
I used a simpler analogy in a c++ class I used to teach.

Some people might argue that setting a variable to 0 or something is pointless
if you now your about to use it. But while technically it could add overhead.
The chance of bugs forming from a future refactor is decreased. And those who
track down sporadic uninitialized value bugs should know why it's almost
always better to just initialize values. And not implicitly always trust the
compiler will catch complain and or a future less knowledged developer won't
accidentally do something silly.

Many habits in programming are formed from habits and we're told to not do
thibgs(1 entry and 1 exit. No goto. Etc..) but few can back it up with why and
when it might be a worthy edge case

~~~
anarazel
I dislike that for another reason: It prevents the compiler from telling you
that you're using an undefined value. Just setting vars to 0 doesn't mean that
that's the right value.

~~~
jwhite
There's a worse problem, which I've seen in the wild:

    
    
        int some_function(...);
    
        int some_other_function(...)
        {
           int r = -1;
           /* imagine a bunch of other locals defined here */
    
           r = some_function(...);
           if (-1 == r)
           {
               return -1;
           }
          
           ...
        }
    

Now imagine someone changes the return type of some_function():

    
    
        char *some_function(...);
    
        int some_other_function(...)
        {
           int r = -1;
           /* imagine a bunch of other locals defined here */
           char *s;
    
           s = some_function(...);
           if (-1 == r)
           {
               return -1;
           }
          
           ...
        }
    

Oops! Every other reference to r has been removed except the declaration and
the test. Now some_other_function() will always take the early exit, and
because r is initialized in its definition the compiler does not complain. (In
real life, hilarity ensued.) If it was 'int r;' with no initializer this would
have been caught by the compiler.

Modern gcc is great at finding uninitialized and unused variables. -Wall
-Wextra -Werror FTW.

EDIT: referred to some_function() where it should have been
some_other_function().

~~~
lstamour
I'm pretty sure static analysis like Clang would warn you about such a thing
too... So maybe proficient programmers just need to keep their linters and
tools up to date! ;-)

------
WestCoastJustin
Here's the supporting "A Five-Stage Model of the Mental Activities Involved in
Directed Skill Acquisition" reference link for anyone interested.

[http://www.dtic.mil/get-tr-doc/pdf?AD=ADA084551](http://www.dtic.mil/get-tr-
doc/pdf?AD=ADA084551)

------
okreallywtf
Despite the reception this article seems to be getting here I find it speaks
to me pretty directly and summarizes some observations I've been making
lately.

I consider myself an intermediate developer (at just under 3 years out of
school at my first job) and I feel like for the first year or two I increased
my competence rapidly (and with it, salary thankfully) but I'm at a point
where without branching out into other areas it will be more difficult to
continue acquiring pure competence or I will do so at a flat or decreasing
rate because of the increasing complexity of concepts left to improve upon
(within my day-to-day work, not including side projects and academic
pursuits).

On top of that I work with a small team of other developers who are all highly
competent but only some of whom fit the description of proficient developers
in the article. I think the article describes really well the differences
between the two types, and I have tried to nail down what the proficient
developers do and how I can acquire the same skills and instincts they have.

The main things I have noticed are a) as the article discussed, always being
able to debate the pros and cons of an approach beyond just best practices and
without regurgitating things that renowned developers have espoused and b)
being able to be able to drill into problems in the code-base or our process
even if its due to technical debt that other competent developers are willing
to work around, but more importantly knowing when it is appropriate to down a
rabbit hole and when it isn't.

I'm lucky to be able to see the distinction in action and overall I think the
article helps to describe a distinction that I haven't been able to verbalize.

------
mod
> But the place where the intermediate programmer tends to get stuck ... is
> thinking that the difference between a beginner and an expert can be
> measured in how much stuff you know.

> And at its essence, proficiency is about "why you do things a certain
> way"—It's the difference between understanding each of the parts of a
> problem individually, and understanding how the parts fit into the whole.

So I guess it _is_ about stuff you know.

The article then goes into further specifics about how you have to know when
to apply what you know.

~~~
adekok
I'm sure everyone has worked with someone who has memorized a lot, but doesn't
know how to do much. Their productivity is limited.

There are also people with innate "know how", who can get things done without
much background knowledge. They just know how things work.

My $0.02 is that experts have both of the above skills. They know a lot more
than average people, and have better techniques for doing things.

My experience has been that once you reach a certain level of expertise, it's
better to "know how", than to know things. For the software I've written, I
just forget about the minor details, and have to look them up again. The
details aren't important, and just aren't worth remembering.

In contrast, remembering the problems and solutions is much more important.
The solutions can be applied to multiple problems in a way that simple
"memorization of facts" cannot.

~~~
Digit-Al
Yeah. I used to work with a guy who mainly knew databases, but also had to do
some C# as part of his job. He did loads of MS certifications, just to have
them on his CV, but was clueless and usually had to ask me how to do anything
more than the most simple programming tasks.

------
dingdongding
As a programmer I always write code considering if a new guy wants to take
over my code, he should be able to understand it and use my code with as
little complication as possible. Things should be simple enough that when a
new guy takes over your code he can be onboarded soon and doesn't have to ask
someone to explain him the magic pattern or secret sauce to under teams code.

~~~
horizone
I am some what the opposite. The person that comes after me should be able to
read and understand what I wrote without line by line documentation. If they
can't, they are not fit for the position. Although, if there is a quirk within
the code where something needs to be explained, it will have documentation.

~~~
huckyaus
I think you're agreeing with each other. Parent never specifically mentioned
writing documentation. I took their post to mean that the code should be easy
to understand.

~~~
horizone
You are right, I jumped the gun and read the opposite. Cheers. Sorry Parent.

------
hasenj
What the article describes as "competence" sounds like total incompetence to
me.

If you learn a pattern from a book or a class or a blog post, and then you
apply it in a project just because "the book said so" you are not a competent
programmer.

This might be an artifact of English not being my first language, but I would
reverse the definitions.

Proficiency means knowing how to use something.

Competence is knowing how to do something properly, which implies having a
deep _understanding_ about what is going on.

That seems to be how people use these terms anyway (regardless of the
dictionary definition).

Proficient in jQuery: knows the ins and outs of most jQuery functions and
plugins.

Competent in jQuery: non-sensical statement.

Proficient in git: knows most useful commands and arguments.

Competent in git: almost a non-sensical statement.

On the other hand:

Competent front end developer: understands how to develop a web based
application UI from scratch without being tied to a specific product domain.

At least that's how I understand these terms.

~~~
nimblegorilla
I agree that better terminology would be something like competent and master.

~~~
practicingdev
This is roughly the full Dreyfus model:

(1) Novice... does not understand anything but basic knowledge in the abstract
sense

(2) Competent... knows how to apply knowledge to solve concrete problems

(3) Proficient... sees how particular solutions fit into the context of
different problems (i.e. what tools to use, when, and why)

(4) Expert... picks the right tool for the job without having to do careful
analysis... works from intuition by pattern matching against fundamental
concepts combined with past experiences.

(5) Master... picks the right tool for the job without even being consciously
aware of the fact that they're "doing work" at all.

It's important to remember that all of these levels apply within specific
contexts... you can be master one thing while being a novice at many other
things.

But each step along the path is a gate of sorts: in that you can't really
understand what it's like to be an expert in anything until you're an expert
in at least one thing, and building expertise is easier when you have done it
at least once.

But a big problem (which we're mentally hard wired to be biased about) is
evaluating our own skills, as well as the scope of experience of others.

This is why someone with local expertise often thinks they can speak on topics
outside of their actual expertise, and why people tend to believe them when
they do.

"Thinking, Fast and Slow" by Daniel Kahneman is the best book I know on that
topic. Totally worth reading.

------
dukerutledge
Some of these remind me of Ed Kmett's YOW talk: "Stop Treading Water: Learning
to Learn"

[https://yow.eventer.com/yow-2014-1222/stop-treading-water-
le...](https://yow.eventer.com/yow-2014-1222/stop-treading-water-learning-to-
learn-by-edward-kmett-1750)

------
squiguy7
> Patterns, principles, idioms, libraries, language features—these are all
> tools. But a truly proficient programmer fits the tool to the job, not the
> other way around.

This isn't a unique statement but many people forget it.

We all have our favorite tools and we criticize others that don't have
complete parity. Picking a tool to use is often the hardest part considering
there are so many nowadays. It's easy to rule out a hammer when you want to
tighten a screw but in order to build a skyscraper you need to start with
something.

------
jwatte
"so many people struggle with high level programming ideas, like design
patterns"

That sounds more like the movement from "apprentice" to "journeyman." Is it
really expected that professional, experienced programmers should struggle
with the appropriate application of known techniques?

------
foxFive
As a budding programmer I like the ideas here, but I want to take it with a
grain of salt and figure it's best to have a wide breadth of knowledge before
going deep. Or rather, gain competence before striving for mastery.

------
awkward_yeti
> Pick a small number of specific skills you're simply good but not great at.

I am struggling with this one since forever, what are the skills-set a
programmer should enumerate through ? like how good they can connect to a DB
provider ? or how quickly they can set up a web server ? what qualifies as a
skill in this context ?

~~~
ysavir
Ultimately, it doesn't matter. The point of the exercise isn't to get better
at those specific skills, but to develop an understanding of high-end
proficiency, which you can later apply to other subjects.

Like many (proper) learning sets, the content of the exercise is irrelevant
compared to the deeper lesson.

~~~
awkward_yeti
Yes I can see the deeper meaning of the exercise, yet, it helps to know what
we're talking about specifically.

I am not proficient yet, and I would like to be, and I don't think it's one of
those (When it happens you'll know it) moments, I believe there is a clear set
of skills we need to work through first in order to see the forest for the
trees.

My question therefore is, what are those skills exactly ?

~~~
practicingdev
The web of foundational skills for software development is vast enough that
you can't really build it out from the bottom up.

What you can do though, is start with small projects and try to understand
every piece involved in them, and why you did things the way you did.

Repeat this with increasingly complicated projects, testing and synthesizing
what you learned.

~~~
awkward_yeti
So cross reference the common experiences from different small projects. That
does make sense.

Have you done that ? Or are you doing it at the moment ? because some hints of
those projects ideas will be awesome.

~~~
practicingdev
I am the author of the essay, so... yes!

The context I currently apply this in is that in the apprenticeship I'm
running.

So for example, we work on business applications and some amount of complex
analysis is needed because we work with raw problems (i.e. it's necessary to
interview the users/customers directly, collect raw data, etc... collect and
transform raw data from many sources before we can even start on a project,
etc)

I would start by trying to give my apprentice small chunks of the work we were
doing, at a task-based level. She would do fine when I could break it down
into well-defined tasks, but not do as well if I just gave her some raw
materials and said "OK, implement something that will solve <HIGH_LEVEL_GOAL>"

So we circled around that a lot, and realized part of the issue was the
challenge of thinking rigorously and synthesizing lots of details. We dug into
Gilded Rose kata together to practice that a bit...

(
[https://github.com/NotMyself/GildedRose](https://github.com/NotMyself/GildedRose)
)

Then after that, we went back to some more realistic work, talking things
through... taking notes... etc. It helped for a little while, but then we were
still hitting issues related to rigorous problem solving / analysis.

So then we went back and did some more exercises. This book chapter gives some
examples of the sort of "fundamental lessons" that can be pulled from specific
exercises, so long as you're looking at them with the goal of seeing the
deeper ideas behind the work you're doing:

[http://tinyurl.com/pbp-rigor](http://tinyurl.com/pbp-rigor) (PDF)

This is the sort of stuff I've been working on lately, because I don't think
there's a direct path towards getting the big picture if you don't have
someone guiding you, aside from a ton of hard work and patience combined with
continuous practice.

That said... keeping a journal does help. My apprentice has been working with
me since the beginning of the year, and she writes notes _daily_ on what she
does, what she studies, what she struggles with, etc. Periodically going back
through those is how we figure out what to do in practice and study sessions,
and I imagine even if working solo... you could try that.

Hope that helps!

------
avindroth
This article is way too long and without a proper table of contents. I don't
know what's important or not, so at a first glance I could not gauge
opportunity costs.

And also lists are meant for small items, not paragraphs.

Readability is respect for the reader.

------
ovrdrv3
It isn't often that you click on a link to the book referred to and it is the
pdf, sweet!

------
facepalm
Nobody knows everything, so I must admit I don't see the point of the article.
Maybe sometimes you get lucky and have the relevant knowledge for seeing the
big picture. At other times you won't have that knowledge. Are you proficient?

------
tooljob
>> But a truly proficient programmer fits the tool to the job, not the other
way around.

A truly proficient programmer finds the right tool for the job, learns best
practices on how to use that tool; makes mistakes, learns and improves.

------
rainhacker
Nice article, learned a new design pattern today. Wondering what are some
practical use cases of memento design pattern ?

~~~
rezashirazian
If you like design patterns checkout my articles
[https://shirazian.wordpress.com/2016/04/11/design-
patterns-i...](https://shirazian.wordpress.com/2016/04/11/design-patterns-in-
swift/)

It's a compilation of design patterns implemented in Swift, solving a real
world problem.

------
SubiculumCode
Seriously, I misread the title as "Traits of a(n) ancient programmer"

My first thought was "proficient"

~~~
SubiculumCode
and the correct answer to the original title is 'ancient.'

------
Vektorweg
In short: if you have done it before, you are now an professional who can
implement a very similar thing again. For everything else, you are not a
professional. Thats how I understand the article.

------
choward
No mention of testing?

~~~
rimantas
No mention of scrum, agile and pair programming either. Strange, huh? I'd say
*DD is nice-to-have but orthogonal to being proficient. Or sometimes just
counter-productive, if all it is is cargo-culting with zero understanding.

~~~
rhizome
I think testing has inherent benefits regardless of understanding.

~~~
Retra
Are you talking about some specific testing methodology, or does "running your
code and seeing if it works" count?

~~~
rhizome
Seeing if it runs is probably the absolute minimum of any testing methodology,
but my point is that (passing) tests are always good.

