I <3 Steve McConnell*
Coding Horror
programming and human factors
by Jeff Atwood

Jul 8, 2008

Spartan Programming

As I grow older and wisereven older as a programmer, I've found that my personal coding style has trended heavily toward minimalism.

I was pleased, then, to find many of the coding conventions I've settled on over the last 20 years codified in Spartan programming.

300-movie.jpg

No, not that sort of Spartan, although it is historically related. The particular meaning of spartan I'm referring to is this one:

(adj) ascetic, ascetical, austere, spartan (practicing great self-denial) "Be systematically ascetic...do...something for no other reason than that you would rather not do it" - William James; "a desert nomad's austere life"; "a spartan diet"; "a spartan existence"

I've tried to code smaller, even going so far as to write no code at all when I can get away with it. Spartan programming aligns perfectly with these goals. You strive for simultaneous minimization of your code in many dimensions:

  1. Horizontal complexity. The depth of nesting of control structures.
  2. Vertical complexity. The number of lines or length of code.
  3. Token count.
  4. Character count.
  5. Parameters. The number of parameters to a routine or a generic structure.
  6. Variables.
  7. Looping instructions. The number of iterative instructions and their nesting level.
  8. Conditionals. The number of if and multiple branch switch statements.

The discipline of spartan programming means frugal use of variables:

  1. Minimize number of variables. Inline variables which are used only once. Take advantage of foreach loops.
  2. Minimize visibility of variables and other identifiers. Define variables at the smallest possible scope.
  3. Minimize accessibility of variables. Prefer the greater encapsulation of private variables.
  4. Minimize variability of variables. Strive to make variables final in Java and const in C++. Use annotations or restrictions whenever possible.
  5. Minimize lifetime of variables. Prefer ephemeral variables to longer lived ones. Avoid persistent variables such as files.
  6. Minimize names of variables. Short-lived, tightly scoped variables can use concise, terse names.
  7. Minimize use of array variables. Replace them with collections provided by your standard libraries.

It also means frugal use of control structures, with early return whenever possible. This is probably best illustrated with an actual example, starting with raw code and refactoring it using the spartan programming techniques:

I don't agree with all the rules and guidelines presented here, but I was definitely nodding along with the majority of the page. Minimalism isn't always the right choice, but it's rarely the wrong choice. You could certainly do worse than to adopt the discipline of spartan programming on your next programming project.

(hat tip to Yuval Tobias for sending this link my way)

Posted by Jeff Atwood    View blog reactions
« The Problem With Code Folding
iTunes is Anti-Web »
Comments

Character count should be a concern, but not at the expense of readability. Ever.

Kris on July 8, 2008 2:03 AM

I guess this is a little late in the discussion but I recently read (yesterday?) a post that raised some really good points against private variables. Mostly about how it's rude to other programmers and isn't explicit about why they're private.

http://debuggable.com/posts/programming-psychology-ii-private-methods:481ed862-b0d8-4a0e-9247-165c4834cda3

He (Felix Geisendrfer who I like a lot) points out...

If somebody does not understand why he is not supposed to modify the balance property - he will find ways around it. And it won't be pretty, trust me. He'll directly write his values to the database and reload the object. He'll simply change your source code without warning. He'll extend the class and overwrite the set method.

Programmers will do just about anything to restore power you are trying to take away from them.

Now you might think: But it really makes sense to use a private property here, nobody would ever want to work around this?. Well maybe. And thats a big maybe. Predicting what other programmers will want to do with your code is like playing number guessing with uuids.

And follows up with an example that uses a validate function in the save function of the model. He claims it makes it a lot more flexible and provides yet another useful function instead of wasting time with setters and getters that may not have a consitant api between classes.

Francis on July 8, 2008 2:09 AM

Well, not I have to disagree. :-)

If the programmer will insist on screwing up, there's no help for it.

The point of using getters and setters is preventing internal changes in the implementation from having an impact on the client source code.

For instance, suppose you have an object car (which implements the Vehicle interface :), and one of the properties of the car is the acceleration. You expose this directly, and now you have everyone doing things like:

car.acceleration += 10;
print car.acceleration;

And then, one fine day, the TerrestrialVehicle class change it's implementation so that now it stores mass and force, and always calculate acceleration from and to that. Suddenly, that code up there is invalid!

Unless, of course, the language has implicit getters and setters, so that you can change the way acceleration has been implemented without the client code ever realizing it.

Daniel on July 8, 2008 2:23 AM

Nice post

John Pirie on July 8, 2008 2:42 AM

@astine

First of all: as for feeding the balls...

http://bodyspace.bodybuilding.com/ssmoimo/

Ok, now thats out of the way. Yes, that is exactly what I would do. Now of course that program doesn't make sense, but it is much better to take a complicated boolean statement and store it in a variable or a function call. (Depending on which would provide more clarity.) Yes a reasonable programmer can figure it out, but when I am looking at the logic of the method, I don't care how it determines if a message is valid, but only that it is. If I want to look at the logic of is a message, valid I'll look at that method or variable.

Also, take a look at page 434 of Code Complete 2nd edition to see that McConnell advocates that same exact technique. Granted his example is more complicated logic, but that is likely to be the case in a real example.

Also you don't have enough information to know which name is better, neither do I. Doesn't sound like your using in IDE either.

John on July 8, 2008 2:48 AM

It's definitely an art to write more expressive code with less (typing, structures,control loops,etc), but that doesn't mean abbreviating unnecessarily nor prematurely. The only goal is writing short, concise code that does no more than it should. I also don't think the notion of 'spartan' programming (i.e. not somebody's concrete definition) goes against Code Complete either. Readable and maintainable code is paramount.

But then I feel the definition Jeff quoted isn't particularly helpful. Instead: http://www.thefreedictionary.com/Spartan has a bit better definition.
spartan:
2.a Rigorously self-disciplined or self-restrained.
2.b Simple, frugal, or austere

spartan (adj)
2. (of a way of life) strict or simple and with no luxuries

The related word of non-indulgent is also pretty apt.

Think of your house. If you led a spartan existence, you would have 2 pots, 1 plate, 1 bowl and 1 set of cutlery. You don't have more because you don't need more.

Your best idea is to:
- refactor continually
- don't goldplate code
- only add as much as you need, and no more
- use unit tests to provide feedback

Developers love features, but more code = more bugs. Read books on refactoring - it's probably the best thing you can do to make yourself a better nuts bolts programmer.

It's small-a agile .. Red-Green-Refactor.

RedGreen on July 8, 2008 3:12 AM

@Mecki: I'm a big fan of early returns. They avoid that you need to indent 20 times within a function

I hear this a lot, generally because people try to replace code like this:

if (func1() == false)
____return false;
if (func2() == false)
____return false;;
if (func3() == false)
____return false;;

dostuff();
return true;

...with arrow-code that looks something like...

