tags:

views:

1550

answers:

24

Like children, programmers are often given the information that they need for their profession in the form of inviolable "rules". Like children, we often follow these rules unflinchingly until one day, by accident more often than deliberately, we don't follow the rule, and nothing bad happens. Maybe we even see that not following the rule makes our lives easier and our code works better.

My favorite abandoned rule is:

Never use SELECT * in a query

I absorbed this rule while learning SQL the night before my first day at my first IT job (1996) by cramming a book on Access. The book spoke with the ferocity of a televangelist about how a baby kitten is drowned whenever a programmer uses SELECT * in a query, and I believed.

For years I never ever used SELECT *. One day, I was writing a query like

SELECT COLUMN1, COLUMN2, ... COLUMN472 FROM tblWHYTHISMANYCOLUMNS

when it occurred to me that since I was just asking for every column in the table, I could save some time by typing

SELECT * FROM tblWHYTHISMANYCOLUMNS

I tried it, and amazingly it compiled and ran perfectly. I've been an asterisk-man ever since. Nothing bad has ever happened to me as a consequence.

So what's your favorite abandoned rule?

+1  A: 

Never tell "I will never use <bla-bla-bla> ".

dimarzionist
+10  A: 

This might be naughty...but:

Write tests for your code before you write the actual code.

Oops...that almost never happens.

jjnguy
It can't be abandoned if you never followed it in the fist place. :P
KTC
Ha, we were forced to in class.
jjnguy
This rule seems hard to follow, but test-driven development helps you to write clearer and better code. And if you really start to try this method ... it is fun. It makes fun to write a test, run the test knowing it should fail. Sometime the test doesn't fail, and you know the test isn't sufficient.
Mnementh
I've never agreed with test driven development. Tests written in advance can't know where the edge cases to test are!
Loren Pechtel
imho *former debugging printfs* make the best tests afterwards
ZJR
@Loren: I disagree. Either you define your behavior, or all of your behavior is undefined.
kyoryu
You can define the behavior but this doesn't specify where internal edge cases are.
Loren Pechtel
A: 

Depending on how much of an exaggeration COLUMN472 is, having to specify columns may not be the only issue with your application.

(I'm kidding, I'm kidding ;)

Jeremy Banks
I think the actual epiphany occurred with a 60-column table (not my design). I was getting ready to write a little desktop app to auto-generate the SELECT statement for me, when the somewhat-simpler SELECT * solution occurred to me.
MusiGenesis
i mean yea might as well use * if your app is that f'd up already. what happens when someone adds another text/blob column to your table and your queries now return huge amounts of unnecessary data?
Shawn Simon
If he adds the BLOB column without telling me first, I kill him.If he gives me advance warning and lives, I create a view on the table that includes all the original columns but excludes the new BLOB column. I then call SELECT * FROM {the view}.
MusiGenesis
+8  A: 

Hungarian notion (at least in the microsoft longpointertosomethinginmemoryonacomputer form)

ps. Yes I do know the correct use of Hungarian notation and I do use that.

Martin Beckett
my boss made us use that, i finally got him to stop, makes no sense in a dynamically typed language
Shawn Simon
Shawn, check out http://joelonsoftware.com/articles/Wrong.html for what Hungarian is really meant, not what most of the world imagined it was supposed to be like.
Nouveau
@Shawn: it's even _more_ important when you don't have the compiler enforcing strong type checking. But as for the MS hungarian, it's unfortunate but most of the Windows API uses hungarian wrong, and even more unfortunate that Charles Petzold did it wrong - and taught an entire generation of programmers.
John Knoeller
im sorry, i meant statically typed
Shawn Simon
@shawn - it makes no sense for a dynamic typed language (one where the type of an object can change during execution) it does make sense for a duck-typed language (one where the type is set depending on what you first assign to it) then it can help debugging if bFlag suddenly contains a string
Martin Beckett
+17  A: 

Never use gotos.

Used correctly they can be immensely useful!

