8 ms·
Signs that you're a bad programmer
- blasdel 17y agoThis is absolutely amazing and comprehensive! I can't think of anything he really left out. I've seen articles like this before, but they're usually super-parochial, and I've never seen one that offered 'remedies' (much less the hilarious 'alternative careers' in the last section).
- russell 17y agoSeems to be a good source for creating interview questions.
- jcapote 17y agoThis is spot on: 5. Lisp is opaque to you
- absolut_todd 17y agoIts not opaque to me, i just haven't invested the effort to bother learning it yet.
- deleted 17y ago[deleted]
- rjurney 17y agoI can't learn LISP. I can get reasonable work done in imperative functional/OO languages like Perl, C, Java, etc. and took the time to learn Erlang to get a look at functional programming and I can drop the SQL bomb like nothing else (so I can do declarative too) but every time I've sat down to learn LISP because people say it will make me a better programmer, I've gotten distracted and haven't finished. I don't think this makes me stupid, or a bad programmer. I think it means I have different tastes and limited time. Learning LISP feels like learning assembly: a great exercise, but there are other things I'm more interested in doing - like building things I enjoy with my limited free time. That being said, maybe I am stupid, or a bad programmer. I don't think not being into LISP means this is the case. I like building things people use, more than I like writing elegant code for code's sake.
- derefr 17y agoI don't think Lisp being opaque has anything to do with your ability to learn a particular PL such as Common Lisp, Scheme, Arc or Clojure. Rather, opacity is usually a term levied at a syntax, when it makes it hard to understand what the underlying semantics of the program are. Lisp has the least "syntax" of any programming language I know of, so if it's opaque to you (e.g., you can't take a guess at what "(+ 2 3)" means), you probably shouldn't be programming.
- rjurney 17y agoI see. Its not literally opaque - I got that far in the book, but I can't follow a real program's execution.
- copenja 17y agoI don't understand the following point you made: "so if it's opaque to you...,you probably shouldn't be programming" So your saying that someone should not program if they haven't learned basic lisp ( 5 )? Or are you suggesting that there should be some time limit... like if you program for X months but don't understand it you are forced to quit. But.. further... What is the purpose of forcing these people to quit? And.. What is the purpose of belittling these people?
- derefr 17y agoI'm not talking about learning programming. The reference in the article was to people that already were programmers. To put it another way: if you call yourself a programmer, and sell your skills as a programmer, but can't mentally decompose "(+ 2 3)" into an AST (basically the first, and easiest, step to understanding), even after Lisp's general syntax is explained to you, then you aren't actually a programmer.
- copenja 17y agoAbove, you said whether they could guess it, not whether they could understand it after explained. "you can't take a guess at what "(+ 2 3)" means" I can see your meaning if it was explained to someone and they still didn't grok it. But I would still kinda feel like encouraging them.
- deleted 17y ago[deleted]
- cturner 17y agoI'm skeptical of these lists because people can work through things. For example, the stuff listed under "Inability to determine the order of program execution" is something that many people will get jammed on eary on as they try to take their brains (which is honed on the syntax of school level maths) into the programing world (where equals is an instruction rather than an assumptions). Another one is "Lisp is opaque to you". It's very sweet for MIT types to make these declarations from mount olympus, but lisp is something that can take time to acquire. If someone isn't a natural programmer but is happy to work at it to overcome hurdles then there's nothing wrong with that. One of the examples of bad technique is: Homebrew "Business Rule Engines" Can anyone give examples of the sorts of things the author means by this? What sort of systems have people seen, and why is it necessarily a bad thing?
- benatkin 17y agoWell, his alternative careers for those who with an inability to determine the order of program execution are pretty good. I wouldn't mind being a civil engineer.
- ardit33 17y ago"It's very sweet for MIT types to make these declarations from mount olympus, but lisp is something that can take time to acquire." Don't worry. In the Valley, people from MIT don't have a good reputation as great programmers. For some reason, their education is a lot of 'theory' and less practice. Apart from Standford\Caltech, Some of the best schools that produce great programmers are your average state school. I have a theory behind this, which may be correct. Learning to be a great programmer takes years, and school is just the start. People that do well enough go to something like MIT, think they are already very smart, and don't try hard when they come out. But if you are hungry, and smart, and just happen to go to your average state school, you probably will do better, as you probably are humbler to begin with. It seems when the rubber meets the street, in startups, building products, that's where the great programmers are made, and lisp is not a requirement to know to be a great programmer, or actually build great products. Having an idea of what functional languages are is a must, knowing them is not.
- 17y ago
- elai 17y agoHe's missing the third part, signs your a decent programmer, to differentiate the good from the great.
- blasdel 17y agoThat's ridiculously difficult to do at all, much less in pithy universal checklist form.
- sophacles 17y agoFor starters howabout: 1. you read the bad list and thought "oh crap!" 2. the oh crap is no longer a problem for you, but remembering the code with that problem makes you wince.
- elai 17y agoI know it's fairly difficult, but we can think of a few. You can have a derivative of the 'good' programmer, the hotshot cowboy who productively makes many products quickly that run well, but the code is "unnecessarily clever", disorganized and difficult to change.
- wglb 17y agoThis is a very good article, and hits lots of very good points. However, it seems that there is a little bit of a self-diagnosis problem. For example, if you write "voodo code" (great description), unless there is some one to tell you, how do you know? And if you write voodo code, do you know what idempotent means? There is maybe a bit of the "Blub" effect here. Perhaps between "Symptoms" and "Remedies" there needs to be "Diagnosis" or some hints at self-evaluation or tools for self-assessment.
- rw 17y agoPageview limit exceeded We are sorry, but this site has exceeded its page view limit at this time. Please try again later. For more information, see Google Sites help.
- mshafrir 17y agoDoes anyone have a mirror for this page?
- bugmenot 17y agoMirror: http://74.125.155.132/search?q=cache:http%3A%2F%2Fsites.google.com%2Fsite%2Fyacoset%2FHome%2Fsigns-that-you-re-a-bad-programmer http://74.125.155.132/search?q=cache:http%3A%2F%2Fsites.goog... (Funny, ain't it?)
- wizardofoz 17y agoI'm getting the same message, could someone post a mirror? Or if any one still has the page open, please save it and post it elsewhere.
- spolsky 17y agoOh! I thought that was the joke. The sign that you're a bad programmer is that you implement a page rate limit on one of your properties (google sites), only to serve up the exact same page out of another one of your properties (google cache) thus accomplishing exactly nothing
- nbroyal 17y agoGoogle cache for those who hit the "pageview limit exceeded" nonsense: http://www.google.com/url?sa=t&source=web&ct=clnk&cd=1&url=http%3A%2F%2F74.125.155.132%2Fsearch%3Fq%3Dcache%3AA7_WaV28LBcJ%3Asites.google.com%2Fsite%2Fyacoset%2FHome%2Fsigns-that-you-re-a-bad-programmer%2Bhttp%3A%2F%2Fsites.google.com%2Fsite%2Fyacoset%2FHome%2Fsigns-that-you-re-a-bad-programmer%26cd%3D1%26hl%3Den%26ct%3Dclnk%26gl%3Dus&ei=G6p7Spq1CovYsgPg8KXvCg&rct=j&q=http%3A%2F%2Fsites.google.com%2Fsite%2Fyacoset%2FHome%2Fsigns-that-you-re-a-bad-programmer&usg=AFQjCNHJJZpSR-zgzZoC-dz6oeOChaPpqA http://www.google.com/url?sa=t&source=web&ct=clnk...
- mojaam 17y agoNever thought I'll see that on a google service. Thanks for the cache.
- Jebdm 17y agoIt's fairly ironic--Google is restricting the page views (to limit bandwidth usage), but at that same time they're hosting a copy in cache of that same page, with no limits.
- CamperBob 17y agoNo kidding. That's so moronically un-Google, it's got to be a bug rather than a genuine quota issue. Because otherwise, Google 2009 == GeoCities 1999, and that would be unthinkable.
- gojomo 17y agoI find "Google 2009 == GeoCities 1999" very thinkable, especially if tweaked a little to "Google Sites 2009 == GeoCities 1999". Empires rise and fall fast on the net. Google is now a mish-mash of offerings which get uneven attention from their internal talent. 'Sites' itself is a successor to the soon-to-be-shuttered Google Page Creator (which unlike Sites allowed custom CSS and JS). A few key people leave, a couple bad quarters -- 'Sites' could get the axe too.
- 17y ago
- ivank 17y agoIt's down, but it sounds like a copy of http://badprogrammer.infogami.com/ http://badprogrammer.infogami.com/
- clawrencewenham 17y agoJust moved it to another host. Not like Google was any better >:|
- ivank 17y agoIndeed, I just realized you're the author of both pages. Thanks for bringing a fine article to attention again.
- sjf 17y agoI noticed when one of your articles was posted to reddit that there was no signature on it, it's nice to know who is behind them. Do you think you will ever publish these in book form? Your tips are blindingly accurate, it could definitely be a Code Complete III, updated to include functional and declarative programming.
- sophacles 17y agoOh man, I wish I had this at my last job half the team had over 50% of these symptoms, one guy had 90%. They believed, and had somehow convinced management, that they were great programmers! Some awesome practical examples from those guys below: Overheard statement "You know when I was in college I learned C. I just can't get the hang of these objects, so I try to avoid them". The guy who said this is now 34, and has programmed python for 4 years. A guy who would copy and paste 100 line blocks of code, and then occasionally thing "oh yeah, i need functions", and then finish out the current function by passing 12 parameters of state to current_function_2(). If you combined the func, func_2 and factored out the 100 line blocks it would be reverted with a commit: "stop making this so complicated". There was one guy who insisted that using templates was only for web frameworks, to use them to write system/config files (done frequently due to 3rd party daemon limitations) was an abuse of the templating system, and we should just use inline prints. The program was to be called with prog > /etc/conffile. One guy who decided that threads were so tricky, that he was the arbiter of thier use. My idea of a job queue and worker threads was "too abstract and hard to debug", so we stuck with the "tried and true" one thread per job method, all spawned at once. I could go on, but you're all prolly bored now :) tl;dr: i worked with the guys the article was written about
- jacquesm 17y agoouch... I love the 'stop making this so complicated bit'. While some people really don't get it I'm pretty sure that most people could learn how to program with some competence. The only metric I've found to measure programmer competence reliably is how big a project you can manage to complete. Some people get stuck at around 100 lines, others in the thousands or tens of thousands, some can keep their rudder straight across 100's of thousands of lines. The latter takes extreme self discipline and organization.
- blasdel 17y agoLOC is a horrible metric for this, given the degree to which morons can get comfortable with copy-paste and IDE-generated boilerplate. Gzip-bytes of source FTW.
- deleted 17y ago[deleted]
- mfukar 17y agoJust reading that made me a bad programmer. :/
- gojomo 17y agoSigns that you're a bad web host: "pageview limit exceeded" If Google can't figure out a way to monetize popular content targeted at a professional technical audience, something's very wrong. The best idea I've seen for such situations is to let people trying to view the page buy an instant traffic upgrade on the site's behalf; I'd chip in 100x the costs to serve my single hit if I knew it would restore visibility for me and some others. The help link is also uncharacteristically inept for Google -- it doesn't lead to an explanation of pageview limits, and searching [pageview limit exceeded] in the help area turns up only user questions, no official article on the topic. The third hit is this unanswered gem, from a popular site with AdSense that keeps going down due to the limits: http://www.google.com/support/forum/p/sites/thread?tid=08f19dca3ab69764&hl=en http://www.google.com/support/forum/p/sites/thread?tid=08f19...
- tjmc 17y agoI love the insight that lacking critical thinking "originates in both lazy thinking and egocentric thinking". The latter is very true. I have never met a great programmer who thinks they are at the top of their game. Being aware of the trade offs in any solution requires a degree of humility.
- 321abc 17y agoThe author lists the following as a symptom of being "unable to reason about code": "5. 'Bulldozer code' that gives the appearance of refactoring by breaking out chunks into subroutines, but that are impossible to reuse in another context (very high cohesion)" I disagree with this. The purpose of breaking out code in to subroutines isn't only for code reuse. If you don't break out code in to subroutines, at some point your code is going to become unwieldy and difficult to read. I try to stick to the rule of having each subroutine consist of no more than a page of code (so that each subroutine can be seen all at one time, without needing to scroll). Often that leads me to break up the subroutine in to many other subroutines. This improves readability greatly and makes it much easier to reason about the code. If any of the subroutines I break my code out in to happen to be reusable, that's just icing on the cake, not a necessity.
- angusgr 17y agoI thought this as well when I was reading it. I think what the article is suggesting, though, is not just that the subroutines would be "reusable" as in useful if called from another part of the program. He's suggesting that the contents of each subroutine should be decoupled from each other - so not sharing global state, depending on strange changes made in other seemingly unrelated methods, etc. The property of "I could reuse this routine if I needed to" implies low cohesion and therefore (probably) more maintainable code. Steve Yegge argued something related to this topic that I don't think I like much, and I don't think you'd agree with it either. He claimed that junior programmers tend to write shorter methods because they're not used to fitting large chunks of complex code in their heads: http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.html http://steve-yegge.blogspot.com/2008/02/portrait-of-n00b.htm... As someone who has seen 2000-line long C++ methods written by "senior developers", I still think short clearly named methods are better. :)
- jonke 17y agoI have seen Fortran programs that don't have any subroutine at all //senior guru model. Even if you could reason about that large amount (40K LOC) I don't enjoy when you die and I get the responsibility to fix "the bug". I do agree that you should not (depending on language) write sub of everything. ex int add(int a, int b) {return a+b;} //Junior model
- jonke 17y ago"Phase 5: "By letting a constraint solver figure out the mundane details, I can write programs by describing what I want, rather than how to give it to me"" This is one of the best arguments for why anyone should bother to learn Haskell (or likewise language)
- sriramk 17y agoHere's a flaw which I've seen in several otherwise good programmers - forgetting that sometimes the core purpose of code is to be read and maintained by other human beings. Some of those other human beings may not have had the time to catch up on the latest/greatest language feature or 'trick' and may miss subtleties of your implementation. I get worried when I see someone take a mainstream language (C#, Java, Python) and try and twist its idioms into whatever their favorite language is (lisp, the ML family, Perl, etc). Or if someone wants to be on the bleeding edge and use the latest language syntax/library trick. This is a pain because - Someone new to the codebase may not have as much familiarity with all these nuances of the language. For example, I've seen crazy things done with C++ templates. I don't think there was ever a justifiable reason for doing any of them. - The esoteric, cutting edge features often have bugs and/or don't have great tool support. Fact of life is that the more some feature gets used, the more the bugs found and fixed. If you're on the bleeding edge, you're going to hit weird language/runtime bugs which you need not have inflicted on everyone. - Debugging. Often, the only thing you have after a weird bug is a crash dump and caffeine. You want to give yourself all the chances you can of tracking down that issue. Esoteric language features rarely lead themselves to great crash dump debugging. I'm not suggesting writing C code but the closer the mapping from code you write to x86/64 code, the easier it is for you
- deleted 17y ago[deleted]
- jongraehl 17y agoSometimes use of advanced facilities is a way of elevating your status over the uninitiated. Now that you've shown weakness, I'm really going to pour it on!
- ardit33 17y agoAfter reading it twice, there are many points that are good, but there also some points that are not so clear cut, or plain bad. Maybe I am a bad programmer, but I disagree with some points: # (OOP) Writing lots of "xxxxxManager" classes that contain all of the methods for manipulating the fields of objects that have little or no methods of their own I guess they keyword 'lots' make this ok, but having plain objects (scruct like), passed around in the application, and having some managers is fine. eg. if you have an application that passes around contacts, you can have a ContactsManager, taking care of all the messy bussines (local peristence, remote persitence, deleting, etc., while contacts remain simple objects. ActiveRecord pattern goes the other way, where this logic is placed in the objects. Both are fine. # (Relational) Treating a relational database as an object store and performing all joins and relation enforcement in client code --I guess all those programmers in the "NOSql" movements are idiots. (they are not, some of these people are really smart). Don't take this statement too seriously. # Re-inventing or laboring without basic mechanisms that are built-into the language, such as events-and-handlers or regular expressions --I think regular expressions are evil, obscure, and performance is highly depended on the implementation. Practical example, checking if an email address is valid. While some people go all the way crazy with regular expression, All I do is check that there is an '@', or a '+', at least one '.', and minimum/maximum lengths. You don't regular expressions for that, as no matter how smart you think your expression is, there is a great chance somebody that edits it will fuck it up just by changing a character on it. # Re-inventing classes and functions that are built-into the framework (eg: timers, collections, sorting and searching algorithms) * Done many times. If you are doing mobile, most of platform implementation (at least in J2ME) just suck ass. You can't rely on them. Heck, in my previous company we did even font rendering, thread worker queues, etc. as the scheduler was unreliable, etc. #Recursive subroutines that concatenate/sum to a global variable or a carry-along output variable --For some problems carry-along variable are needed. eg, in a binary search tree, trying to print only the nodes in a certain level. printTreeLevel(tree, 2) -- will print only the nodes at level two print(node, level) if level == 0 print node.data else printTreeLevel(node.left, level - 1) printTreeLevel(node.right, level - 1) # Writing business-logic functions with tragically compromising side-effects, such as updating a user interface or performing file I/O --I guess it depends on the definition of what "business-logic" is. This guy thinks it more as the transactional/model part and not a controller. For some apps, the business logic is the main controller. Plus, "bussines logic" is more of a managerial speak anyways. #Homebrew "Business Rule Engines" -- Maybe I am not old enough, but I had to look it up what a "Business Rule Engine" is. Seems stuff from the Dot Com era/enterprise world. #Code that tries to prevent an exploit from working by searching for the exploit's signature --Haha. That's the whole Antivirus industry. I agree with him, and I don't have antivirus software, but it seems that those companies made millions by breaking this rule.
- dkersten 17y agoSigns that you're a bad programmer: 1) You think you're an amazing programmer.
- scottdw2 17y agoI have to say, I really didn't like the document much. Not because of substance. Some of what he says is true. On style, though, I think the document is trash. Some of what I say is probably even a bit ad hominem. Most of the good programmers I know don't spend time worrying about bad programmers. They just write good code and cleanup bad code when they see it. If someone feels compelled to write up an essay about bad programmers, he probably spends a lot of time dealing with bad programmers. That experience should lead to humility, not arrogance. If you deal with a lot of bad programmers, you might not be as good as you think you are. After all, you work at the same place on the same project as a bunch of bad programmers. They where hired under the same standards as you. To me, the document just seemed like arrogant posturing. An attempt at crafting a "negative identity" (define a group by vilifying the outsider). The best way to "be", and to be recognized as, a good programmer is to write good code. All the other stuff is just horse shit.
- axod 17y ago>> "They where hired under the same standards as you." The problem is though the hiring process for programmers is often completely broken. Measuring good programmers is also broken in many companies, so bad programmers tend to just stay there instead of improving, or being fired. I think being a good programmer isn't too hard if you have the talent, taste, time etc. Being recognized as a good programmer, and rewarded as such is harder.
- timwiseman 17y agoExcellent point. Another to add to the list is that you may easily have been hired under a higher standard as the team lead or "working/programming manager". I have been fortunate to never work with a bad programmer, but I have worked with inexperienced programmers that were learning as they went. I was not hired under the same standard or for the same reason they were.
- wynand 17y agoI agree with your sentiment, and although I generally agree with the parent, I also disagree with the statement that "[t]hey where hired under the same standards as you". Few companies look for programming talent and I've seen this being hand waved away by statements like: "good programmers don't necessarily make good employees". But on the whole, the article also leaves a sour taste in my mouth due to the superiority complex that cuts through it. Good programmers won't effect much change at companies that have broken hiring practices. Rather move somewhere where your skills will be appreciated.
- torpor 17y agoHow to avoid (if you're a C programmer) writing utterly terrible code - always include these WARNINGS in your build step: WARNINGS := -Wall -W -Wunused-parameter -Wmissing-declarations WARNINGS += -Wstrict-prototypes -Wmissing-prototypes -Wsign-compare WARNINGS += -Wconversion -Wshadow -Wcast-align -Wparentheses WARNINGS += -Wsequence-point -Wdeclaration-after-statement -Wundef WARNINGS += -Wpointer-arith -Wnested-externs -Wredundant-decls WARNINGS += -Werror -Wdisabled-optimization -pedantic CFLAGS += $(WARNINGS) Note: -pedantic is pretty good if you really wanna learn how to write code that will work properly. Also: Treating Warnings as Errors is a good thing. You'll learn a lot, and the most important thing will be: handle all warnings. Do not release code until it builds clean.
- sfk 17y agoGood advice, but compilers often issue warnings like "x may be used uninitialized" even when it cannot happen.
- torpor 17y agoErm, wut? Not really. If there is a warning, its there for a reason. Fix that.
- sfk 17y agoAs everyone who has written a C program of sufficient complexity knows, these warnings are not always correct. Google for "spurious warnings uninitialized", e.g: http://kerneltrap.org/node/6591 http://kerneltrap.org/node/6591 An unrelated example where gcc (and icc) emit needless warnings about integer types is this: int x = foo(); unsigned y = (x == 0); Don't get me wrong, I'm in favor of cranking up the warning levels, but there is a reason why not everything is included in -Wall (yes, "uninitialized" is included, I know).
- torpor 17y agoAs a professional C coder for 20+ years, with well over a million lines of code under my belt, I can tell you that anyone that is ignoring warnings because of a buggy compiler is using the wrong compiler and should fix that immediately. I work on SIL-4 rated systems for life-protection applications. Absolutely ZERO TOLERANCE for warnings is a requirement in this job, and every single time it has been addressed, the warning gave us a clue how to fix something. Whether it was the code that needed fixing, or the compiler - either way, the alert is there. Ignore at your own peril.
- brown9-2 17y agoI'd been looking for a name for what the author terms "yo-yo" code. I've often wondered if others have to deal with such head scratchers too.
- polos 17y agoOh, you can put it as simple as: If you think you are good, you are not. If you think you have to improve, chances are you will become better. (Life is baby steps; ask a baby...)
- JMostert 17y agoFunny that he has this under "Signs that you shouldn't be a programmer": "you think the presence of code in a program will affect its runtime behavior, even if it is never invoked". Anyone who has written code in C can probably cite an anecdote where exactly this was the case, be it from a compiler bug or as fallout from a memory corruption bug. Maybe we should add "does not understand the von Neumann architecture" to the list of signs that you're a mediocre programmer... On second thought, let's not -- the piece is bad enough to begin with. The "alternative careers" sections are just odious, and the whole thing breathes an air of inconstructiveness.
- ewjordan 17y agoThis happens in JVM languages as well. Most optimizing compilers will do things differently depending on what happens elsewhere in a function, even if it's "dead code" (and especially if it's dead code that the compiler is too stupid to realize is dead). Granted this usually only affects runtime speed, but in some circumstances things can get worse (multithreaded programs are particularly susceptible to such optimizations, especially if they're not written correctly - yes, the real problem may be that you've written your code wrong, but there are very real situations where the presence of dead code can change the optimization path taken enough so that it either works or doesn't, which is a very real effect). And that's even before we take into account compiler bugs, which just make things worse.
- tholex 17y agoGreat doc to make screeners with.
- NoHandle 17y agoHigh cohesion is bad in exactly which programming environment? Functional or procedural? I've always understood high cohesion to be related to low coupling. Also, writing util classes before you need them (where low cohesion may be necessary) is a nothing more than a time sink. Do something when you need it, not before. You are not omniscient and will not be able to account for everything no matter how hard you try.
- aschobel 17y agoFTA: "Signs that you shouldn't be a programmer 1. Inability to determine the order of program execution Symptoms a = 5 b = 10 a = b print a You look at the code above and aren't sure what number gets printed out at the end" The answer is not always obvious. If the above code were in Java and print a was running in a different thread then it very well print 0, since a or b could be 0. JMM can really bite you if you don't understand within-thread as-if-serial semantics.
- olliesaunders 17y agoThat's a pretty extreme case don't you think? You're certainly playing devil's advocate here. We all know what the author meant by this.
- tuukkah 17y ago1. (Haskell) Propagating the myth that Haskell would do some automagic caching of function results. (Haskell simply does call-by-need: square (x+1) evaluates to (x+1)*(x+1), but there's still only one (x+1) that gets evaluated.)
- olliesaunders 17y agoSome praise for this article: Identifying a set of patterns for sub-quality programming practise is useful in order to set about correcting those things esp. if you're in a mentoring position. I think it would have been nice to have given these names (like design patterns perhaps) and fleshed out their definitions further. Yes, the author is more arrogant than desirable in his delivery but don't let that blind you to the good stuff. Some of the teaching analogies, in particular, I thought were good.
- jongraehl 17y agoThat was mostly high quality except for the wannabe "you might be a redneck" (shouldn't be a programmer) section at the end. > (Functional) Manually caching the results of a deterministic function on ... Haskell You still have to explicitly memoize at times in Haskell. > refactor his old code with the goal of reducing its instruction count by 10:1 or more What a loser! I go into my old code with a goal of 10000:1. > Recursive subroutines that concatenate/sum to a carry-along output variable This can be justified. > Using strings/integers for values that have (or could be given) more appropriate wrapper types in a strongly-typed language Not always worth it. > Unit Testing, which you use at design time. No, I don't. > You don't use whitespace or indentation If I'm not using whitespace, what am I supposed to indent with?