result = false;
if (func1() == true)
____if (func2() == true)
________if (func3() == true)
________{
____________dostuff()
____________result = true;
________}
return result;

..wheras they could just do something like this...

bool statusOk = func1();
statusOK = statusOk func2();
statusOK = statusOk func3();

if ( statusOk )
____dostuff();

return statusOk;

Graham Stewart on July 8, 2008 3:14 AM

Keeping unnecessary things to a minimum is good and all but it can sometimes come at a price.
It can be expensive to make make code leaner and smaller. It can also seriously affect readability. Code should (and can) always be self documentary.

Keep it simple, get the job done. :)

Swedish Code-monkey on July 8, 2008 3:17 AM

How many Jr Developers have been dropped off the mountain?

Come home with your keyboard or on it.

brian on July 8, 2008 3:50 AM

After I read through some of the Spartan rules, I wondered, why? What is the benefit? They say, short programs tend to be more correct. Are they? That's it.

Horizontal complexity: I prefer to always include the braces in and if-then-else even if there is one statement. I'm thinking of maintainability and the next person that has to review and add code.

Token count, character count: I feel like we are writing assembly code on an 8088 processor :-), and we're counting every byte. Those days are gone, aren't they? I'm confused. Is this for performance (i.e., big O notation)? Or is this because the author doesn't want to type. Most good editors have code completion. Is a really a better choice for a variable name than coefficient_X_squared? Well, at least it isn't polish notation ;-)

A good coding standard and consistency can go a long way in the current state of programming. No need to make things more complex, or create rules because you can.

Linux Kernel Coding Standard
http://lxr.linux.no/linux/Documentation/CodingStyle

dj on July 8, 2008 4:21 AM

@john

http://bodyspace.bodybuilding.com/ssmoimo/

LOL, flexing your muscles over the Internet are you? A lot of good it will do you. You've just given me the upper hand, and that's all I'll say about that.

Also, don't quote me this or that professor, I've never read Code Complete, never intend to, and don't acknowledge it as an authority.

I do know enough about that method to tell what it should be called; a method should always be named after it's function. Also, I've used many IDE's from VS to Eclipse/Rational to Emacs. You should never be too reliant on such tools. If you can't parse the code in plaintext, then there is something wrong with the code (or you,) not your tool.

astine on July 8, 2008 5:56 AM

..wheras they could just do something like this...

bool statusOk = func1();
statusOK = statusOk func2();
statusOK = statusOk func3();

if ( statusOk )
____dostuff();

return statusOk;

That's terrible, terrible, terrible code. The entire logic is removed and abstracted away in favor of some bit juggling that nobody is ever going to understand again six months from now. And for what ? The original code was perfectly fine, readable, concise, effective.

J. Stoever on July 8, 2008 5:56 AM

Wow, Jeff, you basically copied that wiki page word for word. Even if you did cite it, this is basically link-jacking and unfair usage. Totally uncool.

James A. on July 8, 2008 6:25 AM

Plagiarism. That's the word I was looking for. Taking credit for the work of another.

James A. on July 8, 2008 6:26 AM

For compiled languages, the length of variable names does not matter. All names are tokenized anyway and you will gain absolutely nothing by using one-letter variables.

Minimalist programming has more to do with avoiding code-bloat than anything else - something Microsoft is heavily opposed to because, for some reason, Features Equal More Bloat.

BugFree on July 8, 2008 6:26 AM

Like several commenters before me, the first thing I noticed in the java example was that they attempted to remove the variable fds by inlining the constructor, but then left a reference to fds in the following line. A small compile-time bug like that doesn't even remotely nullify the overall argument, but it does bring to mind an existing counter-argument, the if it ain't broke, don't fix it methodology that refactoring working code can at best, leave it still working, but at worst, introduce bugs.

Also, the manager of the wiki made a serious webmaster blunder- There's no contact information that I could find anywhere in the wiki. If there were I'd have contacted him/her to point out the fds variable bug, but as it stands we have to mention it in the comments of a page LINKING to it and hope that he finds this post via pingback or a google search for links to the wiki.

Not sure I agree with collections instead of arrays- Arrays are faster, and leaner on memory- I would say to use whatever data structure is given to you, unless converting it yields noticeable speedup. Leave an array as an array, a vector as a vector, etc. Even if your first inclination is to convert it to something you're used to, try and figure out why the collection was given to you in that form in the first place. If you're creating the aggregate yourself, I'd go with arrays unless there's a significant algorithmic advantage to using something else.

Alex on July 8, 2008 6:32 AM

I couldn't resist posting something that I went Spartan on:

http://seanja.com/blog/2008/07/08/spartan-coding/

I did not however sacrifice 'readability' by changing the one vaiable that there is to one letter. I hate that.

I also reduced what the function did to make it simpler... I could not see a point to having the same function update and delete. They are not the same thing! GAH!

SeanJA on July 8, 2008 6:50 AM

first!

gothael on July 8, 2008 7:21 AM

It's good to know I practice most of these techniques anyway. I remember I read in a programming book somewhere (I think by Chris Pine) that you should strive to program as lazily as possible, meaning you should try to do as much stuff by typing as little as possible. Seems pretty similar to Spartan programming to me!

Matt S on July 8, 2008 7:30 AM

This particular process of Simplifying code is, in my opinion, almost completely offtrack. You don't make code simpler by reducing character count anymore than you make a Toyota Prius by putting a Ford Truck in a car crusher and reducing it to the appropriate dimensions. One would hope that obfuscated C contests would have made that clear by now. Code is simple when it does exactly what it looks like it does, and that doesn't come about just by reducing things to some arbitrary minimum sized source file.

Simple code has easy to understand control paths, and well-named symbols (both concise and accurate). Simple code is exactly as complex as it needs to be, and no more. The Spartan philosophy is a sure way to overdo it.

Also @Mecki

There is a procedural form of RAII for C that deals with this. Construct a chain of initializer funtions, that call the next initializer function in the chain if their initialization is successful. Otherwise they return early. The last in the chain is the function for real work. This is best used when things are particularly complex in the final function. A real example would return a value or modify some state, but you get the idea.

void func()
{
int *foo = init_foo();
if(!foo)
{
return;
}
func_foo(foo);
cleanup_foo(foo);
}

void func_foo(int* foo)
{
float *bar = init_bar();
if(!bar)
{
return;
}
func_foo_bar(foo, bar);
cleanup_bar(bar);
}

void func_foo_bar(int* foo, float* bar)
{
//do something
return; //anytime you like, returning from this
//will trigger all cleanup.
//do more things
}

Clark on July 8, 2008 7:30 AM

It's noise reduction, especially what you are talking about in regards to declaring minimal scope (encapsulation).
If more things can be read-only and less variables are available globally this cuts down the amount of background noise and keeps things clearer, simpler and makes it easier to see what is going on and what code might be causing a bug.

