
Ask HN: How obsessive are you with your code? - mishmash
So.. realized today that I probably spend an hour a day refactoring code. It's usually towards the end of the day, and includes items such as renaming variables, creating/moving classes, enforcing stricter patterns, writing in-depth comments, checking and removing dead code, and other general upkeep issues.<p>My question: is this too much? too little? How much time do you spend on these activities? Should I spend more time upfront thinking before coding (gasp!)?
======
inerte
I've been called a perfectionist because of my coding maintenance. Dozens of
my commits are "Source code formatting", where I try to make the code closer
to PEP8 (Python).

But I don't go actively looking for things to "fix". While reading code, if
only one line is separating functions, I add another. I add \ to line ends
trying to limit width to 80 chars.

Lately my mantra has been "Shipping is a feature". Code working is my number
one priority. But like most of the people, I like to think I'm above average,
so I don't believe I write _bad_ code at the first time. I know it's not
perfect. Just by saying this, I remember of things I know I should change to
make the code better, but why bother?

What you must always pay attention is the balance between creating value for
your customer, and for you as a professional. And even when you do things for
yourself, always remember your main objective is to make things easier in the
future to create value for your customers.

Caveats apply, of course. A refactoring to allow more modularity or whatever
in the future might be good to do now, but honestly usually there are more
pressing matters (unless the current pressure is to add some module
functionality).

It's hard to give any straight answer. There are no hard rules, like "you
should only refactor during one hour per-day". Maybe you're doing something
where a big-design-upfront is not possible. Maybe not.

These things come with experience, tough. And where you want to keep your
focus. If I was working on a 10 year code base where the original programmer
has left the company, and didn't document anything, then I guess I would spend
more time nurturing the code. But my job today is too fast paced, and "when it
will be ready" is my customers/stakeholders number one priority. I negotiated
and told them quality would suffer, and they are aware, but don't care much.

~~~
fexl
I stay happy as long as my black box continues to function as advertised. That
keeps me from obsessing over internal details. Ugly code can stay ugly and I
sleep fine at night.

But whenever I wade into the code for good reason, I reward myself by
refactoring whatever areas I happen to touch. It's like throwing a fish to a
seal. That way I always get a chance to do fun things like unifying similar
code or making code more data-driven.

I'm still a perfectionist, but I'm also a strategic procrastinator. So while
I'm working on code, whenever I think of _anything_ , however small, that
might improve it, I'll throw in a comment such as "TODO 0703 might want to
tighten this up" or "TODO 0703 you need to test this case before releasing". I
am so relentless and unforgiving that sometimes the TODOs multiply like
rabbits.

Before I release anything, I grep on "TODO". As long as any TODOs show up, I
can't release. If I need to put off something until later, I'll change that
"TODO" to "LATER". Occasionally I'll make a point of revisiting my LATER
entries, converting some of them back to TODO. That way perfection is an
ongoing process, not an attained state.

~~~
Quiark
The problem I have with refactoring todos is that after a time it's no longer
clear to me why the refactoring was needed (unless it's obvious, but in that
case I probably already did it).

~~~
fexl
To be clear, I usually add TODOs only for observable features and
enhancements, rarely for internal issues like refactoring. My point is that I
usually refactor only when I'm already in the code for other reasons, as a
reward for doing the immediate observable changes. This helps focus my
refactoring efforts only on code that is already changing for the customer's
benefit.

------
kineticac
There's a good balance of writing it right the first time, and spending too
much time with the details and not the actual feature you're implementing.

With enough experience, you'll know how to start writing something such that
it won't require extensive refactoring. Make sure it's good enough that if you
don't have enough time, it's still good in these two major ways: as fast as
possible with no redundancy, maintainable by someone else.

------
cperciva
_Should I spend more time upfront thinking before coding (gasp!)?_

Probably. But anyone who reads my blog could have guessed that I would say
that.

