
Thoughts on being a programmer - earnubs
http://www.yelsew.com/thoughts.html
======
tokenizer
_Be yourself._ Code for fun. _There's hundreds of ways to write the same
thing, don't be a dick about your way, but stand up for good practices._
Respect those who accomplish great things, because it was a lot of work, even
if they say it was a weekend practice, they took a lot of time to get to that
point. _If you code correctly, one line changes are possible._ Learn to desire
success more than you fear failure. (I like this one) _Don't become the old
people you hate, always try to learn new things, no matter how alien._ Who
cares if you're coding on production live? Right? Right? _Comments are for the
weak, tracing and prototyping code is not._ Mistakes are inevitable *It's hard
being the smartest person in the room sometimes, wear it with humility rather
than pride.

My version of the list. This was fun!

~~~
nickolai
>Comments are for the weak,

Care to elaborate on this ? Commenting code is bad ? Or did I miss the irony ?

~~~
recycleme
I've met a few senior level programmers who frown on detailed commenting (or
commenting at all). I cannot wrap my head around this since I consider it best
practice to comment.

A reason given to me was that "it takes up too much time to comment and when
you make a code change you need to make a change in the comments as well." To
that I say, so what! I would like the future me (or the future programmer) to
have full knowledge on what's going on in the code.

~~~
flatline3
> _I've met a few senior level programmers who frown on detailed commenting
> (or commenting at all)._

If they express those views, I wouldn't call them senior.

Commenting is necessary to express invariants, and to summarize complexity
that would otherwise require each reader of the code to understand the code
itself in depth.

Those are actually closely related things.

Very few languages are capable of succinctly expressing sufficiently detailed
invariants. Some are better than others -- maybe they support Maybe monads
instead instead of possibly-NULLs. However, it's rarely possible to express --
purely in code -- what the code is _supposed_ to do, what the input is
_supposed_ to be, and what the output is _supposed to be_.

Failing to express those things means that any future reader/maintainer will
be forced to trace your code, _in its entirety_ , to reverse-engineer how it
is _probably_ supposed to work. In many cases said maintainer can never know
for sure without tracing your code and _ALL_ code that calls your code --
otherwise, any change to that code could break undocumented behavior that
other code relies upon.

Anyone who advocates against comments is justifying laziness, and they're
wrong. The only supportable argument for not commenting is if a language is
sufficiently powerful and succinct enough to express all the invariants
normally expressed through comments, as well as being readable enough to
permit a future maintainer to understand the design of the code without
requiring them to spend an undue amount of time studying its inner mechanics.

I'm not aware of such a programming language.

~~~
rimantas

      “Don’t comment bad code—rewrite it.”
      —Brian W. Kernighan and P. J. Plaugher
    

Is that senior enough for you?

    
    
      > Anyone who advocates against comments is justifying
      > laziness, and they're wrong
    

No, they are actually advocating to put more effort in thinking about stuff:
how you name your functions/methods/whatever, how do you name your
arguments/parameters, how do you write the code itself.

To anyone interested I recommend to get a copy of "Clean Code" and read the
relevant chapter. IIRC "Code Complete" mostly agrees.

~~~
flatline3
> _Is that senior enough for you?_

No. Have you _read_ 70s and 80s C code? Tried tracing through the original
UNIX kernel sources? Tried _working_ with them?

To understand all the invariants of one small aspect of the system quite often
requires tracing through the whole system until you get to a well-documented
input/output module point (via comments, man pages, or otherwise).

Also, the quote (aside from it being out of context) says to not comment _bad_
code.

> _No, they are actually advocating to put more effort in thinking about
> stuff: how you name your functions/methods/whatever, how do you name your
> arguments/parameters, how do you write the code itself._

You can't define all the invariants -- or summarize for readability -- in pure
code.

~~~
ori_b
> _No. Have you read 70s and 80s C code? Tried tracing through the original
> UNIX kernel sources? Tried working with them?_

Yes. It's some of the easiest to understand code I've read. For example,
<http://unixarchive.cn-k.de/PDP-11/Trees/V6/usr/sys/ken/slp.c>