Makes me wonder how people make some of the best sites in the world in PHP as that language doesn't appear to lend itself to this style of coding.

Jax on July 8, 2008 7:31 AM

Good stuff. Definately agree with most of the ideas here... although mindless swapping of ifs and switches can be questionable... and I am loathe to encapsulate variables when leaving them public will suffice (less code, less function calls... the only disadvantages are that you can't upgrade the class to do other stuff on get or set in later releases and that you break OO... if thats even a bad thing)

Still, the C example is not much different between the two (i.e approximately the same amount of coder effort to produce the code). Other than the switch statement, the compiler is likely to produce very similar results...

The Java example is much more drastic and proves the point very well I think. :)

In a similar vein, one of my favorite time savers/code shorteners is to provide a #define or typedef for unsigned long/unsigned int. typing unsigned all those times gives me a headache. C# gets it right with the label of uint. :)

Jheriko on July 8, 2008 7:33 AM

Makes me wonder how people make some of the best sites in the world in PHP as that language doesn't appear to lend itself to this style of coding.

Jax: poor workmen blame their tools. the opposite is also true, a master craftsmen will take the worst raw materials and the worst tools, and still will create a masterpiece.

Jheriko on July 8, 2008 7:34 AM

although mindless swapping of ifs and switches can be questionable

Likewise with reflexively replacing for loops with foreach loops. I'm not 100% sure about Java, but with C# there can be performance costs associated with such a change.

protected static on July 8, 2008 7:43 AM

poor workmen blame their tools. the opposite is also true, a master craftsmen will take the worst raw materials and the worst tools, and still will create a masterpiece.

However, most master craftsmen, given the option, would not use inferior tools. Walk into the woodshop of any even remotely accomplished wood worker, and you probably won't find a lot of low quality tools.

Kibbee on July 8, 2008 7:49 AM

I think there are more important things to keep you up at night than the overhead costs of foreach.

mrcl on July 8, 2008 7:50 AM

Likewise with reflexively replacing for loops with foreach loops. I'm not 100% sure about Java, but with C# there can be performance costs associated with such a change.

Of course in Python the for loop IS a foreach loop and nobody cares about performance since it's already interpreted.

Michael on July 8, 2008 7:56 AM

@Jax

Makes me wonder how people make some of the best sites in the world in PHP as that language doesn't appear to lend itself to this style of coding.

Care to elaborate on why PHP is not a good candidate for this kind of programming? Spartan style programming seems to be on the programmer shoulders, not on the language. PHP can do 100% of what was shown in both of the examples...for each loops, switch statments, use of local and global keywords to minimize variable scope...

I get the impression you bash PHP because jeff seems to blindly write negative posts about the language.

mmattax on July 8, 2008 7:57 AM

Less code typically means it's faster, more secure, and easier to maintain.

With, of course, the largest exception being the use of most of microsoft's standard controls.

Chris Lively on July 8, 2008 7:57 AM

I agree with the use of concise, terse names. However I don't like shortening everything to single characters as in the example, i.e. Message as m and Subject as s:

Message m = new MimeMessage(s);
m.setSentDate(new Date());
m.setFrom(new InternetAddress(from));

Call me pedantic, but Steve McConnell taught us to only do that in tight loops. Those lucky C# developers can use object initializes:

Message msg = new MimeMessage(s){
SentDate = new Date(),
From = new InternetAddress(from)};

...which also assists in keeping constructor overloads to a minimum.

Casper Bang on July 8, 2008 7:58 AM

You rarely see these kind of guidelines for functional languages since they are inherently enforced by such things as single assignment, no global variables etc.

Adam on July 8, 2008 8:00 AM

Lots of comments have been posted already, but I feel compelled to chime in with my disagreement, primarily with that particular wiki page's definition of spartan programming. Like many commenters, I too believe in creating the minimal solution to every problem. Also like many of the commenters, I might even agree with a smattering of the recommendations aimed at doing so, but I absolutely disagree with the wiki author's priorities in terms of what to minimize and how to do so. By way of a few examples:

The wiki's micro abstractions aren't abstractions of any kind. They are primarily syntactical options, many of which fall into the clever category, some of which are clever enough to have been banned in more than one coding standard I have found myself working with over the years.

The terseness of identifiers may minimize characters typed by the code's initial author, but also minimize readability and maintainability for those faced with the code in the future. The wiki strikes me as written by someone who has never had to maintain code in even the medium term, let alone the long term.

The reduction of whitespace and braces does, well, minimize whitespace, but does so at the cost of increasing visual density which for the majority of developers results in decreased readability and in turn maintainability.

The wiki's deadly fear of line count drives an unwillingness to do things like perform Extract Method and Introduce Explaining Variable. These simple refactorings can, like any other, be overdone but in general are a great way to increase readability and maintainability.

I could provide more examples, but I think the case has been made well enough above and by other commenters.

I've worked with a few developers who absolutely loved producing the kind of code encouraged by the linked wiki, but those developers also had a tendency for producing out-of-spec implementations that were high in defects and low in maintainbility. I know, I know, things like visual density of code (which is in many ways the primary symptom of applying the wiki's problematic recommendations) should in theory run orthogonal to defect rate and maintainability, but in practice the correlations are too great to ignore.

In my experience:

Dense, terse code = more defects, each with greater time-to-fix.

Minimal, while still visually open and explanatory, code = less defects, each with lower time-to-fix.

As for net new code, it is worth remembering that new code becomes maintained code character by character, and does so just as soon as you lifted the key.

Jeremy Gray on July 8, 2008 8:02 AM

As well said by Antoine de Saint-Exupry

Perfection is not when there's nothing to add, but when there's nothing to take away.

lars hundertwasser on July 8, 2008 8:03 AM

You rarely see these kind of guidelines for functional languages

True, then again, you rarely see functional languages solving real world problems. ;)

Casper Bang on July 8, 2008 8:04 AM

I too have found my coding style naturally trending in a spartan direction over the years. I've found this style makes it easier for me to catch bugs (before they get checked in) and makes it easier for me or anyone else to maintain the code down the road.

Dave C. on July 8, 2008 8:07 AM

Serious question: Why are people allergic to whitespace? That Java example has the code compressed into a huge block, line following line without pause, even after the spartanization.

I personally don't like the brace-at-end-of-line style of scope operators since I find it much harder to read with all the lines of a control block crammed together, indenting notwithstanding.

However even sections of code that are logically grouped together could stand from having some nice, free, paragraph separating whitespace to improve legibility.

People complain on forums and blogs when someone expresses their ideas as large blocks of text, unrelieved by the occasional empty newline. Why is this so often not the case for code?

It seems to me that if you write code in paragraphs, you can use these as a good indicator of where you can refactor into a method, as the paragraph gets longer.