I tend to spend a long time writing code and then never look at it again. I
even forget the implementation details. It makes my life much easier -- if I
had to keep thinking about how btree_node.c calls proto_lbs_client.c which
calls wire_requestqueue.c which calls wire_writequeue.c which calls
network_buf.c which calls events_network.c I'd never get anything done. And if
I can remember all that, I'm going to think about it whether I like it or not.

Just get the code right the first time. Then you can use it as a building
block without needing to worry about implementation.

~~~
eru
I often use code as a tool to think about code.

So my time spent upfront may actually look like coding. Depending on the
problem I may use strange domain specific languages like scribbling equations
on dead trees.

The artefacts of this upfront thinking may get re-used in implementing the
solution. Than it can look like refactoring.

------
watmough
In answer to the headline, not very! I prefer to get something working, then
I'll refactor, reformat and rewrite until reliability, readability and
performance meet my needs. This process can take months, depending on the
required balance between adding new features or improving existing ones.

This approach works quite well for me, since I generally plan code in my head
before a coding / transcribing session.

An hour a day sounds high, but understandable if you are working on a scrappy
code-base. It sounds like you are doing a good job, especially since you will
be eliminating 'code-smells', fixing warnings etc.

I always like to plug it, but Code Complete was the book that transformed my
attitude towards 'my craft'. Great book, should be mandatory reading.

------
Zev
Too much, probably. For me, its not usually not related to reorganizing my
code around. But, I'll nitpick over whitespace or brackets. I won't fix
formatting up if I'm in the middle of working on something, but I'll make a
mental note to come back to it.

My justification (to myself, at least) is that when I encounter code thats
badly formatted, I find that the flow doesn't tend to make much sense (either
to read, or as its actually executed) and it needs refactoring anyway. So,
I'll fix the formatting up and read the code to see what it does. And then
refactor parts, if necessary.

~~~
eru
I do almost the exact opposite: I see that fixing minor flaws in the whole
code base is a temptation, but I do not have enough time to do it. So I just
polish everything that my edits touch (i.e. every function that is affected).

~~~
Zev
_...but I do not have enough time to do it._

Neither do I, really. I don't go back to change something around unless I _do_
have time.

------
paulcarey
When I was employed as a developer, I was quite obsessive about refactoring my
code to the point where I considered it elegant.

Now I run my own company and am the sole developer. So these days I tend to
think if my code is well factored, I'm doing it wrong.

It's not quite that simple of course. The lower down the stack a chunk of code
lies - the more things that depend it - the more I want it well factored and
well tested. But I'm quite comfortable with code high up the stack being
scrappy, hacky and untested.

------
exception
I try to follow a simple rule.. Leave the code in a better state than I found
it.

Every time I submit a revision I try to include a change which improves an
area of the code outside of my main focus.

By doing this I am constantly improving and re-learning parts of the codebase
that otherwise become moldy.

So, A typical checking might be something like...

Add ability for animation tracks to play in reverse. Add missing null
reference check to CalculateWorldTransform Improve per of serializer by 10%
(avoid string parse for main line case) BUGFIX #1087: Keyboard input delayed
by one frame

Basically, I try to make refactoring/improvements an ongoing part of
development rather than a chore.

------
HeyLaughingBoy
For the last few months, I've been trying to enforce a discipline of Design,
Code, Inspect Code for errors, Unit Test, repeat. I try to do this over
relatively small increments like 1-2 functions at a time, maximum. The change
from what I did previously is that before I didn't do much detailed design --
that happened as I was coding. And reading code for errors was only done if a
test failed.

It gets tedious very quickly but at the same time the number of errors that
persist to Unit Test has dropped considerably.

After spending a _lot_ of time thinking about Software Process, I've concluded
that the biggest gains come from engineering discipline, not heavier process,
so yeah, I don't think you're doing too much. Although I wouldn't force
code/design into patterns.

A lot of the code I'm modifying these days is legacy stuff with 300+ line
methods!!! Although it was written by a pretty smart guy, I really wish he had
heard of refactoring and removing dead code: I have a burning hatred of
commented out code and code that never gets executed.

