views:

1631

answers:

26

I've been programming in C-derived languages for a couple of decades now. Somewhere along the line, I decided that I no longer wanted to write:

if (var)    // in C
if ($var)   # in Perl

when what I meant was:

if (var != 0)
if (defined $var and $var ne '')

I think part of it is that I have a strongly-typed brain and in my mind, "if" requires a boolean expression.

Or maybe it's because I use Perl so much and truth and falsehood in Perl is such a mine-field.

Or maybe it's just because these days, I'm mainly a Java programmer.

What are your preferences and why?

+18  A: 
if (var)

Less to type, as long as you're sure you're not testing the wrong thing.

Gerald Kaszuba
Not only less to type, but also less to read, which means less brain power is needed to understand it.
PolyThinker
if(v) are 3 keystroke less to type and to read, so it's much better.
Roberto Russo
it's all about semantic ask my wife she will sad both way are not readable (she is not a programmer) For trained C coder is perfectly clear so i will prefer the short way as well.
Ilya
@PolyThinker, that's just not true.
Zach Langley
+23  A: 

I prefer

if (var != 0)

It's easier to read/understand. Since you write the code once but read quite a few times, easy reading is more important than easy writing.

asalamon74
+1 code == prose, write for the reader and not for the typesetter
kenny
I use this, unless var is a boolean. I never do if (var == true).
Thomas Owens
if (var) is equally easy to read (if not easier) for me. More to read means more difficult to understand. But I agree that this is purely subjective.
PolyThinker
I agree with PolyThinker... for me, if(var) is easier to read because there is less to read and I already understand its meaning.
Jason Coco
Warning: the theory "less to read means easier to understand" leads inevitably to the conclusion that APL is the most easy-to-read computer language. Our tests say otherwise.
Steve Jessop
+7  A: 

I prefer explicit tests unless the result inside the parentheses is a explicit boolean. The phrase "if (1)", while syntactically and semantically correct in terms of the language, is not logical. It should be true or false, not cast automatically.

I prefer readable logical code to less typing any day.

I also despise vehemently code of the form:

if (gotError == FALSE) ...
if (isComplete == TRUE) ...

If the boolean value is properly named (and it should be), the right way to do that is:

if (!gotError) ...
if (isComplete) ...

That's because (using reductio ad absurdum) boolVal == TRUE is simply another boolean value, so where do you stop?

if (isComplete == TRUE) ...
if ((isComplete == TRUE) == TRUE) ...
if (((isComplete == TRUE) == TRUE) == TRUE) ...
if ((((isComplete == TRUE) == TRUE) == TRUE) == TRUE)...

And so on, ad infinitum.

paxdiablo
+2  A: 

I have a bunch ways of doing it:

for booleans:

if (x)

for ints:

if (x != 0)  // always compare, never assume true/false on int values

for pointers:

if (x /* != 0 */)  // I've always done this, not sure where I picked it up but I like it

These days, I think it's nicer to have a function call which describes what the logic actually means within the if statement

EDIT: Note, the 0 (intsead of NULL) is because I mainly use C++ these days

billybob
Why do you use "if (x /* != 0 */)"? To generate less (therefore faster) code? Is there any difference in the code generated for "if (x)" and "if (x != 0)"?
Adrian Pronk
Readability, more than anything. I did some tutoring when I was younger and this helped newbies out a bit (if (x)) can be confusing surprisingly enough. I'm always careful with logic :-)I don't think it generates less code, not enough to be signifant anyway :-)
billybob
A: 

VBScript? Well this bit of code declares a Variant, so bFlag is zero, which is effectively a False.

Dim bFlag
If bFlag Then

I don't like that. So even in VB, with the option of more specific declarations, I find myself being explicit no matter what the type.

Dim bFlag As Boolean
If bFlag = False Then

The other issue related to variable naming rules. If you're using an Hungarian-influenced regime, then you can tell visually that a given variable is boolean, so being specific about whether it's true or false is less of an issue. If, however, you're using some other variable naming technque, or worse, naming in an ad hoc way, then being specific about what's being tested for is appropriate.

boost
+3  A: 

If you have a value that is intended to be a boolean, you should feel comfortable just doing:

if ( var )
if ( $var )

If you have more specific requirements for your "boolean," you can always do some prep work/tests on your variable and assign it to another variable with better defined boolean values.