Wouldn't that be an even better way to add this spartan feeling to code? If one added whitespace in the Java example, you could see there are at least three paragraps: one that sets up the message basics, one that adds the attachments, and one that sends the message.

One could make this code even cleaner and more spartan by makingaddAttachments() and smtpDeliver() methods.

Dan Fleet on July 8, 2008 8:10 AM

terser programs are easier to understand (from the Spartan programming page).

While the goal (readability) is good, I doubt if these rules help reaching that goal. For example, while veryLongVariableNamesThatGoOnAndOn are clearly cluttering,

c.setSN(f.getSN());

is not as easy to understand as

child.setSurname(father.getSurname());

you can might even infer the type of the variables from the latter statement.

I can find similar issues with several of the other guidelines. I think simply stopping to read what you've done after you've completed a unit of code to check if it's readable will be more useful than following these rules.

Jeroen on July 8, 2008 8:11 AM

@mmattax:

PHP isn't condusive to this kind of thing because PHP doesn't have a local variable scope.

The 4 scopes in PHP are
1. Superglobal scope (always visible)
1. Global scope (variables you need the global keyword to see, or can be accessed through the superglobal $GLOBALS array (well... hash))
2. Object global scope - your standard public, private, etc... variables
3. Function global scope - Variables occurring anywhere within a function can be seen anywhere else in that function.

What does lack of a local scope mean? Here's an example

function AFunction() {
for (i = 0; i 10; ++i) {
echo i, \n;
}
echo i; // Prints 10
}

