Why use short-circuit code? - coding-style

Related Questions: Benefits of using short-circuit evaluation, Why would a language NOT use Short-circuit evaluation?, Can someone explain this line of code please? (Logic & Assignment operators)
There are questions about the benefits of a language using short-circuit code, but I'm wondering what are the benefits for a programmer? Is it just that it can make code a little more concise? Or are there performance reasons?
I'm not asking about situations where two entities need to be evaluated anyway, for example:
if($user->auth() AND $model->valid()){
$model->save();
}
To me the reasoning there is clear - since both need to be true, you can skip the more costly model validation if the user can't save the data.
This also has a (to me) obvious purpose:
if(is_string($userid) AND strlen($userid) > 10){
//do something
};
Because it wouldn't be wise to call strlen() with a non-string value.
What I'm wondering about is the use of short-circuit code when it doesn't effect any other statements. For example, from the Zend Application default index page:
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
This could have been:
if(!defined('APPLICATION_PATH')){
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
}
Or even as a single statement:
if(!defined('APPLICATION_PATH'))
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
So why use the short-circuit code? Just for the 'coolness' factor of using logic operators in place of control structures? To consolidate nested if statements? Because it's faster?

For programmers, the benefit of a less verbose syntax over another more verbose syntax can be:
less to type, therefore higher coding efficiency
less to read, therefore better maintainability.
Now I'm only talking about when the less verbose syntax is not tricky or clever in any way, just the same recognized way of doing, but in fewer characters.
It's often when you see specific constructs in one language that you wish the language you use could have, but didn't even necessarily realize it before. Some examples off the top of my head:
anonymous inner classes in Java instead of passing a pointer to a function (way more lines of code).
in Ruby, the ||= operator, to evaluate an expression and assign to it if it evaluates to false or is null. Sure, you can achieve the same thing by 3 lines of code, but why?
and many more...

Use it to confuse people!

I don't know PHP and I've never seen short-circuiting used outside an if or while condition in the C family of languages, but in Perl it's very idiomatic to say:
open my $filehandle, '<', 'filename' or die "Couldn't open file: $!";
One advantage of having it all in one statement is the variable declaration. Otherwise you'd have to say:
my $filehandle;
unless (open $filehandle, '<', 'filename') {
die "Couldn't open file: $!";
}
Hard to claim the second one is cleaner in that case. And it'd be wordier still in a language that doesn't have unless

I think your example is for the coolness factor. There's no reason to write code like that.
EDIT: I have no problem with doing it for idiomatic reasons. If everyone else who uses a language uses short-circuit evaluation to make statement-like entities that everyone understands, then you should too. However, my experience is that code of that sort is rarely written in C-family languages; proper form is just to use the "if" statement as normal, which separates the conditional (which presumably has no side effects) from the function call that the conditional controls (which presumably has many side effects).

Short circuit operators can be useful in two important circumstances which haven't yet been mentioned:
Case 1. Suppose you had a pointer which may or may not be NULL and you wanted to check that it wasn't NULL, and that the thing it pointed to wasn't 0. However, you must not dereference the pointer if it's NULL. Without short-circuit operators, you would have to do this:
if (a != NULL) {
if (*a != 0) {
⋮
}
}
However, short-circuit operators allow you to write this more compactly:
if (a != NULL && *a != 0) {
⋮
}
in the certain knowledge that *a will not be evaluated if a is NULL.
Case 2. If you want to set a variable to a non-false value returned from one of a series of functions, you can simply do:
my $file = $user_filename ||
find_file_in_user_path() ||
find_file_in_system_path() ||
$default_filename;
This sets the value of $file to $user_filename if it's present, or the result of find_file_in_user_path(), if it's true, or … so on. This is seen perhaps more often in Perl than C, but I have seen it in C.
There are other uses, including the rather contrived examples which you cite above. But they are a useful tool, and one which I have missed when programming in less complex languages.

Related to what Dan said, I'd think it all depends on the conventions of each programming language. I can't see any difference, so do whatever is idiomatic in each programming language. One thing that could make a difference that comes to mind is if you had to do a series of checks, in that case the short-circuiting style would be much clearer than the alternative if style.

