[racket] Aging code

From: Sean McBeth (sean.mcbeth at gmail.com)
Date: Wed Jul 10 18:03:07 EDT 2013

I just spent the last several hours sifting through the folders and folders
of code that have accumulated on my hard drive over the last 15 years. I do
this about once a year or so, so there actually wasn't anything from as far
back as 15 years because somewhere in the middle I was ashamed of how much
of a noob I was and didn't think that I would like to keep some of those
programs just for posterity. But anyway, point is, the only way the code
pile is manageable now is because I've thrown away a lot of redundant, bad,
or useless project files.

Now, this isn't necessarily Racket-specific, but I've started to notice
something along the way: certain projects seem to age more than others, and
they age in different ways.

One example: a JavaScript library for drawing shapes on the screen, by
positioning colored DIV tags as pixels, adaptively combining runs of pixels
of the same color into rectangular DIVs. At the time, there was no other
way to make dynamic drawings in the browser (as these were the days we were
struggling to convince clients to upgrade from IE5 to IE6). That code is
completely useless now, there was nothing special about it other than "in
the browser". So there seems to be one style of aging in which *new
advances in technology make old projects obsolete*.

The opposite side of this coin: a game I started writing in Microsoft XNA,
that I am still terribly keen to complete, but now XNA is a dead platform.
So *technological progress made the underlying API obsolete, but not the
project itself* (in this sense, the advent of the iPhone and Android
systems stole the indie game developer attention away from XNA, thus why I
list this as tech progress). This is particularly scary!

Another: a priority queue that I wrote in C# for .NET 1.1 is *terribly*
antiquated, being pre-generics and thus untennable in any modern .NET
project, but before then it was an extremely useful bit of code. On the
other hand, the adaptation of it that I wrote for .NET 2.0-- to support
generics--still holds up and is still useful (code styling issues not
withstanding). So there seems to be another style of aging in which
new *advances
in technology gave us have higher expectations for our projects, *even
though the fundamental need for the project still existed.

Styling issues segues into another example: a task managing application for
the desktop with the option to store tasks locally or on a centralized
server. I still think this project could be very useful, especially coupled
with a mobile companion, but the actual code itself is ugly to my
sensibilities now (it is a very small project that employs a terribly
complex MVC architecture that was all the rage in the 2008). There are a
fair number of these sorts of incomplete projects that, while I would still
one day like to complete it, I cannot stand the *style *of code I wrote
back then, even though it was very good by the standards of the day. Now, I
would probably just restart the project from scratch. So, *our growth as
programmers and the ever changing culture of programmers can kill our
desire to revisit the project*.

There is a related bit of aging in the task manager example: even if I
swallowed my pride and did refactor the project instead of rewriting from
0, there are parts that would get refactored to nothing. Certain wrappers,
written as stand-alone libraries, of standard API features would just get
thrown away completely. I originally wrote them. Today, my old decision to
wrap the API feels short-sighted, the API was perfectly fine and it was
only my lack of understanding of it that made me feel it was inadequate.
So, *our growth as programmers can make us aware of the crutches we
employed in the past*.

I think I see some patterns here. It seems that a project can either become
"stale" (it is still good in concept, just old) or it can become "rotten"
(there is no longer a use for the project, it must be discarded), and the
project can come to this state due to external progress in technology and
culture or internal progress in skill or style.

Obviously, we can't do anything about rotten projects. If something better
comes out and makes an old project obsolete, well that's that, time to move
on to other work.

But stale projects are interesting. I'd like to be able to organize my
projects in such a way that recovering from staleness is easier. If I write
an RPG today with a complex economic system, I don't want whiz-bang future
graphics or changing cultural notions of how menus in games should work to
invalidate that economics code. If I write a work tracking program, I don't
want some future need for a VR helmet UI invalidate the code that generates
reports and prepares it for plotting.

Some thoughts I've had on how to do this:
-- *Open source the projects/make the project a contribution to an existing
open source project:* if the project is useful, then other people may find
it useful, and help prevent it from getting stale. This technically has
nothing to do with slowing or stopping the aging of the code itself, it's
just being reactive to the aging process.
-- *Something handwaivey about Unit Tests:* I've noticed that my
stale-not-rotten projects all have a decent set of unit tests behind them.
Did the unit tests make the code more robust? Or are the projects just of a
particular nature that they would survive longer, a nature that is also
particularly suited for TDD? Did the code age, but the unit tests helped me
to maintain it over the years? Or is it simply the YAGNI principle that
drives TDD: the bulk of the code was for a real, present need, rather than
an imagined, future need, thus there was never a chance for the future to
prove the code wrong? Thus, TDD is correlated here, but I cannot claim it
to be causative.
-- *Embrace more of the Unix philosophy of small programs doing one thing
well.** *You cannot deny that programs like *ls, cd, mkdir, grep*, etc.
have lasted a very, very long time and have no need for being changed
(beyond the occasional discovery of defects). But that's systems
programming, it's not clear what that means for applications programming.
What is a small, does-one-thing-well program in the middle of a Customer
Relationship Management suite? There is a whole chunk of programming in the
area of *workflow* that doesn't seem to be generalizable.

This last issue may be the most important one. I want to be productive, and
by that I mean I would like to stop reprogramming certain projects over and
over again, just because a client says they want it in Ruby.NET 73. I want
to be able to use clients to write canonical projects (the contract terms
are not an issue here, I always include terms to allow for open sourcing of
mundane and non-business-secrets related code) and then tell future clients
that they can take the canonical example or go find a different consultant.

Anyway, I'd like to hear your thoughts and experiences. How often do you
revisit old projects? What has been your experience with your old code
hand? What do you do about your old projects? This seems like it would be
pertinent to the latest developments with package management system as
well, as there are a lot of aged (both stale and rotten) projects on PLaneT.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130710/56d82e16/attachment-0001.html>

Posted on the users mailing list.