They're actually quite decently commented. The functions describe what they do
clearly, and the bodies show how they do it tersely, with comments around the
sticky bits.

Have you read through the original Unix kernel sources? Claiming that they're
uncommented and difficult to work with is surprising. (On the other hand, the
directory structure could be better.)

~~~
flatline3
Without tracing the backing kernel structures and the code that relies on
them, please describe _why_ sleep(chan, pri) works, and as a maintainer, what
I need to watch out for when modifying that code.

What does swtch() do? What does issig() do? Does that mean it's checking for a
signal during sleep? What signals could be generated? Under what circumstances
do I need to check for those signals? Are there any race conditions? Does
ordering matter? What happens if I move the call to issig?

Beyond the invariants, this code is _NOT READABLE_. I can't just glance at the
comments for an atomic unit of 4-5 LoC and see what it does -- I have to
examine the code in depth, running the logic in my head, and explore the
workings that way.

Reading code without comments is like tracing out a circuit without a
schematic or documentation. First you have to manually establish the _what_ ,
and only then can you even start to spend your time determining the _why_.

I work on modern BSD code. It's better than this old stuff, and I _still_ have
to dig to figure out how/why things are supposed to work. It's a headache
compared to properly commented and documented code, where I can just skim
standalone units and know what they do without having to trace everything
myself.

~~~
ori_b
Of course you need context to understand code. You can't get away from that
without essentially translating the rest of the code into prose and attaching
it to each line. At which point there are enough comments that you need
context to figure out which parts of them you care about, reading them becomes
a chore, and they essentially become noise. I've seen codebases with insane
levels of commenting. I found myself ignoring the comments and tracing through
the code.

If the model is simple and the code is clear, learning the context becomes
easy, and it fits into your head. Following code becomes easy.

~~~
flatline3
> _Of course you need context to understand code._

Comments decrease the amount of code you must personally read and understand,
and define invariants that _can't_ be expressed purely through the code.

> _At which point there are enough comments that you need context to figure
> out which parts of them you care about, reading them becomes a chore, and
> they essentially become noise._

I've never seen this outside of contrived examples from lazy developers that
think they're too smart to need to comment their code.

> _If the model is simple and the code is clear, learning the context becomes
> easy, and it fits into your head._

In other words, you must trace the entire system to understand it and then fit
it into your head. This is not advantageous to maintainers.

~~~
ori_b
> _you must trace the entire system_

No, just the part you care about. You do need a high level mental model of the
system. I've never seen a system where this is not the case, regardless of the
number of comments. Even literate programming -- or at least, the examples of
it that I've seen -- suffered from this. (Amusingly, I found literate
programming examples were often easier to understand by mostly ignoring the
prose and looking at the code.)

~~~
flatline3
> _You do need a high level mental model of the system._

That is extremely time-consuming to build without code comments and
documentation, regardless of how "literate" the code is, because _code alone
can not express sufficiently detailed invariants_ , and _simple logical/atomic
operations involve a non-trivial amounts of code_. (especially when writing in
C).

There's almost nothing I hate more than inheriting a complex uncommented code
base and spending hours or days tracing out the code to build a high-level
mental model, when instead, with reasonable comments, I could have had that
model nearly immediately.

~~~
ori_b
You want some sort of design document. Comments are not sufficient to describe
the way that the concepts interconnect. They are almost always detail
oriented, scattered and do not give the big picture.

Comments embedded in source code are singularly unsuited to giving the sort of
interconnection of concepts that allows you to quickly and efficiently
understand build a model of the system. They are a poor substitute for real
documentation.

Something like this should always be present to describe the overarching
structure of the system:
ftp://gcc.gnu.org/pub/gcc/summit/2003/GENERIC%20and%20GIMPLE.pdf
<http://gcc.gnu.org/onlinedocs/gccint/RTL.html>