What if you had a expensive to call (performance wise) function that returned a boolean on the right hand side that you only wanted called if another condition was true (or false)? In this case Short circuiting saves you many CPU cycles. It does make the code more concise because of fewer nested if statements. So, for all the reasons you listed at the end of your question.

The truth is actually performance. Short circuiting is used in compilers to eliminate dead code saving on file size and execution speed. At run-time short-circuiting does not execute the remaining clause in the logical expression if their outcome does not affect the answer, speeding up the evaluation of the formula. I am struggling to remember an example. e.g
a AND b AND c
There are two terms in this formula evaluated left to right.
if a AND b evaluates to FALSE then the next expression AND c can either be FALSE AND TRUE or FALSE AND FALSE. Both evaluate to FALSE no matter what the value of c is. Therefore the compiler does not include AND c in the compiled format hence short-circuiting the code.
To answer the question there are special cases when the compiler cannot determine whether the logical expression has a constant output and hence would not short-circuit the code.

Think of it this way, if you have a statement like
if( A AND B )
chances are if A returns FALSE you'll only ever want to evaluate B in rare special cases. For this reason NOT using short ciruit evaluation is confusing.
Short circuit evaluation also makes your code more readable by preventing another bracketed indentation and brackets have a tendency to add up.

Related

Ruby evaluates the default value in fetch even when key is found

h = {a: "foo"}
h.fetch(:a, h.fetch(:b))
yields key not found: :b
It seems strange that Ruby evaluates the default value even when the key is found? Is there a way around this?
Edit: Apparently this behavior falls under the paradigm of lazy vs eager evaluation. Nearly all imperative languages use eager evaluation, while many functional languages use lazy evaluation. However some languages, such as Python (which was before last week the only language I knew), have lazy evaluation capabilities for some operations.
It seems strange that Ruby evaluates the default value even when the key is found? Is there a way around this?
The overwhelming majority of mainstream programming languages is strict, i.e. arguments are fully evaluated before being passed. The only exception is Haskell, and calling it mainstream is a bit of a stretch.
So, no, it is not really "strange", it is how (almost) every language works, and it is also how every single other method in Ruby works. Every method in Ruby always fully evaluates all its arguments. That is, why, for example defined? and alias cannot be methods but must be builtin language constructs.
However, there is a way to delay evaluation, so to speak, using blocks: the content of a block is only evaluated each time it is called. Thankfully, Hash#fetch does take a block, so you can just use
h.fetch(:a) { h.fetch(:b) }
If you want the computation to only run if the key is not found, you can use the alternate form of fetch which accepts a block:
h.fetch(a) { h.fetch b }
I didn't actually know this was the case but I had a hunch and tried it and it worked. The reason I thought to try this was that something similar can be done in other methods such as gsub, i.e.
"123".gsub(/[0-9]/) { |i| i.to_i + 1 } == "234"
You could use the || operator instead, since it's lazy evaluated by design.
For example the following code where Nope is not defined does not throw an error.
{ a: "foo" }[:a] || Nope
However the fetch version will throw an error.
{ a: "foo" }.fetch(:a, Nope)
Personally I prefer how fetch is designed because it wont hide a bug in the default value.
However, in cases where I would rather not evaluate a default statement, then I would definitely reach for the || operator before doing something in a block or a lambda/proc.

TCL how to require both operands to determine result in IF statement

new to TCL and running into a short circuit issue it seems. Coming from vbscript, I'm able to perform this properly, but trying to convert to a TCL script I'm having issues with the short circuit side effect and have been trying to find the proper way of doing this.
In the following snippet, I want to execute "do something" only if BOTH sides are true, but because of short circuiting, it will only evaluate the second argument if the first fails to determine the value of the expression.
if {$basehour != 23 && $hours != 0} {
do something
}
Maybe I'm not searching for the right things, but so far I've been unable to find the solution. Any tips would be appreciated.
The && operator always does short-circuiting in Tcl (as it does in C and Java and a number of other languages too). If you want the other version and can guarantee that both sub-expressions yield booleans (e.g., they come from equality tests such as you're doing) then you can use the & operator instead, which does bit-wise AND and will do what you want when working on bools. If you're doing this, it's wise to put parentheses around the sub-expressions for clarity; while everyone remember the precedence of == with respect to &&, the order w.r.t. & is often forgotten. (The parentheses are free in terms of execution cost.)
if {($basehour != 23) & ($hours != 0)} {
do something
}
However, it's usually not necessary to do this. If you're wanting an AND that you're feeding into a boolean test (e.g., the if command's expression) then there's no reason to not short-circuit, as in your original code; if the first clause gives false, the second one won't change what value the overall expression produces.

