This is a common idiom of just about every language, including Java.
Many programmers write methods that look like the following:
public boolean isBigger() { // return if a is bigger than b if (a > b) return true; else return false; }The if statement is redundant. Boolean expressions (a > b) evaluate to a boolean value -- if your method needs to return it, then there's no need to have an if statement. The following code is equivalent to the previous:
public boolean isBigger () { // return if a is bigger than b return (a > b); }-- KyleBrown
It is sometimes stylistically clearer to be explicit in such matters, in any language, just as one might put "redundant" parentheses in an arithmetic expression. In more realistic contexts the coder might well anticipate that the "isBigger" method might eventually involve more complex logic than a simple compare of two variables, for instance, or it might be that related methods (isFuzzier, isMoreInteresting) are more complex and so isBigger is written so as to be consistent with them. -- JimPerry
A compiler might generate more bytecodes for the longer version than the shorter version. -- KyleBrown
Interestingly, they are compiled into identical bytecodes under jdk1.1.3 (without optimization). (javap app is very handy for this) -- BillKayser
Clarity should win out over minor inefficiency. When clear source produces bad object complain to the compiler writer rather than adopting a style that works around it. -- JimPerry
For many people, following a very common and simple idiom such as ReturnBooleanEvaluations makes for more readable code, particularly when the idiom shortens the code (as is usually the case). The eye can much more quickly consume the 1-line version. And since it follows a common idiom, the brain is not left behind.
On the other, I have to agree that it is sometimes best to be explicit. (I habitually, 'over-parenthesize'. :) And I strongly agree that clarity should win over minor inefficiency. (I just disagree about which form is clearer. ;)
-- KielHodges
I also side with the 'clarity first' crowd. And, here's an insight: The rule here is the converse to the Exception style rule. For example, we deprecate C-style code like:
if ( ioActivity1() != -1) { ... } if ( ioActivity2() != -1) { ... } if ( ioActivity3() != -1) { ... }...in favor of all code grouped together with exceptions handled somewhere else. Why? Because the code should clearly show it's -intent-. The intent with the C-code isn't to make a bunch of decisions, it's to do a bunch of io activity.
And thusly...
The intent of the original example is to make a decision and return a result. An if() paired with one or more returns shows what's going on. The suggested solution:
return (a > b);
...would be appropriate if the intent is to compute a value - which it's not. So - I find this ironic - on one hand, I'm advocating taking the if's out (relative to C-style coding), on the other hand, I want it put back in.
PS: I actually always try make every method have a clear beginning, middle and end, (The clear end being most important) and so would write the original example like this. This pays off as methods get complicated or need to be debugged:
public boolean isBigger() { private boolean result; if (a > b) { result = true; } else { result = false; } return result; }-- RobbShecter
I'm having difficulty imagining any sense in which the above 7-line, two-level chunk is more clear than
return (a > b);How many eye fixations does it take to read them? How much study does it take to ascertain that the code is answering whether a > b, not the reverse? How long does it take to convince oneself that all this code is just returning a boolean, with no side effects or other important horseplay? I see no dimension upon which to prefer the long version, unless your company is measuring LOC. --RonJeffries
May be it is down to house style. I prefer a functional style, with minimal side effects, and it seems natural to me to equate "isBigger" with the expression "a > b". To use 9 lines of code where 1 will do is to bloat the source.
If I need to see the value in a debugger, I (a) use a debugger which can cope directly (maybe with cut-and-paste from the source to an evaluation window; or (b) edit the source and recompile. If the routine gets more complex, bloat is probably going to make it worse rather than better because it distracts attention from the interesting bit. Either way I'd deal with the situation when it arises. An example perhaps of YouArentGonnaNeedIt. -- DaveHarris
Could the representation of booleans in C favor one idiom over the other? No probably not. But a tangential (and false) speculation as to why a C programmer might favor the longer form over the shorter led to a series of observations which have been moved to BooleanRepresentation.
Using if...else for ReturnBooleanEvaluations imparts the intent into your code that you are implementing conditional branching. In the above example, you are not making a decision, you are simply calculating a result. I prefer the idiom that a conditional results in a boolean value, which is what is to be returned as a result:
return a > b;Parentheses in this case do nothing to clarify the statement.
-- JeffLangr
Would this seem an acceptable compromise to people?
return (a > b) ? true : false;Here it is very clear that you are specifically returning one of two values and are selecting which value based on the expression. On the other hand, it is fairly terse and easy to grasp quickly.
-- RussellGold
I see no reason to compromise. When we use a language, we should commit ourselves to knowing it, being able to read it, and writing it idiomatically. The name of the method should clearly indicate that it is a boolean-returner to the users of the method. The code: "return a > b" is more clear to the qualified reader of the code, not less. (This may be a definition of "qualified".) --RonJeffries
Personally, I've always detested the use of ?:. It's not an obvious expression, since it derives neither from English or any branch of mathematics that I'm aware of. I don't think that's a compromise -- it's an alternate solution.
To me the short form is *so* much clearer that I spent a couple of years teaching students not to do it the long way. So many students just can't understand that booleans are values just like any other type that I really wonder about their understanding of computing at all. OTOH, I spent many years doing FunctionalProgramming where if is a function defined by:
if true a b = a if false a b = bor in lambda calculus, boolean constants are functions
true = \x.\y.x false = \x.\y.yand I think after you get used to that style you are a lot more comfortable with booleans. Most normal people only encounter them in if statements. --JohnFarrell
For those of us who are not native speakers of FunctionalProgramming would you translate those definitions to prose please?
Oops, sorry (but I could say the same about Smalltalk :-). The first definition defines a function if which takes 3 arguments. The first argument is a boolean. Depending on whether that is true or false, one of the clauses is chosen. For the lambda calculus, the backslash is a lambda. "\x" means "x is a parameter". "\x.A" means a function which takes a parameter x and returns A. A function of two arguments is really just a function of one argument which returns a function of one (more) argument (CurryingSchonfinkelling). So false and true are both functions which take two arguments, true returns the first, and false returns the second. So to evaluate a conditional expression, you write it like:
(boolean-expression) (true-result) (false-result)As boolean-expression will evaluate to either true or false (although there is no type-checking), the overall result will be either true-result or false-result.
Sorry, I thought I understood it, and then I didn't. It looks to me like you defined the function called "if" as a 3-arg function. That's the part I got. Where I am confused is where you switch to pretending that the word "true" is a 2-arg function. If you mean that, then for sure you have a different understanding of the word "true" than I do. Or do you mean that "true" is both a value and a 2-arg function? And then "to evaluate a conditional" don't you have to write "if <bool-expr> <t-result> <f-result>" ? Thanks - Alistair
Tha author (JohnFarrell) switched from discussing the if form to the lambda form, where
true = \x.\y.x false = \x.\y.yso that, for example, false is a two-argument function answering its second arg, while true answers its first. As if
true ( a, b) { return a } false ( a, b) { return b }--RJ
See also LambdaCalculus
Thanks for that link. I copied the above to LambdaCalculus page, where the opening sentences indicate that there is no such thing as a constant value in l.c., so of course :-) true and false will be functions (and 2-arg functions, as the inventor of the form decided). - Alistair