Incidentally, I'm not sure if you're familiar with literate programming.
That's where the code is almost an afterthought to the comments. This is an
example of a literate program:
[http://tug.org/texlive/devsrc/Build/source/texk/web2c/tex.we...](http://tug.org/texlive/devsrc/Build/source/texk/web2c/tex.web).
You may be familiar with it -- it's tex, the core engine used by LaTeX.
Compiled to PDF, the source looks like this:
<http://eigenstate.org/tmp/tex.pdf>.

~~~
flatline3
Design documents are necessary, but are no replacement for comments. When
working in GCC briefly, I found the design documents to not be nearly so
valuable as the (few, poor) comments that existed in the code (objc).

~~~
dahvyd
The problem with comments is that they decay into irrelevance and worse, lies
(that chapter of Clean Code will live with me forever). You can't write a unit
test to ensure comment correctness, but you can for code correctness. Hence
the code is the only reliable source of the truth.

~~~
flatline3
Comments only decay into irrelevance if lazy developers don't do their job.
Circularly, it's developers that don't write comments that claim comments
decay into irrelevance.

Imagine that.

~~~
dahvyd
I work at a shop where we use comments sparingly if at all. Our primary
product has 14m LOC and 400k unit tests. We enjoy over 75% global market share
in our extremely lucrative industry. We didn't get where we are today by being
"lazy" as you put it. Comments are by very definition a redundancy when the
code is perfectly descriptive and self-documenting. Thus developers can get on
with their job and be more productive when they don't have to duplicate their
efforts for dubious benefit.

~~~
flatline3
> _We didn't get where we are today by being "lazy" as you put it._

The two are hardly correlated.

Have you ever worked with some of the Mac OS X code written by poorer teams?
For instance, the security framework? The internals of that code is a disaster
at best, and yet, the core OS enjoys tremendous success and market share.

> _Thus developers can get on with their job and be more productive when they
> don't have to duplicate their efforts for dubious benefit._

How do you determine the invariants of your APIs when writing code against a
module? I don't trust arguments that boil down to "we're much too important to
waste our time documenting, code is perfectly expressive!"

It's not. You're just wasting your time somewhere else, in little tiny
increments, every time you have to trace code a few steps down just to figure
out what it probably is supposed to do.

Or, sometimes in _BIG_ increments, when somebody new has to learn the code
base.

~~~
dahvyd
> the core OS enjoys tremendous success and market share.

How is _that_ relevant? OSX has at best around 10% global market share? I'm
talking market dominance here.

> How do you determine the invariants of your APIs when writing code against a
> module?

We flick through the well-documented code just as you would largely ignore the
code and flick through well-documented comments. Here is a simple example for
you:

    
    
        public class EntitySynchroniser : IEntitySynchroniser
        {
        	public EntitySynchroniser(BusinessObjectFactory factory, IDirectorySearcher directorySearcher)
        	{
        		Argument.NotNull(factory, "factory");
        		Argument.NotNull(directorySearcher, "directorySearcher");
        		this.factory = factory;
        		this.directorySearcher = directorySearcher;
        	}
        	...
    

The arguments here are invariant - they must not be null. I don't need a
comment that may or may not be written in precisely the same format between
100 developers maintaining the codebase. I simply look for the one call to
Argument.NotNull that all developers use in this case. The code is MUCH more
readable than if the constructor had a comment explaining that each should not
be null, mixed in with explaining what each should do. I can also determine by
file searching or through the IDE which methods have these requirements.

If readers want to know what this API is and what it can do they need only
look to the interface, or the implementation of it's methods in the class.
Each method explains what it does by maintaining the same level of abstraction
within the method. Like:

    
    
        public void MethodA()
        {
            DoFirstHighLevelThing();
            DoSecondHighLevelThing();
        }
    
        void DoFirstHighLevelThing()
        {
            // do less high-level things
        }
    

Each method call would maintain a constant level of abstraction so that the
code is easily reused, easily tested and easily maintained.

> You're just wasting your time somewhere else, in little tiny increments,
> every time you have to trace code a few steps down just to figure out what
> it probably is supposed to do.

If I needed to figure out why code wasn't working the way it should what's to
say a comment would be more forthcoming in explaining the reasons for the
defect? Surely if MethodA did "thing A" but was really doing "thing B" the
comment would tell me "thing A", therefore I'd be forced to examine the code
further anyway, only I'd be hampered by the deceitful comment also? This is
the nature of a defect - something that operates outside the documented
behaviour of the system or module.

Not to mention that your stated opinion is that comments should explain the
inner workings of things so that consumers can be well informed. This has the
potential for exponential maintenance as really low level changes are made.
Imagine that you change the conditions under which data access-level
exceptions are raised. If anything that ever touched your data source
explained what happened in exceptional circumstances you'd have to change
hundreds or thousands of comments, or face the sort of comment rot I mentioned
earlier. _This_ is the real time waster!

> ...when somebody new has to learn the code base.

This is _always_ going to be the case. Comments don't make this task any
easier than a well structured codebase. A well structured codebase comes from
developers making the conscious decision that any reliance on the crutch of a
comment is a failure to write proper self-documenting code. A well-structured
self-documenting codebase by definition requires no comments (except for the
"why" not the "how", which I fully support doing by the way).

~~~
flatline3
> _How is that relevant? OSX has at best around 10% global market share? I'm
> talking market dominance here._

Fine, I'm familiar with OS X, but I'm sure there's equivalent stupidity in
Windows.

> _The arguments here are invariant - they must not be null. I don't need a
> comment that may or may not be written in precisely the same format between
> 100 developers maintaining the codebase. I simply look for the one call to
> Argument.NotNull that all developers use in this case. The code is MUCH more
> readable than if the constructor had a comment explaining that each should
> not be null, mixed in with explaining what each should do._

No, it's not much more readable, because if properly commented, _I WOULDN'T
HAVE TO READ THIS CODE AT ALL_. Instead, my IDE or documentation browser would
tell me, inline, exactly what I needed to know.

> _If readers want to know what this API is and what it can do they need only
> look to the interface, or the implementation of it's methods in the class._

If you have to look at code's implementation, you've failed. Why isn't that
code a black box to me? Why do I care at all how it's implemented?

Why on earth would I want to waste time doing that instead of instant access
to high-level API documentation?

Moreover, it's a contrived example, because nullable/not-nullable is the least
of an API.

> _Not to mention that your stated opinion is that comments should explain the
> inner workings of things so that consumers can be well informed. This has
> the potential for exponential maintenance as really low level changes are
> made._

No, my stated opinion is that comments that are externally visible should
document externally relevant invariants.

Comments that are internally visible should document internally relevant
invariants (if the code does not adequately express those, as it often does
not).

> _A well structured codebase comes from developers making the conscious
> decision that any reliance on the crutch of a comment is a failure to write
> proper self-documenting code._

A well-structured code base comes from writing good code. Comments are _part_
of writing good code. Self-documenting code isn't fully documented code,
unless it's literally a literate programming language. Claiming otherwise is
just an excuse for you to be lazy and not write comments under the misguided
auspices of being much too smart to need them.

~~~
dahvyd
Sure, if I were publishing a public API I'd want to document the functions
available, but the fact is, the vast majority of the code we write at my shop
is not consumed outside our own codebase. Why duplicate the effort of writing
documentation when everyone has access to the code? There is no benefit for us
so we don't do it. We made that decision and it's the right one for us. Sure,
you have a different situation and I'm sure using comments has helped and
empowered your developers, but for us it makes no sense and is a waste of
time.

I'd suggest you stop trying to tell the world that senior developers must
conform to your narrow views (narrow, by the sheer size of the response
against your point of view here). Calling people things like "lazy" and
insinuating they inflate their own abilities simply because they don't do what
you think they should do is a pretty trollish thing to do. You obviously
missed the first point in the original link.

------
frou_dh
Something in one of Zed Shaw's old talks stuck with me. Roughly:

 _"Don't go with the flow of the industry. Try [unconventional] things because
there's something beneath [software] that we haven't figured out yet."_

I suppose there's two personal disclaimers:

\- I'm not that interested in the business aspect of software.

\- The answer to what the magic beneath is may elude me due to it simply being
"math, stupid".

~~~
toomuchcoffee
_...due to it simply being "math, stupid"._

Care to elaborate?

------
podperson
I liked "err vicariously" ;-)

It's good to learn from your own mistakes, and even better to learn from
someone else's.

~~~
lobo_tuerto
Yeah, but sometimes "vicariously" doesn't cut it, you have to "do the work,"
you have to grind it out.

[http://raganwald.posterous.com/what-ive-learned-about-
learni...](http://raganwald.posterous.com/what-ive-learned-about-learning)

~~~
podperson
Hey, it's a pithy one-liner (two-worder) -- and like any such chestnut is
going to be wrong a lot of the time.

Even so, learning from someone else's mistakes is "cheaper" than making
mistakes yourself. The further you can get by avoiding mistakes others have
made so you can get to your own personal mistakes, the better.

I'd say "err vicariously" gets better the more you think about it, rather than
needing to be nitpicked.

------
jawr
>Always back up before tidying up. I liked this piece of advice, it's a lesson
we all hate to learn.

~~~
arscan
Happened to me last night -- I wish I read this yesterday. Who am I kidding...
I prefer to learn these lessons the hard way :)

~~~
Ralith
Don't you use version control?

~~~
evincarofautumn
To be fair, version control and backups should be separate things.

~~~
georgemcbay
IMO version control, file versioning and backups should all be separate things
and ideally all available.

Even when using a version control system that allows for robust local
branches, sometimes it is nice to be able to revert a specific file's state to
a known recent version that you never bothered to commit. Sometimes editor
undo is sufficient for this, sometimes not. Dropbox and Google Drive have both
saved me some time in this area (like 15-30 minutes, not days, but even that
is appreciated) recently.

~~~
Ralith
Isn't that just evidence that your commits aren't granular enough? Certainly,
simply backing things up generally won't solve your problem, since good backup
procedure can involve offsite storage being hours out of date.

------
alanmackenzie
I would add: Don't release on a Friday.

~~~
gacba
Sadly, the company I work for ONLY releases on Friday nights because the
business closes out at 5pm. _sigh_

------
recycleme
Communicate often. Have a beer with a fellow programmer. Don't be afraid to
break code.

~~~
sukuriant
> Don't be afraid to break code.

Just not in production :)