$shouldDoSomething = ( defined $var and $var ne '' ) ? 1 : 0;

if ( $shouldDoSomething ) {
    // Handle this case.
}

This can clean up the code quite a bit. It also helps if you intend to use this condition more than once. I find this happens pretty frequently, actually. Also, I feel like the above is far more readable than doing it inline:

if ( defined $var and $var ne '' ) {
    // Handle this case.
}
Beau Simensen
The ? 1 : 0 is unnecessary and, to my mind, obfuscatory.
ysth
You are correct, it is unnecessary for this particular example. I added it to address the "truth and falsehood in Perl" being "such a mine-field" issue mentioned in the question. With this code, you'd know that $shouldDoSomething will always be either 0 or 1.
Beau Simensen
+59  A: 

I like my ifs to make sense when read aloud:

if (is_it_happening) ...
if (number_of_sheep != 0) ...
if (pointer_to_something != NULL) ...
shoosh
Constants on the LHS please :)
JaredPar
@JaredPar: constants on the left or right is a topic for a different thread
Adam Rosenfield
constants to the left defeat the purpose of being able to read it out aloud.
shoosh
@Shy 0 != number_of_sheep (zero is not the number of sheep) sounds fine to me :P
Ólafur Waage
For a Jedi master, okay it is especially.
che
che: It's a shame it is not possible to moderate up comments here as +1 Funny like on Slashdot. I would have upvoted yours.
DrJokepu
Constants on the LHS made sense when compilers were braindead. Now they flag a warning if you try and make an assignment inside an if, and everyone should have "treat warnings as error" turned on.
Jesse Weigert
@Jesse: That's what I think. Constants on the left hand side were done to prevent programmer mistakes. In English, the constants are always on the right side of the equation. "My petrol tank is empty", "Your shirt is green", "If the pointer is not NULL" etc.
dreamlax
+4  A: 

In Javascript (I don't know about other dynamic languages)

if (x)

and

if (x != 0)

mean different things. I will use the former when the I expect x to hold a reference to an object or string that should not be zero length. Its a well known enough idiom.

AnthonyWJones
+9  A: 

I would say that if you are comparing a true integer, then never do an implicit conversion to boolean, as it implies a different meaning to the variable.

But then again that style is so popular is probably isn't too big of a deal, but from my work with C#, I write my C++ code in this style:

Boolean or int that is basicaly a boolean:

if (val)

True integer with more than true/false being important:

if (val != 0)

Pointer of some kind:

if (val != NULL)

But as many people will say about coding styles that make no functional difference, it is probably best of all to be consistent, and if you are working with existing code, be consistent with that code.

Guvante
A: 

Very often I use:

 if(x) {
       DoSomething;
       DoSomething2;
     }

Because this is less writing, and book which reading said:

Few good programmers use form if(x!=0), they use if(x).

But sometimes use and other form:

if(x!=0)

HNY! :-)

krisku
Which book did say that?
erikkallen
+3  A: 

I'm surprised nobody's mentioned the other option, which the coding standards at a past employer of mine advocated:

if( 0 != x );