The same code in a strongly typed language (C# in this example):

public void AFunction() {
int i;
// Some other code

for (i = 0; i 10; ++i) {
Console.WriteLine(i);
}
Console.Write(i); // Prints 10
}

This can lead to some nastiness if you're not expecting it, particularly if you expect variables to get reinitialized for each iteration in a loop.

It also means that variables (including objects) do not go out of scope, and thus are not garbage collected until a function ends.

Powerlord on July 8, 2008 8:11 AM

I have to agree with the previous post. Jeff, you tell us that Code Complete is your favourite book, but this post is an obvious opposite of what is said in Code Complete. It is writeen through all the book that first of all the code should be READABLE, because it's simply easier for yourself in the first place. And short variables don't do any good to achieve this goal. Hell, we have got all this IDEs with code completeion and all, why do we have to use so small names?

There are two ways to explain what the variable does: either leave a comment, or choose a suitable name. Of course it's better to use both, but since the varibale should be given some name anyway, why not choose a good one?

At least one-letter names are very annoying when you have to maintain code written by someone else. I don't read other's C code very often (I code in Java), but when I do, I hate using lots of one-letter variables. Even if all of them are commented (I would have hung myself if they weren't), I still get confused when I try to find out how the code actually works simply because I forget what makes s different from g and what is stored in r. The only thing I can do is to read comments over and over again.

Of course, I make use of short variables, but just in the cases when it is obvious what they store, for example, in the loops. That's it.

P.S. By the way, Code Complete advises not use such variables even in the loops. So Jeff... Maybe it's time to look through Code Complete again?

Malcolm on July 8, 2008 8:17 AM

I have also found myself in a loop of becoming more minimal, pretty steadily over the last several years.

I just wrote a similarish but more generalized post on this: http://codetoast.com/blog/im-bored-of-all-this-smorgas

Simple code tends to stay maintained and working a lot longer. Working and simple code is way better than unworking code that in theory could save the world and do my dishes and demonstrate the coolest new pattern of cleverness, umm if only it worked.

knick on July 8, 2008 8:19 AM

Sorry, many people has posted before me, I meant the post by Casper Bang.

Malcolm on July 8, 2008 8:19 AM

Jheriko: I am loathe to encapsulate variables when leaving them public will suffice (less code, less function calls... the only disadvantages are that you can't upgrade the class to do other stuff on get or set in later releases and that you break OO... if thats even a bad thing)

Leaving variables public has a lot more disadvantages than you think, as most good developers figure out quickly. They can easily be altered in places you don't expect because of scoping issues - which aVar is visible here? It also means they can accidentally be changed by others working with your code when they didn't intend to do so.

Finally, public or global variables are just wasteful. They consume memory when not needed, whereas variables with restricted scope (local variables) only take temporary space on the stack during the time they're in scope; once they're no longer in scope, the compiler can reuse that memory space. The same isn't true of global variables; the memory they occupy is used for that purpose even when the variable isn't being used.

Global variables went out of favor a long time ago with people who know what they're doing.

KenW on July 8, 2008 8:25 AM

The interesting thing is that I can't bring myself to maintain continued use of frameworks or open source code that has non-intuitive, up-front syntax. If I have a cake, while I would like to comply with standard baking and slicing conventions, I want to eat() it too.

I agree with the previous posts as well, though not quite to that level of criticism(sorry, guys). When I'm trying to read through aging code (particularly c or c++), I would much rather see a more descriptive coding practice that follows user-friendly ER modeling in variable and function names. It's a grey area, I suppose, but one that defines the difference between a poor programmer and a seasoned professional.

The number one reasons to find the balance between Spartan and Grecian (for lack of a better historical comparison) code is....legacy systems.

Raymond Berg on July 8, 2008 8:30 AM

You can take this much further by eliminating frugal variables all-together and simply compose functions ala Joy and other concatenative languages. I'm reading Thinking Forth at the moment and loving it, not as much as I loved the JonesForth Assembler Tutorial which are just as enlightening as the Joy essays. Go forth if you dare, and learn true minimalism.

Craig Overend on July 8, 2008 8:30 AM

Global variables went out of favor a long time ago with people who know what they're doing.

True Ken, but there's still overhead with passing context around this way and things gets much more tricky when we want to pass context back again to the previous stack frame. Some languages use tuple's for this, but neither C# nor Java operates with this concept.

Casper Bang on July 8, 2008 8:34 AM

first!
Can we ban people who engage in this sort of Internet garbage spewing?

Spartan code is substantially easier for someone else to come in and understand/debug. The less code that is in your system, the less that can break when push comes to shove. (Less code does not mean shorter variable names or method names. Name length on those identifiers is too specific to reduce to a one-size-fits-all rule.)

I didn't see much of a mention on modules that attain god-like status in systems. They are probably the biggest offenders when it comes to proper coding style and make it much harder to work on because so many details are exposed to you at once.

Matt Green on July 8, 2008 8:36 AM

Ha ha. All my projects start out spartan...

Dan on July 8, 2008 8:43 AM

I agree with most of that I think. I don't like terse variable names they make the code harder to read. message is much better than m, emailMessage is much better than message. I don't mind i,j for tight for loops though but I'd prefer row and col (assuming that was appropriate. The more you can do to make your code read like English the better in my view.
I do agree with all the encapsulation points though and I'm a fan of as little code as possible, some of my most productive days are when I reduce the code base by 10%.
The only bug free code is no code.

David Hayes on July 8, 2008 8:46 AM

At Malcolm :
It is writeen through all the book that first of all the code should be READABLE, because it's simply easier for yourself in the first place. And short variables don't do any good to achieve this goal.

short variable name does not mean unreadable code or one char variables.
Looping on row, col is as readable as using tableRowIndex and tableColIndex.

tmp is as readable as tempVar

Of course sometime you will want to be able to know that modelRowIndex is different from viewRowIndex, but if there is no confusion, using row, col, or even i,j is very readable.


bandini on July 8, 2008 8:47 AM

However I don't like shortening everything to single
characters as in the example, i.e. Message as m and
Subject as s

I agree. Bad, bad, bad form.

I would also add the bafflingly controversial rule to reduce the number of returns to ONE to the list. I go mental when I see stuff like the good example given under horizontal complexity:

if ...
return
return

Rhywun on July 8, 2008 8:49 AM

True, then again, you rarely see functional languages solving real world problems. ;)

Not because they can't, but because still relatively few people use these languages. Lack of libraries is no longer a problem. You now have functional idioms for C#, you also have F# for .NET, and Scala which runs in the JVM and is interoperable with anything done in Java.
For anyone who sees the benefit of constructs like 'foreach' and minimization of variable usage, functional programming is clearly a step forward, and it's ready to be taken.

German on July 8, 2008 8:49 AM

I think excessively minimized code often falls for the
six-month rule: You must still be able understand your own code
after having left it alone for half a year

Jens on July 8, 2008 8:56 AM

I'm not a fan of early returns, personally, it's too much of a GOTO solution. I also try to avoid break statements for the same reason.

tk. on July 8, 2008 8:58 AM

The terse rule is a double edged sword, IMO. As someone else mentioned - you need to be able to understand the code later.

If you don't use descriptive variable names, you need to have their meaning clearly defined either by context or by comments.

Lars Fosdal on July 8, 2008 9:01 AM

Of course, if we follow this argument to its logical conclusion, why are we programming in Java in the first place? Stop me if you've heard this one...

http://www.paulgraham.com/power.html
(h t t p colon slash slash www dot paulgraham dot com slash power dot html)

Dan Lewis on July 8, 2008 9:01 AM

Sorry for the funny looking link, I have a hard time remembering what gets past the comment filter because there's no Preview button (and I comment on more than one blog).

Dan Lewis on July 8, 2008 9:03 AM

Go spartans!
I've been a spartan programmer for the last 3 years. Its sometimes painful, and sometimes it means investing more ahead of time, but you definitely thank yourself a few months down the road when you need to update/fix something.

Jay on July 8, 2008 9:17 AM

Of course, if we follow this argument to its logical conclusion,
why are we programming in Java in the first place?

Mostly because it pays. Hopefully the industry will get over Java and the like eventually... (we can all contribute to that by learning new stuff)

German on July 8, 2008 9:19 AM

isn't spartan programming a fanciful expression to label dry programming?

heri on July 8, 2008 9:22 AM

1. The Java example is buggy. They removed the fds variable, which was only used once, and forgot the SECOND use. So, the following line, in the final form of the example, won't work:

part.setFileName(fds.getName());

2. Replace arrays with collections? Well... I like lists and all (of which Collections are variants), but an array is MUCH faster. Both for memory management and access. I use them as long as speed is not important, but they are usually my first choice of optimization. And often last.

Daniel on July 8, 2008 9:26 AM

One place to avoid long variable names not only for asthetic reasons is control names in asp.net because they are actually written on the page that needs to be transfered. Now if you happen to use the container controls of the ASP.Net AJAX control toolkit, the name(s) of the container(s) is/are concatenated to every child control.
In addition the viewstate is also blown up (apparently the encoding of the viewstate does not imply compression).

If for example you have a checkboxlist within an asp.net ajax tab panel, you may get something like this on your page for a list with two items (imagine 100 items...):

tr
tdinput id=TabContainerLongOuterContainerName_TabPanelReallyLongInnerContainerName_CheckBoxListReallyReallyLongCheckBoxListName_0 type=checkbox name=TabContainerLongOuterContainerName$TabPanelReallyLongInnerContainerName$CheckBoxListReallyReallyLongCheckBoxListName$0 /label for=TabContainerLongOuterContainerName_TabPanelReallyLongInnerContainerName_CheckBoxListReallyReallyLongCheckBoxListName_00/label/td
/trtr
tdinput id=TabContainerLongOuterContainerName_TabPanelReallyLongInnerContainerName_CheckBoxListReallyReallyLongCheckBoxListName_1 type=checkbox name=TabContainerLongOuterContainerName$TabPanelReallyLongInnerContainerName$CheckBoxListReallyReallyLongCheckBoxListName$1 /label for=TabContainerLongOuterContainerName_TabPanelReallyLongInnerContainerName_CheckBoxListReallyReallyLongCheckBoxListName_11/label/td
/tr

Manu on July 8, 2008 9:27 AM

I definitely don't agree with some of those ideas.

To me, a variable name can never be too long. In my opinion, a variable name absolutely has to be descriptive, so that other programmers can more easily see what is going on. If a variable must be named horizontalScalingFactorBeforeZoom, then so be it.

The other thing that should be pointed out is that sticking to those maxims will result in slower code (a lot of the time). I especially noticed this one: Minimizing the use of arrays, and replacing these by collections provided by standard and of-the-shelf libraries. Obviously, that will result in more overhead in many situations.

Still, it's a very interesting concept.

Evan on July 8, 2008 9:29 AM

The ability to view a complex problem as a series of simple problems and to code accordingly is one of the most important abilities when writing clean, maintainable code.

Hutch on July 8, 2008 9:31 AM

how does spartan programming apply to peer programming? if my partner breaks the build, should i put my keyboard through his chest?

Darren Kopp on July 8, 2008 9:31 AM

Great care must be taken in these approaches. Less is not always better. Sometimes it might require more lines of code for that piece to run in it's most efficient mannor...

I suggest you run some performance tests on some of your code that you minimized before you call it good.

Aaron on July 8, 2008 9:36 AM

I second Jens and to some extent Evans: Shortening your code is a very good way to make it unreadable.

'Less lines' doesn't necessarily means 'faster to read'. Look at abs() in 'Horizontal Complexity'. I strongly disagree to remove the else (although I think early returns are not evil): shorter program but slower to understand.

Serge Wautier on July 8, 2008 9:39 AM

Less is more.

Charles on July 8, 2008 9:40 AM

A favorite quote of mine by Edsger Dijkstra: If we wish to count lines of code, we should not regard them as lines produced but as lines spent.

Chad on July 8, 2008 9:43 AM

@KenW:
You seem to be using public and global interchangably, or at least implying that the concepts are closely related, which is very confusing. In every language with which I am familiar, public is an object oriented term describing which code can access a class member: specifically that any code with access to the class also has access to the member. Jheriko suggested that sometimes it is better leave data members public (and I'm not going to get involved in that debate for now) and yet you appear to be responding with reasons why global variables are bad. I don't understand the connection.

Weeble on July 8, 2008 9:44 AM

KenW: Sorry I am mainly a C++ programmer, so most of what you said does not fit with what I know and do. I assume you are familiar with something else... for instance, there are no scoping issues on class member variables. you need to use a . or - to access them...

Your stack comment is also a bit wrong, seeing as these variables will more than likely be allocated off of the heap anyway... except for local temporaries which will go on the stack, just as they should.

I agree about global variables though for the most part. These are pure evil, except on very small apps, where worrying about encapsulation will make your project take 2 times longer to complete or worse. These are very much the exception though...

I missed the point about foreach too... whilst there maybe more horrible inefficiencies to worry about, its best to do it right in the first instance. Personally I avoid foreach like the plague, because it hides code. Though I am very much aware that I take that philosophy too far, to the point of avoiding things like the .NET framework, VB or Java whenever possible because they hide about 99.99% of what your program does... at least with C/C++ I can look at the code and get a good estimation of what it will compile into. :)

Bleeding edge optimisation is normally too much, but don't forget that even basic things like memcpy can be improved upon trivially with a smattering of asm. Its naive to think that who ever implemented the library/language actually did the best job possible for your specific situation... its usually a case of picking the best fit method for the most cases...

Jheriko on July 8, 2008 10:01 AM

Good advice Jeff. The concept of Spartan Programming merges a lot of more or less well known rules. I only disagree with the C and Java examples as I dont think they show a good coding style. The C code hasnt been modified very much at all. The Java code made some steps in the right direction, but I think, it could have been split in a few simple methods with proper names. Also some of the variables could have been named better:

* Session ses = ... -- Session session = ...
* for (File f: attachements) -- for (File attachement: attachements)
* InternetAddress[] arr = ... -- InternetAddress[] iAddr = ...

Also a little more whitespace would make the whole thing a little bit more readable. I think one should strive for a spartan programming style but always have an eye for code readability.

Florian Potschka on July 8, 2008 10:11 AM

Except in that Spartanizing of the Java function you linked to, they have an error:

This loop can be simplified further, by removing variable fds, which is used only once, and by using a terse name instead of currPart
for (File f: attachements) {
MimeBodyPart part = new MimeBodyPart();
part.setDataHandler(new DataHandler(new FileDataSource(f)));
*** part.setFileName(fds.getName());***
parts.add(part);
}

Whoops - guess that pesky variable wasn't used only once ...

Kyle Hale on July 8, 2008 10:13 AM

Terseness is an advantage, but the extreme case is going to slow down development:

The inline function calls that remove local variables also remove the ability to breakpoint and inspect intermediate results.

Isn't it a maxim that we should step through ever line of code at least once to make sure things are occurring as expected?

On top of that, both examples look contrived. Each (especially the C code) presumes to represent actual, complex source, but neither has a single assert.

I realize that Java will throw, but how was this 'code' written and debugged?

Enguerrand on July 8, 2008 10:15 AM

@Jheriko: I avoid foreach like the plague, because it hides code. Though I am very much aware that I take that philosophy too far, to the point of avoiding things like the .NET framework

Weird philosophy!

Your basically saying why use existing, well-tested language constructs and libraries that hide your code when you can write your poor equivalents with new and interesting bugs.

Graham Stewart on July 8, 2008 10:18 AM

Like Daniel above, I was disappointed that the example java code Jeff links to is buggy even to my non java eyes. Makes it hard to take you seriously as a proponent of a system when you leave buggy code in public or if you tout an example without critically examining it first.

If you don't critically examine the ideas before you present them, you do a disservice to your readers. Given the cut and past nature of the article, I find it hard to believe that you critically examined much of it. Synthesis is more important than being an echo chamber.

Matt Katz on July 8, 2008 10:21 AM

Early returns make code much easier to use and much easier to maintain.

For example, if I have 6 reasons which make it so a block of code should not execute, I simply test the 6 reasons and return early on any if they are true (or all of them together if you want to test all of them at once).

However, without early returns, my block of code is nested under 6 (sometimes more) loops, where I have to trace back all my start and end blocks to figure out which if statement I am under. My actual code block will be at the right side of the screen, if I can ever find it...

Jeff Davis on July 8, 2008 10:21 AM

The C example could be made better by changing the #define's to const int declarations (basically the equivalent of java's final). That way the compiler will be able to identify type errors, and any static code checking software you're using should work better.

You can also extend this further by modifying your function declarations to use const parameters for variables that shouldn't be modified. For some example's of this, have a look at a C99 header file like string.h

Dana on July 8, 2008 10:27 AM

A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.
-Antoine de Saint-Exupery

PaulG. on July 8, 2008 10:31 AM

I like early returns. If an early return causes you to accidentally miss clean up code, then you're doing it wrong: you should be using RAII. (In C++, use destructors for cleanup. In C# use using blocks and IDisposables.) If an early return makes it hard to see all the code paths, your function is probably too long.

Weeble on July 8, 2008 10:33 AM

Inlining/folding variables that are only used once in C++ can be very frustrating. Like previous posters have mentioned, it makes it harder to parse visually. Removing the clear label that describes what the subexpression is doing can obfuscate and complicate otherwise straightforward code. You're against horizontal complexity at the macro-level, this seems like the equivalent at the micro-level!

Having small temporary const variables hold subexpression results makes stepping through the code in the debugger orders of magnitude simpler (again, in C++) as well.

I agree with your sentiment, but I think you've gone a little too far in your details! But hey, to each his own.

Charles on July 8, 2008 10:36 AM

I'm no fan of early returns and I think var names should be descriptive. But bandini hit my Go Batshit button with the use of 'temp' or 'tmp'. As has been pointed out, now that Globals are seldom used, all vars are temp in manner of speaking. I reserve the 'tmp' prefix for var names to situations where the var is to be removed at some future point. It bothers me when I see 5 year old code with 'tmp's still present. Good thing no one has suggested tight-coupling or I'd have broken my monitor.

twmcneil on July 8, 2008 10:37 AM

This is almost horribly bad. It is completely counter-intuitive to making readable maintainable code. While some of the ideals and principles are correct, the application of them is just plain wrong. Variable terseness is a throw back from the days of 1 character variables. It should never ever be a consideration, its time to re-read Code Complete. It is much much much better to have a variable named messageToSend then to have a variable named message or GASP m and have a comment above stating that this variable is to hold message that will be sent, or worse yet, not have the comment or well named variable and let the reader try and figure it out.

Where is the whitespace? White space is good, its a breaking of logical ideas in the code, makes it more readable.

How much more maintainable is code like this:

if(ShouldSendMessage())
{
... do some stuff
}

private boolean ShouldSendMessage()
{
return m.body != null m.subject != null
}

vs.

if(m.body != null m.subject != null)
{
... do some stuff
}

Spartan coding would frown on the first example and refactor it to the send to save lines of code.

This kind of thinking is totally backwards from the principles which are expounded upon in Code Complete. Simplicity is good, but a good amount of Spartan programming is calling effeciency and cleverness simplicity. Saving the { } on a statment may save space and look cleaner, but its error prone for maintenence. Newing up a variable thats only used once nesting inside of another constructor, may save a line, and look prettier, but its harder to maintain and understand. Sure a guru, who understands all the constructs of the language and what you are doing might be able to figure it out just as easy as having it on a seperate line, but I stress this point. The average novice that picks up the code to maintain it will have a much easier time maintaining a block of code that is 200 lines long and has explicitly named variables and none of the tersity tricks, then he would trying to maintain a clever 50 line function. It has been said write your code like the person maintaining it is a crazed lunatic who knows where you live, but I think its even better to say write your code, like the person maintaining it is an idiot, who has your phone number and will call you up for unbillable hours.

John on July 8, 2008 10:39 AM

Spartans! Prepare for glory!

Minimalism is best especially if not for yourself, but for others in collaboration with you. Why overdue it with complexity when the old adage holds true, *keep it simple, stupid*.... ? Actually I recall you saying this in past posts.

Great article Jeff.

Patrick on July 8, 2008 10:40 AM

Writing Spartan code takes a lot of work.

Long ago a mentor told me: Don't be afraid to remove code, I spend half of my time deleting code I just wrote.

I have always found this quote inspiring and I think it is a thing that differs in young programmers as if they fear changing/editing/removing code that was just written. As if it demonstrates a flaw, that they did something wrong or inefficient. But, the wrong thing is letting that code live there.

My next objective is to be able to write that same quality level code without spending so much time removing code... like in a perfect/spartan first draft.

philibert on July 8, 2008 10:43 AM

@mrcl:

I think there are more important things to keep you up at night than the overhead costs of foreach.

As with so many things in life, it's all in the details: what are you iterating over, what are you accessing, are you only reading the items or are you modifying them, and so on...

protected static on July 8, 2008 10:47 AM

I dont mean to be a downer, but sometimes it feels like these posts fish a little from the shallow side just to have some fresh content. The result is regurgitation, echoing information that other people wrote without adding anything new or original. Thats not contributing.

- After 20 years of programming, youve reflected that its usually a good idea to remove unnecessary code. quite a compelling conclusion.

- Throwing in a tangential pop-culture image just waters this down even more

- How do you justify yourself? Links to other places are a weak way to justify your opinion.

If it is just plain obvious that you should reduce your code and you dont need to justify the argument, then your whole article is ironic, because there is nothing minimalistic in writing an article about the obvious.
Consider an ieee paper regarding some case studies used to define hard figures behind the economics of software reuse
http://csdl2.computer.org/persagen/DLAbsToc.jsp?resourcePath=/dl/mags/co/toc=comp/mags/co/1994/07/r7toc.xmlDOI=10.1109/MC.1994.10075

I don't know what its like being in your shoes as a professional blogger, and I really support your website and great writing style. Of course you cant be a guru on every subject you cover, because you write about a broad range of subjects.

Maybe my problem is that your blog has become more oriented towards people looking for the pre-digested introductory information.

I cringe a little every time I see you rehashing more common knowledge, because I know if you post less frequently, you have the skills to come up with some great in-depth research.

pete w on July 8, 2008 10:48 AM

I hardly ever use early returns here.
The company standard is to generally avoid them.
The only use I have for them is for establishing pre-conditions at the start of functions.

e.g.

int myfunc(int p)
{
// Precondition: p must be in the range 0 to 5
if ( (p 0) || (p 5) )
return -1;
...
}

Graham Stewart on July 8, 2008 10:52 AM

My biggest problem when writing as little code as possible has to do with unit tests. We have a program where we code calculation rules that users give us. We write a unit test for each of these rules to make it harder to mess things up, but that can take a lot of time. But, for the actual code we can usually boil a collection of rules down to a few lines of code. I don't know how to get around that, except to stop coding the unit tests. Right now the benefit of the unit tests outweighs the tedium of creating them.

Gary on July 8, 2008 10:53 AM

As long you are talking tuples, minimalist code, all wrapped up in fascicles of obsolete material, I am with you. Now off to more organ playing and long-hand writing.

Go fictitious machines! Go assembler-like OO languages.

Buy my books. Learn the computers (Video Professor).

DonaldKnuth on July 8, 2008 10:53 AM

I'm a big fan of early returns. They avoid that you need to indent 20 times within a function, which makes it very hard to follow the function. Unfortunately in plain-C, early return means you need to make heavy use of something frowned upon: GOTO

E.g. a function might look like this (_____ used to show idention):

// Init variables
// If all inited successfully
____// Do something with them ... lots of code here
// Clean up all variables
// Return result

Okay, now this is just one level of indention, but Do something might again init something and again and again, so the nesting gets deeper and deeper. Instead I want to leave the function as early as possible, but if init failed, I can't just return. I might have inited 4 vars, some might have failed (that's why I want an early return), but maybe some did not. I need to clean these up (e.g. malloc/free) otherwise I'll have memory holes! The only way to do this in a clean fashion is like this

// Init variables
// If NOT all inited goto finally
// Do something with them ... lots of code here
finally:
// Clean up all variables
// Return result

See, I removed the indention and I can do the same way for every other indention level I had used otherwise; but I can't just return in case something went wrong, the clean-up code needs to run. GOTO is the best way to do this. I use GOTO to emulate the missing TRY/CATCH/FINALLY structure in C. There is no TRY, but my labels are usually named catch and finally. Finally is something that always needs to run before the function returns, no matter what happened in the function. catch if present, only needs to run in case of an error and not at all if everything went right.

I also can't follow the rule GOTO is okay, but only if it never jumps backwards. I know why this rule exists. People used GOTO instead of for/while/do-loops, which makes code hard to read. But if GOTO can only jump forward and I need some catch code, the code will look like this:

// Init variables
// If NOT all inited goto catch
// Do something with them ... lots of code here
goto finally;
catch:
// Catch code
finally:
// Clean up all variables
// Return result

See, I only jump forward, but that means if everything goes right (as designed), there is a jump, too, one that jumps over the catch code. BAD! I design functions in such a way, that GOTO-jumps only take place if something ever goes wrong, but never if nothing goes wrong. If nothing goes wrong, the function runs from top to bottom, enters at top, returns at bottom; clean code flow is very important to me! Hence my code looks like this:

// Init variables
// If NOT all inited goto catch
// Do something with them ... lots of code here
finally:
// Clean up all variables
// Return result
catch:
// Catch code
goto finally;

Disadvantage: The last code of the function is not the return code, it is the catch code. Return is before the catch code. The jump from catch to finally is backwards.

Advantage: If no catch happens and also no direct jump to finally, the code runs from top to bottom, will always enter the finally block, but never the catch block, because it returns early.

Mecki on July 8, 2008 10:56 AM

You should not try to code smaller. Coding smaller is simply the result of right design for the content.

Andy Wong on July 8, 2008 11:01 AM

Sorry Jeff, but I just had to bring up your post 834 Thirteen Blog Clichs here:
http://www.codinghorror.com/blog/archives/000834.html

As the old adage goes, a picture is worth a thousand words. But you should no more insert a random image into your writing than you would insert a thousand random words into your writing. I don't care how beautiful your photographs are, it's a terrible, irresponsible practice that distracts and harms readability.

And those of you sitting there smugly, with your stock photo library and your peripherally, tangentially, almost-but-not-quite related images that you use to break up your text, don't think I'm not talking about you, either. Because I am. Think about that the next time you read an article about a web 2.0 bubble accompanied by-- you guessed it-- a stock photo of a child blowing a bubble.


So OT, but I notice from time to time that you like to use your peripherally, tangentially, almost-but-not-quite related images, and I can't help but think about that older post on each occasion =)

Anyway, another good post today, but it's just easy being a critic!

Wade on July 8, 2008 11:26 AM

I'm going to agree with lots of other posters and say that while spartan programming in general is good, I take exception to terse variable naming.

Using the article Jeff linked to as an example - I would *much* rather have to maintain the first version of the drawing function than the second. Suppose there were a bug where the quadratic formula was written incorrectly, with two of the terms swapped. How would I find the problem if I weren't already familiar with the canonical form of the quadratic formula? There's no indication from the given code which term is x squared and which is x, for example. Is the bug that the terms are swapped inside the function, or the order of parameters is swapped in the calling function? Who knows!

Verbose variable names can be taken to an unhealthy extreme, I suppose, but the vast majority of the time I have problems with code that's too terse rather than too verbose.

Eric Lee on July 8, 2008 11:26 AM

Commonsense programming? ;-)