~~~
codegeek
Problem is that code always breaks in production. What we should strive for is
not to cause a critical break that creates massive loss for the company. But
code has and will break in production.

------
twakefield
> There's always plenty of room for improvement - in your code, in your
> abilities, in you.

I just saw an amazing movie about a man that embodies this philosophy: "Jiro
Dreams of Sushi"[1]. This man's dedication to further mastering his craft is
unparalleled. Even though he is widely regarded as the best Sushi chef in the
world, he is still singularly focused on becoming better every day.

I highly recommend watching - it's very inspiring.

[1] <http://en.wikipedia.org/wiki/Jiro_Dreams_of_Sushi>

------
norswap
Work on unimportant problems. <http://www.yosefk.com/blog/work-on-unimportant-
problems.html>

------
einhverfr
The bit about there always being room for growth was driven home for me
yesterday as I was looking through how to build an object model in PostgreSQL
using object-relational features. I went through the features one by one and
discovered that I had only scratched the surface of that aspect of PostgreSQL.
I suddenly understood how to rethink what I was doing in terms of design
patterns in order to build object interfaces in the db for the relational
underpinnings.

------
3am_hackernews
It is written so beautifully that the "code" part of these thoughts can be
substituted for many other things: design, engineering, life etc.

------
joe_the_user
_Don't be an asshole_

Agreed but on the page, it looks a bit of out of place with the other points.

My mind fills in the details as "don't act like you are the programmer who's a
hundred times more productive than the others, even if it seems like you are".

But that's a big question. Apple Computer arguably expects its programmers to
all be the x100 producers and was managed by someone who it more or less was
admitted to be an asshole (a genius, inspiration, unique asshole but still an
asshole).

So it think the greatness and asshole-dom question is not settled for people
even if I would embrace it.

------
joe_bloggs
"Err vicariously"

Loved that. Subtle, yet deep!

------
jebblue
That was a short, concise, pragmatic, wise and rockin article.