Ruby case/when vs if/elsif

The case/when statements remind me of try/catch statements in Python, which are fairly expensive operations. Is this similar with the Ruby case/when statements? What advantages do they have, other than perhaps being more concise, to if/elsif Ruby statements? When would I use one over the other?
The case expression is not at all like a try/catch block. The Ruby equivalents to try and catch are begin and rescue.
In general, the case expression is used when you want to test one value for several conditions. For example:
case x
when String
"You passed a string but X is supposed to be a number. What were you thinking?"
when 0
"X is zero"
when 1..5
"X is between 1 and 5"
else
"X isn't a number we're interested in"
end
The case expression is orthogonal to the switch statement that exists in many other languages (e.g. C, Java, JavaScript), though Python doesn't include any such thing. The main difference with case is that it is an expression rather than a statement (so it yields a value) and it uses the === operator for equality, which allows us to express interesting things like "Is this value a String? Is it 0? Is it in the range 1..5?"
Ruby's begin/rescue/end is more similar to Python's try/catch (assuming Python's try/catch is similar to Javascript, Java, etc.). In both of the above the code runs, catches errors and continues.
case/when is like C's switch and ignoring the === operator that bjhaid mentions operates very much like if/elseif/end. Which you use is up to you, but there are some advantages to using case when the number of conditionals gets long. No one likes /if/elsif/elsif/elsif/elsif/elsif/end :-)
Ruby has some other magical things involving that === operator that can make case nice, but I'll leave that to the documentation which explains it better than I can.

style opinion re. empty If block

I'm trying to curb some of the bad habits of a self-proclaimed "senior programmer." He insists on writing If blocks like this:
if (expression) {}
else {
statements
}
Or as he usually writes it in classic ASP VBScript:
If expression Then
Else
statements
End If
The expression could be something as easily negated as:
if (x == 0) {}
else {
statements
}
Other than clarity of coding style, what other reasons can I provide for my opinion that the following is preferred?
if (x != 0) {
statements
}
Or even the more general case (again in VBScript):
If Not expression Then
statements
End If
Reasons that come to my mind for supporting your opinion (which I agree with BTW) are:
Easier to read (which implies easier to understand)
Easier to maintain (because of point #1)
Consistent with 'established' coding styles in most major programming languages
I have NEVER come across the coding-style/form that your co-worker insists on using.
I've tried it both ways. McConnell in Code Complete says one should always include both the then and the else to demonstrate that one has thought about both conditions, even if the operation is nothing (NOP). It looks like your friend is doing this.
I've found this practice to add no value in the field because unit testing handles this or it is unnecessary. YMMV, of course.
If you really want to burn his bacon, calculate how much time he's spending writing the empty statements, multiply by 1.5 (for testing) and then multiply that number by his hourly rate. Send him a bill for the amount.
As an aside, I'd move the close curly bracket to the else line:
if (expression) {
} else {
statements
}
The reason being that it is tempting to (or easy to accidentally) add some statement outside the block.
For this reason, I abhor single-line (bare) statements, of the form
if (expression)
statement
Because it can get fugly (and buggy) really fast
if (expression)
statement1
statement2
statement2 will always run, even though it might look like it should be subject to expression. Getting in the habit of always using brackets will kill this stumbling point dead.

defensive coding practices [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Ever since I first wrote
if ($a = 5) {
# do something with $a, e.g.
print "$a";
}
and went through the normal puzzling session of
why is the result always true
why is $a always 5
until I realized, I'd assigned 5 to $a, instead of performing a comparison.
So I decided to write that kind of condition above as
if (5 == $a)
in other words:
always place the constant value to the left side of the comparison operator, resulting in a compilation error, should you forget to add the second "=" sign.
I tend to call this defensive coding and tend to believe it's a cousin to defensive-programming, not on the algorithmic scale, but keyword by keyword.
What defensive coding practices have you developed?
One Week Later:
A big "thank you" to all who answered or might add another answer in the future.
Unfortunately (or rather fortunately!) there is no single correct answer. For that my question was to broad, asking more for opinions or learnings of experience, rather than facts.
Always use braces:
if(boolean)
oneliner();
nextLineOfCode();
is not the same as:
if(boolean)
{
oneliner();
}
nextLineOfCode();
If oneliner() is a #defined function, and it isn't defined then your next line of code suddenly becomes subject to the if(). Same thing applies to for loops etc. With braces then the next piece of code never unintentionally becomes conditional on the if/for etc.
The top 3 defensive coding practices I employ are
unit testing
unit testing
unit testing
There is no better defense for the quality of your code than a good unit test to back you up.
This is a simple and obvious one, but I NEVER EVER NEVER repeat the same string constant twice in my code, cause I KNOW that if I do I will be spelling one of them wrong :) Use constants, people!
Always put curly braces after an if/for/while ... even if there's only one single statement after. BTW D. Crockford thinks it's better too: Required blocks
When comparing a string with a constant, write
if ("blah".equals(value)){}
instead of
if (value.equals("blah")){}
to prevent a NullPointerException. But this is the only time I use the suggested coding-style (cause "if (a = 1)..." is not possible in Java).
One of the things I always try to remember when I am in the Javascript world is to always start the return value of a function on the same line as the return key word.
function one(){
return {
result:"result"
};
}
function two(){
return
{
result:"result"
};
}
These 2 functions will not return the same value. The first function will return an Object with a property results set to "result". The second function will return undefined. It's a really simple mistake and it happens because of Javascript's over-zealous Semi-Colon Insertion strategy. Semi-colons are semi-optional in Javascript and because of this the Javascript engine will add semi-coons where it thinks it's should be. Because return is actually a valid statement a semi-colon will be inserted after the return statement and the rest of the function will essentially be ignored.
From my blog:
Think positive and return early plus avoid deep nesting. Instead of
if (value != null) {
... do something with value ...
}
return
write
if (value == null) {
return
}
... do something with value ...
Avoid "string constants" (i.e. the same text in quotes in more than one place). Always define a real constant (with a name and an optional comment what it means) and use that.
Personally, I dislike this defensive style, it makes the code hard ro read.
VC compiler warning level 4 will spot this (possible) error.
"warning C4706: assignment within conditional expression"
You can enable just this specific compiler warning, at any level:
#pragma warning(3,4706)
Always initialize variables
Use const wherever I can (without using mutable)
Avoid bare dynamic allocation of memory or other resources
Always use curly braces
Code use-cases and tests for any class before coding implementation
Turn on as many useful warnings as I can (-Wall -Wextra -ansi -pedantic -Werror at a minimum)
Use the simplest tool that solves the problem (in my current environment, that's bash -> grep -> awk -> Python -> C++).
I stopped using languages where you can do
if a = 5: print a
This has saved me tons of headaches =).
On a more serious note... I now always write the curly braces right after I write my ifs and for loops, and then fill them in afterwards. This makes sure my brackets are always aligned.
Returning a copy of a mutable object, i.e. a copy of an array, not the mutable object itself.
Couple things:
Yes, the 1-line blocks. Use the braces... heck, most good IDE's will make em for you.
Comment your code after you write it, or re-read your comments if you did it ahead of time. Make sure your code still does what the comments say.
Unit testing is a great fallback to re-reading your code.
Always log an exception... or, NEVER catch an exception without saying so, at least in debug.
Avoid unnecessary test.
Example
if(bool == true)
Pointer checks if(pointer)
EDIT:
if(pointer) is not readable so nowadays I prefer if(NULL != pointer)
Installed Resharper ;)
Then I don't need to write "5 == a" to get warned if I did something wrong :)

Resources