Where the constant was always listed first (especially more important with comparisons as they occasionally get typo'd to assignments - the source of many a bug)

It's the style I've used ever since in my C / Perl / C++ / VB.Net since (obviously the point becomes moot in C# whihc doesn't actually allow the if (x) scenario (unless x is actually a boolean, of course).

Rowland Shaw
Would love to know why someone downvoted this...
Rowland Shaw
Agreed, down voters should comment!
Terry Lorber
Got another unexplained downvote today, as well...
Rowland Shaw
it should be downvoted because it's off topic. the constant on LHS vs RHS is separate from how to test for boolean.
Nathan Fellman
But it's also an expression of a preference where there are three options. maybe the answer should've been "neither", which is less helpful
Rowland Shaw
Constants on LHS is absurd and assumes a lack of intelligence in other coders and yourself.
James Morris
+2  A: 

In C# it has been made explicitly illegal to write

if(x){}

unless x is a boolean type. There is no implicit conversion to bool from most other types.

I used this form a lot writing JavaScript, PHP and such to check for non null. But then again, I did get a few (easily detectable) bugs from it... I guess we are better off without it.

When using it on boolean variables, I strongly believe in easily readable names. I usually name boolean variables used like that with names beginning with "is", "has" or something similar.

Øyvind Skaar
+7  A: 

In Perl if (defined $var and $var ne '') and if( $var) are NOT equivalent. Try it with $var=0. Conversely if you test on $var!=0 all strings that cannot be converted to numbers will fail the test (with a warning if you have them on).

So you must know exactly what your variable contains (number or string, whether it can be undef) so you can test accordingly.

I usually just write if( $var) and let Perl take care it. I believe that's easier to read, and that's the most common style in Perl.

Very often, actually, the proper test ends up being if( defined $var). That's where perl's new (in 5.10) // operator comes in handy. $var= $val // $default or often $var //= $default, where $var will receive $default only if $val (resp $var) is undef.

mirod
Which is why I said "truth and falsehood in Perl is such a mine-field". What I normally want to know is if "defined $var and $var ne ''". I normally don't want the test to return false if "$var eq '0'"
Adrian Pronk
+2  A: 

I generally prefer if (var) or if ($var) if var is used as a boolean, even if there isn't any such type in the language.

I very much dislike constructs like if (!strcmp(...)) or if (var == true). The first tries to be too smart, the second too dumb -- although it scales well to if ((var == true) == true), ... ;-)

Some languages, like Perl and C++, provide extra or even user defined interpretations of trueness. If the conversion to a boolean seems too magic, remember it's basically just an is_true(var) or var.booleanValue(), or something like that behind the scene, just a more concise syntax.

Related to your question, I like to formulate conditions in a positive way. Instead of

if (!condition) {
    g();
}
else {
    f();
}

I prefer

if (condition) {
    f();
}
else {
    g();
}

Even if there is only a single branch, and the condition is not terribly simple. (An indication for that is the need for a comment.) For example, instead of

// explain reason for condition here
if (!condition) {
    f();
}

I prefer to phrase it as

if (condition) {
    // explain condition here
}
else {
    f();
}
Ronald Blaschke
+3  A: 

I go with readability like most people, I like being able to scan my code and read it without having to think too much, it goes hand in hand though with well named variable names. If your variable names make it sound like it should be a plain if(isPurchasable) then I go with it however it referes to a number or date or similar fasion I use if(stock > 0).

Having to write a comment for an if statement too me is a horrible idea if the expression is so simple, an if statement like below though I can see why comments should be used.

if(isPurchasable && stock > 0 && credit >= cost && !reserved) { 
     // Checks to see if customer can purchase product.
}
stuartloxton
readable code improves code maintainability and understanding. Code is intended for people. IL or binary is for computers.
Matthew
Should you really be a coder if you don't want to think too much!?
James Morris
@James; good point but not quite what I meant; thinking should be saved for the actual problem at hand; if simply working out what my code is doing takes thought than any problem solving will take twice as long.
stuartloxton
+3  A: 

For numeric value scalars, I tend to write if ( $num_foo ) when $num_foo is in my control. If it’s user input or passed in from outside I either numify it first or spell out the test explicitly. It depends on a lot of factors. The main criterion is when and how it’s convenient to deal with undefined values, in order to avoid warnings.

To test for non-empty string, I used to write if ( $foo ) because the correct incantation is just way too much typing:

if ( defined $foo and length $foo )

But I wasn’t satisfied with this state of affairs so I instigated a change of behaviour for length undef in Perl 5.12, which throws a warning and returns 0 up to Perl 5.10 inclusive. In 5.12 it will just silently return undef. Therefore in non-boolean contexts you still get a warning, it just happens after the length call is evaluated rather than before. But in boolean contexts, there is no warning, so checking for a non-empty string is much easier to do correctly:

if ( length $foo )
Aristotle Pagaltzis
+2  A: 

To my way of thinking, simplicity is best.

The simpler you make the code, the better. Also, the less likely you'll make mistakes. Therefore, I would use

if(var)

But in the end, you should use what works best for your own way of thinking.

Max
+2  A: 

I don't always manage it, but I try to use

if (0 != var)

so it matches the defensive style

if (0 == var)
stesch
+1  A: 

I prefer a bare:

if ($canDo) {
}

instead of something like:

if ($canDo == true) {
}

Where a conditional is at all tricky, I comment it either explicitly with a comment, or implicitly with a good variable name. I also try to be very explicit when setting a boolean variable, preferring:

my($canDo) = !0;

to

my($canDo) = 1;

The latter is confusing; why assign a discreet value to a boolean?

Given Perl's many meanings to "evaluates to true", though, I can see why being more explicit is more practical in the long run. Still, one of the things I most like about Perl is its natural linguistic fluidity, and I prefer in my code to stick to that (leaving the comments and variable names to further clarify things, if needed).

Joe Casadonte
+19  A: 

It's quite simple. if( var ) tests for truthiness. if( var != 0 ) tests that it's not the number 0. THEY ARE NOT INTERCHANGABLE! There are three reasons.

First, using if( var != 0 ) to test for truth is more complicated. There's simply more there to read and understand. You have to grok that != and 0 is the idiom for "is true". Lacking a distinctive visual pattern, you have to do a little more studying to know that it's not the same as if( var == 0). This is a thin distinction, but worth mentioning. The fact that the if( 0 != var ) style exists gives credence. Better to just eliminate the problem and use if( var ) for truthiness.

Second, and more importantly, the intent must be clear. Are you testing for truth or are you testing for a number (or lack thereof)? if( var ) is testing for truth, if( var != 0 ) is testing a number. To determine anything else requires having knowledge of the author's style, which we must assume the maintenance programmer does not.

Third, there is an assumption here about the value of true and false and numeric operators which might work out in some languages and not in others. In Perl, and I think Javascript, too, empty string is false. A lot of operators return empty string for false. So testing truth with if( var != 0 ) leads to a warning. It becomes more stark when you do something more naive like if( var == 1 ) to mean truth, a clearly dangerous assumption. I have seem many junior programmers write that and in turn written functions that return odd, but true, numbers to punish this sort of thing. Or when I'm in a giving mood, I've sanitized my return value with return var ? 1 : 0.

In a related note, Perl will return the last evaluated expression from a subroutine, so it's not necessary to actually write return. Combine this with the idea people have that explicit return is slower and you get a lot of people abusing this fact.

sub set {
    my( $self, $key, $value ) = @_;

    $self->{$key} = $value;
}

set will return $value. Was that intended? I don't know. What I do know is someone will start relying on it. And the maintenance programmer won't know if they can change it. So I like to explicitly put a return in every non-trivial subroutine.

sub set {
    my( $self, $key, $value ) = @_;

    $self->{$key} = $value;
    return;
}

In that case I decided set will return nothing for the time being and that decision will be quite clear to both the reader and the user.

Schwern
Code complete backs this dude up.
James McMahon
I like your reasoning, never thought of it that way.
JimDaniel
@nemo I grew up on that book. :)
Schwern
+1 for your idiom to include an explicit void return when the subroutine is intended to return nothing. I'd never thought of that angle. BTW my original question states "... when what I meant was if var != 0" so I was not assuming the different forms were equivalent, just that in some situations, one could be replaced with another for better readability.
Adrian Pronk
A: 

