Code Satisfaction

Reading the comments in Dick’s latest post got me thinking about how we, as programmers, are really never satisfied with what we have/write.

And I was reminded of this paragraph from one of the chapters in Joel on Software:

There’s a subtle reason that programmers always want to throw away the code and start over. The reason is that they think the old code is a mess. And here is the interesting observation: they are probably wrong. The reason that they think the old code is a mess is because of a cardinal, fundamental law of programming:

It’s harder to read code than to write it.

I know I’ve been guilty of that several times. I just *know* that I can write it better the second time, when I understand all the complexities and subtle issues and objects that *really* interact in the program, but the effort required to do so is just too great.

So I was curious, are you ever satisfied with your code? is it even worth to look at old code just to always say: “Wow, this is ugly!” ? or is it just part of who we are and we have to rely on other people telling us to NOT do something?

BTW, if you haven’t read that book, I highly recommend it.

Posted in Uncategorized

25 thoughts on “Code Satisfaction

  1. I think it can be more subtle than that,

    quite often when you come back to your code after a couple of month/year, you first dont remember the exact thinking you had at that point, and you also learn many(hopefully) things in between, so doing it today you would go some other way, but that doesnt always mean that this new way would be better.

    I remember learning array formulas a couple of years ago, and I wanted to throw that everywhere, then I discovered that sumproduct was quite often faster and easier to read so I started sumproducting everything, then dbase functions etc… etc…

    Of course sometime some methods are quite efficient and must be used to be mroe flexible etc… but most of the time I found out when reading (and understanding ) my old code, that it does the job well enough, and I remember something very wise: if it aint broken, dont fix it

  2. I’m from the streets man. Naming conventions, indenting, and commenting if for nerds who watch Star Wars in a Klingon mask.

    Any code that works is good code.

  3. Well, just this week I had some rare idle time at work and went through some macros in my personal.xls file. I couldn’t help but try to tweak a few of them to make them faster and more functional. I am not a professional or even semi-professional programmer but I still like to try, (can’t resist) and improve my the code in my macros. I always learn a little more by tweaking.

  4. I agree its harder to read code than write it, and Joel may be right in his area about quality. In my experience though a lot of the ‘old’ Excel VBA that I see is genuinely a mess. Most of it breaks every best practice recommendation I have ever read. However working code is working code (well as long as you can be sure it works correctly).

    As to my own code: If I look at something I wrote 10 years ago and can’t improve it after a further 10 years experience, then I probably havent used my time well. As it happens I have left plenty of scope for improvement! Just need the time to get round to it.

    cheers
    Simon

  5. I also agree with the “harder to read than write” argument.

    With regards to the satisfaction portion, though, I can say that I’m usually satisfied with the code once I’ve written it. Looking back on it later, however, can be another story. The true test, of course, is if it is reliable or not, but I’ve certainly cringed when looking back on some of the functional code that I wrote five years ago.

    I agree with Simon’s point though. If you can’t improve your code when looking back after 5-10 years, (or even less,) you probably haven’t learned much. (There are always exceptions, to be sure, but as a general rule I’d say it holds true.)

  6. “Naming conventions, indenting, and commenting is for nerds who watch Star Wars in a Klingon mask.”

    I used to think this way, but I find these all help me understand code when I reread it later. In fact, I run Smart Indenter (Thanks, Stephen!) dozens of times a day, especially on code sent to me from elsewhere. The naming conventions are my own, loosely based on Romanian, but more along the lines of Simonyi’s goal of understanding than of following rules. I’m always a little lean on comments, hoping that clever variable names can be self-documenting.

    “If I look at something I wrote 10 years ago and can’t improve it after a further 10 years experience…”

    Except sometimes the old code required learning something obscure about APIs or something, which I’ve forgotten. In this case, it’s better not to try too hard to fix it.

  7. Talk about conventions, standards, acceptable practices, etc. all you want. For the stuff that I do, which is probably not nearly as detailed as what some of you do, I still follow a post from JE McGimpsey on the NGs:

    “My US$0.02:

    First, for 90% of VBA code, any code that (1) does what you want, (2)
    doesn’t do something you don’t want, and (3) does it in an acceptable
    time, is good code.”

    This was a response to one of my posts several years ago. Somehow I also got involved in a couple of emails with Dick regarding “standard” coding practices. His response:

    “I don’t have any trouble telling people what MY generally accepted practices are because it was the people who came before me that helped shape my opinions.”

    Come to think of it, I was supposed to email Dick some code that he volunteered to check out for me. I guess I was too worried about billable hours for my “real” job.

    So I think as long as works, it’s fine. Although I’m still learning that commenting is VERY important. :)

  8. I tend to change code only if I am convinced it would improve performance

    For Example – Till a few years ago I would define Dynamic Ranges using Offset and Counta and then one fine day I finally managed to read the article of calculation secrets on Charles website which said Offest was volatile and Index was not…. and fzz or keepITcool (dont remember) commented on this blog that Index/Counta was a better way of defining dynamic names…
    I tested this on a project…. Changed 60 odd dynamic names from Offset/Counta to Index/Counta… and I did find an improvement in calculation time….

    Another tip from Bob said that =Sumproduct(N(Condition1),N(Condition2),ArrayToSum) is faster than the double unary syntax….but I later discovered that this syntax cannot handle arrays of different dimensions…. So I changed back to =Sumproduct(Cond1*Cond2….,ArrayToSum)

    When I learnt arrays…I changed a lot of looping code in reading in to an array and pasting on to a range… It definetly improved the speed…

    I am look to modifying/improve my own code….I would however be very reluctant to touch someone elses “working” code… because I would never completly understood the thought process that would have go into making of the code…

  9. I tend to go along with the “If it ain’t broke, don’t fix it” mentality.

    As others have stated, if the finished product comes out the way you intended it to, the code is good.

    I have a number of large projects (5K+ of code) that’s heavily documented, with intuitive variables, controls, etc. and I still have absolutely no idea what it does (but it works).

    I think that with the speeds of most computers nowadays, sloppy code becomes less of an issue. I’ve read numerous threads in the ng’s as to what’s more efficient, time saving, etc. but….
    saving a few nanoseconds here and there aren’t really perceptible to the end user.
    Another problem (at least for me) is when I compress some code, I’ll have absolutely no idea what it does when I revisit it one day. Sometimes the long version is easier to modify and decipher so wasting a few more nanoseconds here and there can be worth it in the long run.

    I do remember creating a macro in Lotus many many years ago running on a 486 that took a little less that 2 hours to run to completion. Those days are gone and I’m sure that same macro would only take a few seconds to complete on my current PC.

  10. Never a truer word then “harder to read than write”

    A few of my Excel programs used locally are now going global within the company I work with, one in particular I have virtually spent the last 3 day’s doing a complete re-write even though it has worked perfectly since I released it to the local users 6 months ago, most of the time was spent on what Alderaic wrote above:

    ‘You first dont remember the exact thinking you had at that point, and you also learn many(hopefully) things in between, so doing it today you would go some other way, but that doesnt always mean that this new way would be better.’

    The changes that had to be made for it to go global were minimal and would have taken at most 1 hours work.

    So after reading Pablo’s and the other comments here my code will be left alone and only change what is required for it to go global.

    Oh and after the full re-write, the program runs around 7 seconds faster and the code looks pretty and is now full of comments …..

  11. I used to think that the code I wrote was intended for one of three possible audiences. (1) Code that was intended for me didn’t need much in the way of comments, nor did it require much tweaking later on because I wouldn’t have quit coding until I was happy with it in the first place. (2) Code that was intended to be taken over by another programmer for lifecycle maintenance. This required a bit more comments out of courtesy, but it was the other poor guy’s responsibility to keep it up. I would only need to see this again in the most dire of circumstances. (3) Code that was intended “for the masses”. This would require the most comments, but again, it was the end user that had to live with any maintenance. The common theme here was that my thinking brought me to the conclusion that if I put enough work into the project up front that I wouldn’t need to do much in the way of tweaking. But then the real world hit me with things like “oh, by the way, today the enterprise went from Database Product X to Database Product Y, and now your program can’t talk to it anymore”. In short…. it seems that if you touch it once… you own it for life.

  12. The problem with “If it ain’t broke…” is that you’re probably looking at the code because it is broken, or at least needs a new feature. While I wouldn’t change working code (although like Juan, I’m tempted to), I also would never make a significant change without considering the quality of the existing code. I don’t want to throw good code after bad. All that has to be balanced against who’s footing the bill.

    Tushar and I were discussing a change he made to some code recently. It was a pretty significant change, but because he encapsulated and abstracted his code properly to begin with, the time to make the change was trivial. It’s important to me to keep hearing stories like that. Because so much of my code ends up being used only by me, it’s easy to cut corners. I recently completed a project for a client that is working beautifully. The few changes I’ve made have been easy because I documented the code so well. If I had to do it over again, I would have has used more class modules and I think making changes would be even easier. When the client looks for a major upgrade in the future, I’ll probably wish I had.

  13. “It was a pretty significant change, but because he encapsulated and abstracted his code properly to begin with, the time to make the change was trivial.”

    I’m getting better at this encapsulation and abstraction thing, writing subs as functions, putting stuff into classes. I’ve noticed that it helps me understand the code better when I’m reading it, it helps me not worry about the parts that are working fine, because they’re off in their own little module, and it helps me make changes quickly and easily.

    In a recent project, I had an Excel add-in that did some SQL to read data from CSV files and ran through some userforms for the user to make selections. The client had me change it to VB6 so it would run on machines without Excel; I had to redo all the forms, but the rest was nearly a simple export-import exercise into VB6, because it was already broken into bite sized pieces.

  14. I am a bugger for going back and re-doing things after some time for various reasons – be it changing requirements, or just that I have some idle time and I think that something is due an update.
    I found that the stuff I put together when I first started using VBA a few years ago is, by today’s standards, messy, unnecessarily complicated, and full of redundancies. I didn’t think so at the time. I’m fairly certain, that if I come back to stuff I’m writing today in a few years, I’ll think so again. This is very likely to be at least in part due to the “harder to read than write” theory, but I like to think it’s more down to my improving technique. At least I hope so, otherwise I’ve kinda wasted the time in between…!

    I actually get a great sense of satisfaction if I can reduce the run-time of a process by a handful of seconds, or the size of a workbook by a couple of dozen K, whilst retaining or improving all the functionality when revisiting it some time later. But then, I also have all the X-men films on DVD and understand the concept of midichlorians…. ;-)

  15. My best practice rules are simple…

    Write pseudo code on paper first and break your problem up into the smallest bits you can think of.
    Start writing in VBA by typing up a list of the names of the subs you wanted to build
    Go back and describe them at the top of each sub in some green.
    Try to keep yours subs looking like a paragraph and never write a chorus.

    Never ever write more than a screen’s worth of code in any sub if it is bigger then chop it in to three or more.

    It sounds boring but you don’t need much more than this to start writing nice code.

  16. While I don’t write a lot of code I have been tempted, once or twice, to revisit one of my proudest achievements. I inevitably start off planning to re-write from scratch, find that an existing method is the only one I know, decide to recycle that piece of code, then find I don’t actually understand some of the other bits. The whole thing gets shelved again as ‘too much work’.

    The problems are these (some already mentioned). 1) The code works. 2) The finished (working) product is extremely satisfying and you tend to forget the pain and hard work it took to get there. 3) The quality of the commenting isn’t sufficient. 4) Several key parts of the code were worked on the reduce them to their barest possible components, when something more wordy and self explanatory would have been better, meaning I’ve created some nice but impenetrable ‘black holes’. (I don’t like redundant code one bit but it’s a fine line between ‘terse’ and ‘what the hell?’ when you read it back months later).

    Which is why I’m grateful for this blog. I can write some O.k. code when motivated. Just about get my head round variable scope and ByRef or ByVal (though probably not employ either correctly). I don’t use Functions only Subs (cos’ I don’t know any better). There are a couple of practicle tips in this thread for more strategic/architectural code design. More please.

  17. “Never ever write more than a screen’s worth of code”

    I like it, but I break it all the time. Recently I was populating a class module with data from adodb recordset. I had about 40 lines that looked like

    clsSO.TxnID = rsSO.Fields(“TxnID”).Value

    I couldn’t keep all 40 lines on a screen.

  18. Jon, “How about writing the pseudo code in the IDE?” For me the temptation to switch over to real code is very great, but I’ve managed to restrain myself sometimes. OTOH, writing on paper sounds like something I’d never even start, so for me the IDE and some discipline is the best option.

  19. Jan wrote, “Write pseudo code on paper first and break your problem up into the smallest bits you can think of.”

    Right idea but why use paper and pseudo code? Also, there’s no need to commit prematurely to “smallest bits you can think of”

    I start with totally functional “pseudo code” and flesh out the code as required. For example start with

    type UserDataType
        …
        end type
    sub CalledFromCmdBarButton()
        dim UserData as UserDataType
        initialize UserData
        if AppForm.getdata(UserData) then _
            processData UserData
        cleanup UserData
        end sub

    This way I can not only compile but can also execute the code at any time. Essentially, the actual code also serves as a prototype. In addition, by using the proper data structures and using procedures (subs/functions) that reflect the requirements of the business/scientific application I am addressing, the code is also self-documented. Finally, since each procedure always has a clearly defined interface (I almost never use globals) I can guarantee that a change local to a procedure will require no testing of any other code.

    It also makes it easy to change code that ain’t broke. For example, I might implement a quick and dirty procedure (say a bubble sort).

    sub SortData(byref AllData() as UserDataType)
        ‘…
       end sub

    Then, if there is a need I will replace the code with a more sophisticated approach, say a quicksort. Since the SortData code uses only local variables and the argument(s) passed to it, I don’t have to test any other code.

  20. Dick, true example! but at least I know, you thought through the options first.
    Just cause I make rules, doesn’t mean I don’t break rules. I agree with you all.

    The best code I write (and I admit it isn’t always great) is the stuff I scribbled down on paper on the train on the way home (its 1:30 hrs each way and the old batteries don’t always last). When I go back and read it in the morning it is just lists of subs to fill up with code. Every sub is easy to write they are each so simple.

    Oh and my wife says your name sounds a bit like “Bite the Watering Can” in Russian Kus-Leika.
    And I am not going to mention what I thought I might find at a web site called Dicks-Blog.

    Luckily I took the gamble !

  21. I have to say I’m a paper fan rather than a comments/code in the ide fan. Whilst going straight to the IDE may seem like an efficiency, typing/writing is not the time critical part of what I do.I’d say I spend more time thinking/reseaching/planning/designing. Doing any of those faster/better would have a bigger effect for me, and a big piece of paper is the best I’ve found for me so far.

    Dick – why not use callbyname? (xl 2k + I think?)
    AS well as saving code it makes your code less brittle

    for each f in rs.fields
       callbyname theObjectofYourClass, f.name, vblet, f.value
    next f

    Personally though I’d be tempted to put a recordset in the class so its clients could use all that ado good stuff. In fact I’d probably use a variant array.

    Totally agree on business application based naming and clear interfaces, I’d much rather this than comments.
    cheers
    Simon

  22. Simon that’s genius!

    There you go,we can go back to a page a sub.
    Can anyone else come up with an example (other than the constants declaration)?

Leave a Reply

Your email address will not be published. Required fields are marked *