shoosh
To be honest, it has never occurred to me to use goto since I programmed in BASIC. I wonder in how many places it could have helped me...
Thomas
Im guessing zero. Ive yet to find a use for them in any language that supports both loops and exceptions.
metao
@metao: You should NEVER, EVER use exceptions for control flow.
TraumaPony
oh, obviously. But the only "good reason to use GOTO" that used to be taught was basically a primitive form of exception handling. With exceptions built in to most languages now, there is really no excuse.
metao
Get the to a nunnery! :)
johnc
I've seen people write code like: do { ... break; ... } while (false); to simulate a goto. I would rather they used gotos in that case!
Ferruccio
As I learned Pascal (I started with BASIC) my first question was about goto. I wondered how you could program without it. As I learned, how you can use goto in Pascal, I not longer needed it. Since then I never used gots again.
Mnementh
@metao: That's not true at all. In C they are quite useful for breaking out of nested for loops and for grouping clean up code into one place in a function.
Eric
Super useful in TI-BASIC, if used with the `if` conditional, you can easily define functions, albeit in a primitive manner. This comes in handy because TI-BASIC programs are all I can use in my maths exams
Jonno_FTW
Ferruccio: That's not a goto. Goto is more general.
trinithis
MUST POST: http://xkcd.com/292/ . Sorry.
PiPeep
Goto is still valuable in cases where better flow control structures don't exist. These days that almost always means loop-and-a-half cases. I probably only use one per year.
Loren Pechtel
I frequently debate about this with a *fervent* GOTO supporter. Turns out it is a matter of *programming styles* and *claustrophobia* : **loop-claustrophobia**, to be exact. Some people **iterate a lot**, some people **iterate deeper**. I find more that 2 levels of iteration the signal it's *time to make a procedure call*, other people don't, and go on. Then they feel the burn: they **must bail out** but don't know how deep they are in their *iterative inferno*. Loop-claustrophobia ensues, and goto is sometime the *only* solution.
ZJR
+10  A: 

"Premature optimisation is the root of all evil."

People -always- take it out of context. There was the question just asked an hour ago about it on the algorithmic scale; people usually don't know the full sentence. He was talking about things like using "myInt << 1" instead of "myInt * 2" etc.

I used to try and keep my algorithms as... Well, not simple, but brute forced. I quickly learned, however, that in a real time ray tracer, you kind of need decent PVS (Potentially visible set); I had to rewrite most of my code to do it properly.

TraumaPony
I'd say your PVS example is more an issue of design, rather than optimization.
Mikeage
First: your code must work. Later: Optimize if you have time.
yelinna
-1 for not mentioning profiling
finnw
+1 While that motto *isn't meant to mean* "designing is stupid", "not wasting time and memory from the start is stupid", or even "thinking is stupid" too many people read it that way. And disaster follows.
ZJR
+77  A: 

Every function should have only one exit point.

This got thrown away as soon as I graduated.

metao
This is actually good theory. Other than exceptions or other errors, most functions can be written trivially to have one exit point (typically at the end of the function).
Matthew Scharley
What can I say, rules are made to be broken. Yeah, ok, switches put a hole in this theory for me too *covers up his code*. Do as I say, not as I do ;)
Matthew Scharley
multiple exit points can make code so much shorter, cleaner and easy to read and write.
Booji Boy
also leads to way less nested if's
Shawn Simon
actually, its escaping the nesting ifs that made me start breaking the rule in the first place. That, and avoiding those ridiculous retVal variables.
metao
"One exit point" is super-annoying with getters or functions that return booleans.
Antti Rasinen
I never have understood this rule. My best guess is that in the days of GOTO vs GOSUB, it meant that your GOSUB should always RETURN, not GOTO. Which is logical, but in most modern programming languages it's irrelevant.
Kyralessa
The one exit rule is mostly about making sure you've cleaned up after yourself. By having only one exit, there is only one place you need to make sure that any allocated resources are freed before leaving. I stick to it unless it would force me to create temporary variables.
Ferruccio
That's indeed the most retarded rule in computer science. It doesn't make code clearer, it doesn't make it run faster... I wonder who came up with it for the first time.
Vicent Marti
This rule really is bad. It makes me sick to think how complicated get simple functions, if you try to follow this rule. As a java-programmer if often check at the start for null-parameters and return the value for that case. The usage of returns at this point reduce the level of nested ifs.
Mnementh
Jay Bazuzi
It often makes for ugly code, but it makes for easily verified code.Many safety-critical and/or embedded systems standards' require it; for example, cf MISRA. At work, I use it; in my personal programming, I find the lack of readability to be worse than the lack of easy formal verificatoin.
Mikeage
It is no more difficult to formally verify a subroutine with multiple exits than with one exit.
Dour High Arch
The single return point is a great idea, but the dangers of shared memory and state in long methods makes single return point kind of pointless. It's like locking the door while the house is burning down.
kyoryu
+6  A: 