This entry reminds me of a couple of books that came out of a column in an ACM magazine, called Programming Pearls by Jon Bentle. And books like Effective C++, by Scott Meyers.

If one practices minimalism, then they won't need #region ;-)

dj on July 8, 2008 11:28 AM

- Try to limit method/functions to 7 or 8 lines.
- Try to limit classes to 200-300 lines
- Try to limit arguments to methods to 2 or 3
- Use spring or something simialr for initialzation

Good things happen:
- Early returns aren't a problem because your methods are so small and simple anyway
- you have more flexibility of the level of unit tests as you have the option of testing more methods or just the higher level public ones.
- Number of variables drops
- you need less comments as your method names should describe what the small amount of code in it does.
- You lean towards creating new classes to encapsulate data in order to limit arguments.


The real key here though is having an IDE that makes it painless to refactor. However well you plan to write good/well-factored/spartan code at first, when being maintained it will be chopped and changed and new conditions, variables and complexity will be created. If there's any barrier to re-factoring it doesn't happen regularly enough and the best-laid plans... well you know the rest

Alb on July 8, 2008 11:37 AM

basically link-jacking and unfair usage
Plagiarism. That's the word I was looking for. Taking credit for the work of another.

I linked back to the wiki *ten* times, included an explicit citation at the top, and added a hat tip to Yuval Tobias, who provided me the link, at the bottom. I'd have linked to Yuval's blog page or website, too, if he had provided me a link.