I find that if(X) { /* ... */ } is much easier to read (in C, at least).

Anthony Cuozzo
A: 

If i don't expect anyone else to read the code, I'd us the short one. If I expect someone to actually read my code, I would consider using the long form for readability.

Calyth
Someone is _always_ going to read the code.
Adriano Varoli Piazza
+1  A: 

if (var != 0) is better imo.

A: 

I like Python constructions:

if var:
    return "I like the way I do it!"

It's just for example ;-)

dobrych
+1  A: 

If you've got an int-bool in C that already holds a flag (and not a count), and you're testing it with "if (var != 0)", where does it end? Wouldn't "if ((var != 0) != 0)" be even better? :-)

Anonymous Coward
Someone's been reading Godel, Escher, and Bach -- or skipped it and went straight to Lewis Carroll :-)
Dan Breslau
I've never read the former, or anything by the latter. This was told me by my freshman year CS prof.
Anonymous Coward
Well, I didn't say it was *you* :-) But I recommend them both.
Dan Breslau
A: 

There are languages in which you have no choice. In Specman, for instance, you can't write:

var x: uint;

if (x) {
    bla
};

But you can do:

var x: uint;

if (x != 0) {
    bla
};

or

var x: bool;

if (x) {
    bla
};

However, you can't do:

var x: bool;

if (x != 0) {
    bla
};

Because you can't compare a boolean to an integer.

Coming from C and Perl I always thought this to be annoying, until I actually started writing a lot in Specman. The code is simply clearer like this.

Nathan Fellman