I've been known to abuse loop (mostly for loops) semantics to do some fun/interesting stuff before. I mostly blame the time I spent as a perlite, where you can get some interesting one-liners that way. The most recent of these would have to be (C#):

readonly string[] prefixes = new string[] { "", "K", "M", "G", "T" /* etc */ };
public function NumBytesToString(int bytes)
{
    double d;
    int i = 0;
    for (d = bytes; d > 1024; d /= 1024) { i++; }
    return string.Format("{0:0.00} {1}B", d, prefixes[i]);
}
Matthew Scharley
Wow, that's a pretty neat trick.
TraumaPony
i becoming the index into an array of strings that are prefixes ("K", M", etc) and d being the value, hence in C#, string.Format("{0} {1}B", d, prefixes[i])
Matthew Scharley
uh, what's that i++ all about? Presumably it later indexes into some suffix table {"Bytes", "KiB", "MiB", "GiB"}[i].
davenpcj
Or you could do: i = floor( log(bytes) / log(1024) )
fenomas
for ( ... ; ... ; ++i, d/= 1024 ) { /* who needs bodies */ }
derobert
@fenomas: I honestly don't know which would be the "better" way, as both i and d are needed in the final result, as noted in my last comment.
Matthew Scharley
I don't see the "abuse" here, that's a perfectly normal loop. Would you call iterating over a linked list in C "abuse" just because it does something other than increment a counter?
finnw
@finnw: perhaps abuse is too strong a word, but when 90% of loops are simply incrementing a counter, then yes, it's a standout case. It's out of the box. Ironically, my code *is* incrementing a counter, just not in the loop structure itself.
Matthew Scharley
`double d = bytes; int i; for (i = 0; d > 1024; ++i) { d /= 1024; }`
trinithis
+13  A: 

"Never take sleeping pills and laxatives at the same time" - oh wait, that's not to be abandoned :)

I was particularly happy to abandon the "use tables for layout" from web 1.0.

JayTee
I was even happier to abandon the "never ever use tables for layouts" from web 2.0.
Wouter van Nifterick
+1  A: 

I dropped any rule that began Never do ... I'd say never say never or, if you prefer, there are usually exceptions ;D Select * is ok, although I personally use tools to do the bulk of the writing when doing large queries. FWIW I'd say don't use select * when also using "into" like: "SELECT * INTO #TEMP FROM REALTABLE WHERE COLX = 1" because if the structure of REALTABLE changes it can mess stuff up...

Booji Boy
+6  A: 

This is more of a design principle than a "rule", but 3-tier design is something I've enjoyed abandoning (in the sense of I don't feel obligated to use it everywhere).

I have seen countless applications in the wild that had a middle "business logic" tier that did nothing more than hand data tables back and forth between the data layer and the UI layer.

Sometimes (if not most times) your app is just tables in a database and a UI for manipulating that data.

MusiGenesis
Indeed, for most stuff, it's so needlessly enterprisey.
TraumaPony
3-tier is confusing sometimes.
yelinna
+13  A: 

I was once told that writing clean code for everbody understand included not using short if form like:

$data = (isEmpty($field)) ? "Default Data" : $field;

But I just can avoid it ... I even think this is more clear than