How, exactly, am I claiming this as my own?

Jeff Atwood on July 8, 2008 11:47 AM

It would be wonderful if there were more spartan products - a word processor that didn't drive like a stretch-Greyhound-bus, for example. Golly, in every field demanding creativity, it's amazing how much can be done with spartan means. Michael Connelly, whose The Lincoln Lawyer is one of the greatest mystery novels ever written, uses a simple, utilitarian prose style, honed during his years as an LA times crime reporter, to accomplish wonderful things. So did P.G. Wodehouse, the British humorist whom Isaac Asimov and a horde of other respected writers considered the greatest English-language stylist of the 20th century. WordStar was a marvel of utilitarian, Spartan style. So was WordPerfect, though it was the fork where word processing began to forget all about people who write (and not merely paddle words about).

runbei on July 8, 2008 12:01 PM

@ mmattax

It's true that my experience of PHP is mostly hacking around with open source projects for other people, so I don't wish to sound authoritative so perhaps you can prove me wrong and I can learn.

I wasn't talking about Spartan programming per se, more noise reduction. During my PHP hacking it seemed to me that a lot of things were (scarily) globally gettable and settable. Is this common in PHP? Perhaps it was just the case that the projects i've hacked with were badly designed but global variables are the anti-christ of noise reduction and simplification.