------
thinkcomp
This really starts to matter when you're working with other programmers.
There's always a fine line between too much refactoring and micromanaging, so
I basically try to keep things to a level where I can quickly understand
what's going on with one read-through. If I can't, there's a problem, and it's
time to start cleaning things up.

~~~
mishmash
> This really starts to matter when you're working with other programmers.

And see I've been solo for about two years which means I haven't had to manage
any of those external expectations that you get from being on a team.

------
mcritz
I ask myself two things: Will I remember this later? Will other developers be
able to read or understand this?

Some code is obvious, no comments or naming is needed. Otherwise, be obvious
or leave enough comments to make life easy for your team, or “future you.”

------
damoncali
First make it work,

Then see if anyone uses it,

Then make it good.

The time to refractor is when you see a real time savings from doing so, not a
hypothetical one. It works for me at least.

------
PKeeble
I refactor at one of two times. Its either after I get my unit test working or
its a change to the structure of some code so I can add a feature. So its an
activity I am constantly doing throughout the day to make sure the new
functionality is put in relatively well.

In the same way I can't count how long writing tests takes I can't count how
long refactoring takes as its simply part of the normal development process. I
only ever account for work that includes these activities because after doing
it for so many years I realise you can't split them without doing a hack job.

------
Tichy
Are you perhaps doing that because at the end of the day, you are too tired to
get real work done? Might be better to take a break...

~~~
mishmash
This actually probably has something to do with it. I've been working on a new
project lately and have been pretty jazzed up about it during day.

------
leif

        -Wall -Werror -Wextra -pedantic
    

that's all you need

~~~
eru
I guess you also need a way to suppress spurious warnings. And C compilers
normally don't warn you about follies, like using global mutable state. Or
using C where it's inappropriate (or not using C where it's appropriate).

Though I do agree that ridding your code of compiler warnings is a good idea
in general. Because when a warning comes up afterwards, it will actually have
some signalling value, instead of being ignored in a sea of similar warnings.

~~~
leif
> I guess you also need a way to suppress spurious warnings.
    
    
        man gcc
        ...
        You can request many specific warnings with options beginning -W, for
        example -Wimplicit to request warnings on implicit declarations.  Each
        of these specific warning options also has a negative form beginning
        -Wno- to turn off warnings; for example, -Wno-implicit.  This manual
        lists only one of the two forms, whichever is not the default.  For
        further, language-specific options also refer to C++ Dialect Options
        and Objective-C and Objective-C++ Dialect Options.
    

> And C compilers normally don't warn you about follies, like using global
> mutable state.

I mean no great disrespect, but if you need a machine to remind you not to use
global mutable state, get back in the oven, you're still a bit gooey on the
inside.

~~~
eru
I was just arguing against

    
    
      -Wall -Werror -Wextra -pedantic
    

being __all__ you need. I don't doubt that those options are certainly part of
a healthy breakfast.

------
junkbit
Codecraft is important to me. I am obsessed with whitespace and consistent
names. Imagine my delight when I found a gedit plugin called Elastic Tabstops!

<http://nickgravgaard.com/elastictabstops/>

------
bensummers
Before I commit any code, I spend a surprisingly long time making sure the
diff looks neat and it does things the right way.

I wouldn't revisit old code until I needed to change it for another reason,
since all changes should be thought out properly.

------
plq
refactoring is a natural part of coding process. in an ideal world, it only
has to happen only when you need a particular chunk of code in more than two
places. otherwise, time spent without adding value is just wasted.

but this is not an ideal world and from a recent thread about a similar
subject, i got the impression that most of us don't like the code we wrote the
second time we look at it.

i guess it's okay to spend time on code that's already perfectly working as
long as you don't miss your deadlines (or arrive late to a date, or
something).

------
j_baker
Experience is nothing but trial and error. Once you've been programming for a
while, you'll get much better intuition about what works and what doesn't.

------
adnam
If that hour a day pays you back in lower maintenance costs, then it's worth
it. An ounce of prevention is worth a pound of cure.