$data = $field;
if (isEmpty($field)) {
    $data = "Default Data";
}

or the else {$data = $field;} variation ...

Fernando Barrocal
Usch. The ternary operator is far too useful not to use. As your examples shows, it can compress four lines into one. I once converted a screenful of ifs into five ternary ifs. A HUGE improvement in readability.
Antti Rasinen
The ternary operator should be used, nested where possible. And for even more fun, Ruby's ifs return values.
derobert
I love Short If :D
yelinna
+2  A: 

Unit Tests on the UI, they're a bugger to do and too easy to ignore

Hungarian for UI Controls (makes them easier to spot in Intellisense)

Commenting ("Good code should comment itself - just don't ask me to explain why in a month's time" :)

johnc
Self commenting code is easier in something like VB or well structured Perl where you can actually very nearly approximate structured english with your code.
Matthew Scharley
+46  A: 

Think everyone's broken this one:

Design first, code second?

Dynite
What is this "design" you speak of?
Rich Bradshaw
Why can I only vote this up once?
fenomas
I do both at once: I start by writing interfaces. I guess that still counts as "coding without a design" as I'm typing into a code editor not a word processor.
finnw
If you're going to have to write down *SOMETHING*, why not make that the structures that you're actually going to use?
Loren Pechtel
+1 sometimes its impossible to figure out before how things work without coding.
Anders K.
A: 

I quit using CamelCase a while back, and I feel better about not using it every day.