Jax on July 8, 2008 12:29 PM

@john,

I hope that your ordinary code doesn't look like that and that you are exaggerating, because If I ever have to work with someone who splits out single statements into their own methods for no apparent reason I will feed him his own balls.

Not only does this increase the code size, executable size, and execution overhead, it also a pain to reverse engineer. I hate having to skip around code to trace back every statement in a method and its especially annoying when it's stupid one-liners like these. Naming the function SouldSendMessage may help in interpreting the function's purpose, but it's not as informative as looking at the actual code. Especially in a situation where the code is only a single line. If you can't reverse engineer a single line of syntax then you don't really have any business programming, novice or otherwise.

This is especially relevant given that the name ShouldSendMessage doesn't actually tell us anything about the test you gave. A better name would be MessageNotBlank. I should be able to tell from the context of the if statement that the test is whether I should send the message or not, The name of the function should tell me what's being tested. This is especially true if you plan for reuse, which is the only reason I would ever refactor something to this extreme.

astine on July 8, 2008 12:48 PM

I wouldn't get too excited about some wiki posted in the Systems and Software Development Laboratory.

That page could have easily been posted by some student (or even a staff member) with little real world software engineering experience.
While I have great respect for academia, some of the suggestion in that page seems to be either naive, or plainly contradict industry practices. It's like if I would put up a page offering stylistic improvements for writing mathematical proofs. I have limited experience in writing them, and I am not qualified to make suggestions.

The C example is particularly bad. The original code presented (seems to be from some simulator) is very badly written. Almost anything done to that code will improve it, probably.
Converting #defines to enums and chained if/else ladders to switch/case is HARDLY news. Combining two code paths into one, is also nothing earth shattering.

Many of the ideas expressed in the wiki are worthy, but again, they are not new ideas. Some of the ideas expressed are downright dangerous in the hands of the inexperienced.

M on July 8, 2008 1:03 PM

More comments»

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been posted. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Content (c) 2009 Jeff Atwood. Logo image used with permission of the author. (c) 1993 Steven C. McConnell. All Rights Reserved.