if (x > y) {
return x;
} else {
return y;
}
if (x > y) {
return x;
}
return y;
return (x > y) ? x : y;
The logic would be convoluted if you are going through extra hoops in order to write your logic like this, making the flow of the application unclear. For some things, an else branch ends up just being easier to deal with. This is especially true in languages like Rust, where if/else is an expression, leading to the following construct being used often (although usually with more complicated content): let max = if (x > y) {
x
} else {
y
};
Note that "max" is immutable despite the conditional assignment due to the if being used as an expression.If it's a single line of return in both branches, then a ternary expression is usually going to be ideal instead.
I do not agree with the conclusions you draw at all, but it is hard to continue the discussion without examples. There are definitely cases where an else clause is the natural choice, but I believe that these are in the minority.
But that max function should have an else statement since it's part of the logic. Less code doesn't always make it more concise. If there's a more complicated logic, then it'd actually be harder to understand at a glance.
Nothing about early return indicates a special case, but rather just indicate that a conclusion has been reached. A few examples:
1. A function that compares two arrays, and first checks if they are null or if their lengths differ before checking their individual elements, and potentially recursing. The early returns are likely to be the hottest section of the function, with the element checking being the special case.
2. A function that searches a list or tree for a node that matches a set of conditions. All but at most one run will use the early returns, making the corpus of the function the special case.
3. A function that does some processing, with fast paths that handle the vast majority of data, but a slow path for when the fast paths do not apply. The fast path is an early return, but the slow path is the special case.
In other words, I believe that it is incorrect to consider an early return to be a special-case, and interpreting code like so might result in misunderstandings. You should look at the condition to see if it is a special case. The only thing an early return indicate is that the return value has been decided, and no further processing is needed.I still think that all my examples communicate the exact same to the reader.
foo(things) {
stuff = do_work(things);
if (stuff) {
return a;
} else {
return b;
}
}
into foo(things) {
stuff = do_work(things);
if (stuff) {
return a;
}
return b;
}
in code reviews.Ok, I really wonder if in this special case the logic just looks _odd_ because of bracing styles. (bear with me)
This is very easy to understand, where as the parent example, not as much.
fun max(a, b)
{
if a > b
{
return a
}
return b
}A max function is one of those rare moments where a ternary statement just seems right, but it's an admittedly simple example.
I think this is interesting. I wonder if our personal experiences with how we learned programming, maybe first languages or first teachers or jobs, etc... would effect our perceptions on logic flow.
I simple don't see anything unusual about the logic flow in the example. It's a simple if/else - return with less cruft to me.
The control flow isn't confusing either way, and some language linters will insist against if/else in this example, but I see the if/else approach with slightly more clarity. In general, though, I'm a big proponent of early return.