Note: IIRC, among other things, asterisk makes two trips to the database, one to get the column names and another to run the query. A lot of these rules have uses that make sense (otherwise they wouldn't ever have become rules), so I would not ever permanently abandon any of them as options.

devinmoore
SELECT * doesn't make two trips to the database.
MusiGenesis
You should mention what you use instead of CamelCase. All lower case identifiers? The monstrosity of underscores? One word identifiers?
Wedge
As long as it's readable English, it's OK with me. That's why I accepted his answer: it's an example of a rule that doens't hurt if you don't follow it.
MusiGenesis
My view on CamelCase http://stackoverflow.com/questions/406760/whats-your-most-controversial-programming-opinion/1965432#1965432
Tor Valamo
I don't think camel case should be considered a rule. Just a guideline for easy reading. And the idea of a guideline is that not everyone agrees with it.
Ben Shelock
I'm amazed you've been downvoted so much. How dare you have your own opinions!
Noon Silk
I doubt it would be downvoted so much if it were not selected as the answer.
wheaties
You quit using PascalCase, by the looks of things. camelCase has the first letter lowercase.
Blorgbeard
@Silky His note is incorrect, which probably explains the downvotes.
Blorgbeard
Blorgbeard: Is it? It's the reason I've been given (can't remember where I heard it) for not using * (though, that's not why I don't do it). I must admit I haven't looked into it though.
Noon Silk
+13  A: 

Always use curly-braces around code-blocks, even though the language may not require it

This is a common "best-practice" suggestion that I have heard throughout the years, and it wasn't until recently that I have realized why I adamantly disagree with it.

Consider the following example:

if(myDevice.hasConnectionError())
  FaultResponseManager.submit(myDevice.getLastError());

If we assume the above code snipplet is apart of a code-base where all error conditions are expected to be handled exclusively by the FaultResponseManager (as per design decision), a perfectly clean way to discourage other developers from adding other code to the block of this if-statement is to simply drop the curly braces. This makes it clear that the original intent of the code block is to do exactly one thing.

Ryan Delucchi
That's gonna be tough in VB :)
chris
IMHO without the surrounding text (i.e. just look at the code sample) it isn't in any way clear that the code block should only do one thing. It's just clear that you haven't put braces around it. And it's not clear why you haven't done that.
Greg Beech
The point is that the lack of braces can "enforce" conventions within a given code-base. Let us say that there exists a convention that all error handling must be routed through a single delegate (in this case a "FaultResponseManager") and that if anything else needs to happen: it must be added to the implementation of said delegate (not within code blocks surrounding invocations of it). Applying such semantics to {}-less constructs is a light-weight approach to achieve this.
Ryan Delucchi
I hate curly braces when they're not necesary. I think the code is more readable this way.
yelinna
As a general rule, if I omit the curly braces, I make sure the if statement is only one line. I never omit the curly braces if there's an else.
Toon Van Acker
Brilliant in its simplicity. +1
FerretallicA
+5  A: 

In Java some people keep coding following the rule, that you should assign null to references that are no longer in use. That should help the garbage collector to reclaim the memory taken by the object the reference was pointing to.

This rule is completely outdated, on modern virtual machines it makes the Garbage collector actually less efficient!

Mnementh
I agree with you, but be aware that some devs do it so that an Object which is now in an unusable state is not accidentally accessed again. So it may look like they're doing it for the GC when they're really doing it to avoid bugs in later code.
David
Hmm, I'm not happy about this either. In Code-Review I would suggest to rewrite the object, that it cannot enter an invalid state. If that is really unavoidable, I would prefer asserts over nulling out the reference.
Mnementh
+4  A: 

I'm taking JayTee's comment at face value, although I don't believe that "use tables for layout" was ever a rule, so much as a de facto standard.

There is, however, that "don't use tables for layout" — or anything other than "tabular" data — rule, which is my personal favorite to abandon.

I've never been punished, or suffered in any way for breaking this rule! I've suffered a lot more over trying to answer questions like "How do I achieve x without tables?" In "both" browsers. Good riddance!

harpo
+2  A: 

Never use "magic numbers".

Often they are obvious, and a constant/#define actually obfuscates. In other cases, a judcicious comment is preferable anyway, as the description is where it is actually being used, rather than hidden elsewhere.

Jon Ward
A magic number is often unnecessary when localized in a well defined method or block. i.e. it may be obvious what it's for. If it's used in more than one place though - then it's best to provide a constant.
Conor
Good one! You'll love these: `#define BITS_IN_A_BYTE 8`, `#define NUMBER_OF_DIMENSIONS_IN_3D_SPACE 3` ;)
Emile Cormier
#define THREE 3
kyoryu
+9  A: 

You should NEVER, EVER use exceptions for control flow.

And then Python came.

Update: Having become familiar with Erlang, I'll have to add that to the already enormous list of [Python].

Tor Valamo
+11  A: 

Design frameworks, or so called re-usable code.

In my experience I have very seldom seen code been used outside their original place, but still I and others have designed stuff to be more portable than necessary. Nowdays I clear with customers first, then it often will be designed to ship.

Link on subject

epatel
If I could upvote this twice, I would.
kyoryu
A: 

Not using curly braces for everything.

http://leepoint.net/notes-java/flow/if/30if-braces.html

PiPeep
That's java, which automatically disqualifies any rule.
Tor Valamo
Actually, this idea has been reiterated for a number of languages. For example, "Javascript: The Good Parts" mentions the same thing.
PiPeep
+4  A: 

1) Every line of code should have comments.

++age; // Increment age
result = 42; // Assign 42 to result

2) Use unsigned integer types for numbers that can never be negative.

3) For better performance, use the smallest integer type that can hold your number.

Emile Cormier
I agree with 2) and 3), but was 1) a rule? I'd shoot myself in the head before I had to comment every line of code! Good code needs no comments, much like good people need no introductions.
Alix Axel
Every line of code should have comments? Hmm... that contradicts the 'good code should comment itself' rule. What do I do!?
Pheter
I don't remember where I heard #1. A university professor, maybe. A related rule I'm sure you've heard of is to always comment your code heavily. I agree with you it's better to use very clear variable/function names and let the code speak for itself (except where you're doing "tricky" stuff).
Emile Cormier
Now I remember... A univ professor required that every line of code be commented for his assignments, claiming it would instill good habits. Perhaps he was sick of guessing what `potato += 3` meant.
Emile Cormier
+1  A: 

"always design tables with 3NF in mind"

turns out that sometimes performance gets a hit when always doing 3NF

Anders K.