I'm not sure whether this is a good question, but this was just bothering me from a theoretical perspective. Can anyone explain why some languages like php have an explicit elseif/elif while others like c++ or java make do with just if and else. It would seem that less keywords to remember is preferable to more keywords. Is there any benefit to having an elseif statement available ?
P.S. I am writing a book on programming languages and I am collecting opinions on language design theory
EDIT: Thank you for pointing this out. I realize now that in Python specifically it is important due to the whitespace / indentation rule. I have changed my example from Python to PHP.
In my opinion, elseif avoids excessive indentations as #kalhartt commented, for python (mandatory) and for other languages like c++ (optional but customary).
But more importantly, I think elseif is a helpful feature that hints about the workflow in the sense that,
1) there is nothing else in the else branch, i.e. we don't have complicated structures like
if (A) {
}
else {
if (B) {...} else { ... }
i++;...
}
2) it helps to create a linear structure similar to the switch statement, where
switch (a) {
case 1:
...
case 2:
...
case 3
...
default:
}
maps to:
if (a == 1) {
}
elseif (a == 2) {
}
elseif (a == 3) {
}
else{
}
The if ... elseif ... form is a bit more verbose, but more powerful, i.e. with less stringent requirement on the conditional for each "case". For example, you can use
elseif (a > 3 && a < 7)
In my opinion, the benefit is to simplify code. Say there are a list of choices and you are using if statements to do an action per each different choice. It is easier to use elseif statements to narrow down the choices. Also, it has greater readability.
Related
I'm attempting to go through a large number bitwise tests, 32 to be exact, where there could be multiple matches. The only method I can think of that would work is to use a whole long list of if statements, e.g.
$test = 3;
if(($test & 1) == 1) {
do something...
}
if(($test & 2) == 2) {
do something else...
}
The other possibility I was thinking of to cut down on the code, although probably not by much is a switch statement. That said, I'm not even sure if what I am thinking of will even work:
$test = 3;
switch($test) {
case ((1 & $test) == 1):
do something...
break;
case ((2 & $test) == 2):
//Will this run?
do something else...
break;
}
Will the break end the switch? Or will the switch continue and each case run that the bitwise operation returns true?
I ask because my actual program will have 32 different tests, and I don't want to write all 32 just to find it doesn't work and Google hasn't turned up anything on this.
If this doesn't work is there a solution that will, or am I relegated to a large number of if statements?
No this is not the case. Only one of the switch cases will run in your example. As soon as break is encountered the switch processing ends. Only one branch will match. In PHP I think (but you might want to double check) the first matching case will run.
With multiple possible matches you will need to use a set of if statements (note do not use if...elseif)
I would convert to
if($test & 1) {
// do stuff
}
if(test & 2) {
// do stuff
}
Well first, using switch with int this way is not really recommended. It's not a good practice / not really readable / not comfortable. I would say it does not even work, although I have a doubt now... depending on versions and stuff, I'm not aware enough of these things.
Then, to answer your question, you only go inside the first matching case... then the break makes you leave the switch. However, you can omit the break and it will go through the second case.
Anyway, you should make more use of OOP to characterize better what you intend to do, and things will probably get more simple and clearer.
What is the best practice to end an if...else statement without an else condition? Consider the following code:
$direction = $_POST['direction']; //Up or down
if ($direction == "up") {
code goes here...
}
elseif ($direction == "down") {
code goes here...
}
else {
//do nothing?
}
As you can see, there's only 2 condition; either up or down and the else statement doesn't really have a purpose unless you want it to display an error message.
Most of the time I see programmers simply put the else condition there but inserts a comment instead of any working code like this.
else {
//error messages goes here...
}
or just assume if it's not 'up' then everything else should be 'down' since there's only 2 condition. If a user inputs 'left' or 'right', it would still be considered as 'down'. I think this is somewhat inappropriate.
if ($direction == 'up') {
code goes here...
}
else {
code goes here...
}
I know that PHP would still work if we put if without else condition. But what if there is an elseif condition? In cases like these, what is the best practice if we want to maintain a strict if...else statement if we do not want to include any error messages or have any else conditions?
Thanks in advance.
There is no if...else statement.
There is only an if statement that can be extended with else and elseif operators.
So, the best practice on if statement without else condition is an if statement without an else condition:
if (condition) {
//some code
}
Frankly, there is no best practice. The best practice is just one that follows the program logic.
That's all
Don't write empty elses. This would just clutter up the code, and it's perfectly obvious what you meant.
In many cases, you can actually use the switch statement:
switch ($_POST['direction') {
case 'up':
// code ...
break;
case 'down':
// code ...
break;
default: // else
throw new Exception('Invalid direction value');
}
I think that if there's nothing to do on else, then there's no need for else block to exist in code. If else block is included, it means that it has a purpose to be there, so the code is incomplete yet, if it is empty.
This isn't something that can take a definite answer. Here's my take, it would be interesting to see what other opinions exist.
Scenario 1: Testing a boolean condition
This is the simplest case:
if (condition) {}
else {}
Specifying a condition as else if would be redundant, and it's really obvious to the reader what the code does. There is no argument for using else if in this case.
Scenario 2: Testing for a subset of infinite states
Here we are interested in testing for conditions A and B (and so on), and we may or may not be interested in what happens if none of them holds:
if (conditionA) {}
else if (conditionB) {}
else {} // this might be missing
The important point here is that there isn't a finite number of mutually-exclusive states, for example: conditionA might be $num % 2 == 0 and conditionB might be $num % 3 == 0.
I think it's natural and desirable to use a reasonable amount of branches here; if the branches become too many this might be an indication that some judicious use of OO design would result in great maintainability improvements.
Scenario 3: Testing for a subset of finite states
This is the middle ground between the first two cases: the number of states is finite but more than two. Testing for the values of an enum-like type is the archetypal example:
if ($var == CONSTANT_FOO) {}
else if ($var == CONSTANT_BAR) {} // either this,
else {} // or this might be missing
In such cases using a switch is probably better because it immediately communicates to the reader that the number of states is finite and gives a strong hint as to where a list of all possible states might be found (in this example, constants starting with CONSTANT_). My personal criteria is the number of states I 'm testing against: if it's only one (no else if) I 'll use an if; otherwise, a switch. In any case, I won't write an else if in this scenario.
Adding else as an empty catch-errors block
This is directly related to scenario #2 above. Unless the possible states are finite and known at compile time, you can't say that "in any other case" means that an error occurred. Seeing as in scenario #2 a switch would feel more natural, I feel that using else this way has a bad code smell.
Use a switch with a default branch instead. It will communicate your intent much more clearly:
switch($direction) {
case 'up': break;
case 'down': break;
default: // put error handling here if you want
}
This might be a bit more verbose, but it's clear to the reader how the code is expected to function. In my opinion, an empty else block would look unnatural and puzzling here.
I sometimes do it like this. I'm not worried that "left"
is interpreted as "down" because I always validate my input, in this case with preg_match('{^up|down$}', $direction). Inarguably a switch is more appropriate... but I dislike the verbose syntax.
if ($direction == "up")
{
// code goes here...
}
else //if ($direction == "down")
{
// code goes here...
}
I try not to write else. Ever. In my experience, using else results in less readable logic, especially when if/elses are being nested.
For assigning a var to either true or false (or any other simple this-or-that value), I always use:
$varx = false;
if ($my_codition_here === true) {
$varx = true;
}
When I have a bigger chunk of logic that you might consider "belongs" in the if/else, I make sure to structure my code so that if the condition is met, the function terminates, usually by returning:
if ($my_codition_here === true) {
// A reasonable amount of logic goes here
return $the_result_up_untill_here;
}
// All logic that would have been "else" goes here.
return $the_result_up_untill_here;
As phihag mentioned; use a switch statement when you consider elseif.
And as Your Common Sense already said, there is no best practise, but there are good practises, and I think this is one.
when I use some nested if / else statements, sometimes I get confused if my code logic corresponds to my original idea. I use some simple procedural code, so how can I train my understanding?
Try to split your code up into functions. If you have deeply nested if/else statements then you can probably create well-named functions for both the "if" tests and the resulting logic. For example, change:
if ($something == "a" && $somethingElse == "b") {
// code
}
else if ($whatever > 4) {
// more code
}
else {
// yet more code
}
to
if (condition1True()) {
handleCondition1();
}
else if (condition2True()) {
handleCondition2();
}
else {
handleDefaultCondition();
}
Making your code read more like English means you can more easily understand how it works. You can also split your functionality so that each function only needs to do something simple then compose those functions into higher-level behaviour.
EDIT: Regarding comments, I tend to go for well-named functions and variables rather than copious commenting. If you can read the code without comments then that's ideal, but obviously you will still need comments sometimes. Definitely worth writing Javadoc-style comments for each function detailing the meanings of the arguments and return value, but inline comments in the code are sometimes more hindrance than help.
Comments! Write your original ideas in comments above each if/else block, and then make sure the conditionals for each block match the pseudo code you outlined in the comment. If they do, go back after you're done an re-read the comments - if the logic in them still seems valid, then there's a good chance your code will be good to go. I find it much easier to read comments outlining what a conditional does than to decipher each conditional on the fly. Of course, that means keeping comments up to date as well.
One of the best programmers I've ever met stubbed out functions with comments detailing how the function was supposed to work. He could read it back in plain English to make sure it made sense, and then implementation was, as he said, a simple matter of translation. This may not be for everyone, but it may help you keep focused.
Simplify complex conditionals and inner logic with appropriate function calls. Refactor you code to make it more clear, into small chunks. Use switch statements if appropriate, polymorphism if dealing with similar objects, etc.
Seeing some sample code would help give a more appropriate example, but consider the following contrived example:
if($a.isAnimal && $a.animalIsAlive){
if($a.isDog){
if(!$a.hasHadWalk && date('h') > 6 && date('h') < 20){
getLeash();
attachLeashToCollar();
putOnShoes();
...
}else{
//doNotWalk
}
}else{
//some other stuff here
}
}
could be refactored into
if(canBreathe($a)){
if($a.isDog){
if(shouldWeWalk($a)){
walkDog();
}
}else{
//some other stuff here
}
}
function canBreathe($a){
return $a.isAlive && $a.isAnimal;
}
function walkDog(){
getLeash();
attachLeashToCollar();
putOnShoes();
...
}
function shouldWeWalk($a){
return (!$a.hasHadWalk && date('h') > 6 && date('h') < 20);
}
First make a copy of the PHP file ;-)
Then try to refactor some of the deeply nested conditionals code blocks into their own functions and choose the name of these functions carefully.
That will force you to think about the code.
I think
if (condition1True()) {
handleCondition1();
}
else if (condition2True()) {
handleCondition2();
}
else {
handleDefaultCondition();
}
this variant is more preferable, because of better understanding what program doing.
I've seen a lot of code recently formatted as the following:
A:
if ($var=='test'){
$var=Foo('blah'.$var1);
}else{
// do something
}
Personally I don't like it and would prefer it as:
B:
if ($var == 'test') {
$var = Foo('blah' . $var1);
} else {
// do something
}
I think it's much more readable (note the addition of spaces).
Is there a general preference in the community or is one way better than another?
The most important thing is to follow a standard and stick to it.
That said maybe you can follow Zend's Framework standards and they use spaces. Check C.4.6.
if ($a != 2) {
$a = 2;
}
Hope it helps!
+1 for spaces :)
but that's just my own standard, as long as you are consistent and your code is clear, it should be okay
PHP is much like C in its syntax. As I use both, I tend to follow the same style.
For instance, keywords vs functions:
if ($foo) {
vs
MySuperDuperFunction($foo);
Then you come to a question of indentation:
switch ($bar) {
case CONSTANT:
more_code();
.. is much easier to read as
switch ($bar) {
case CONSTANT:
more_code();
This indicates that the switch and the case are on the same level, which they are. It also helps avoid crazy indentation in yet-to-be-optimal switches.
Your style should illustrate the syntactic sugar of the language you are using. This gets strange with PHP as well as C, because both have forgiving parsers.
If you write something like this:
if($a==2&&b==1&&c>3)
{
I'm going to hunt you down and demand that you pay for my aspirin. The same would go for this:
if (
a==2
&&
b==1
&&
c>3
)
{
... For God sakes man, its not LISP!
It's a matter of convetions that are stablished within your team.
The most famous conventions are Zend Framework and PEAR. You can also create your own, just make sure it is readible.
Personally, I use spaces.
The general advice would be to standardize the code formating, so it meets some best practices, and is widely known, instead of inventing something custom.
PSR-2, the coding style guide would be the best well known approach, accepted by many. here are facts, why it's good to keep the code formatting.
I've heard rumors that PHP is planning on introducing a "goto" command. What is it supposed to be doing?
I've tried searching a bit, but haven't found anything awfully descriptive. I understand that it won't be a "GOTO 10"-like command...
They are not adding a real GOTO, but extending the BREAK keyword to use static labels. Basically, it will be enhancing the ability to break out of switch nested if statements. Here's the concept example I found:
<?php
for ($i = 0; $i < 9; $i++) {
if (true) {
break blah;
}
echo "not shown";
blah:
echo "iteration $i\n";
}
?>
Of course, once the GOTO "rumor" was out, there was nothing to stop some evil guys to propagate an additional COMEFROM joke. Be on your toes.
See also:
http://www.php.net/~derick/meeting-notes.html#adding-goto
I'm always astonished at how incredibly dumb the PHP designers are.
If the purpose of using GOTOs is to make breaking out of multiply nested
loops more efficient there's a better way: labelled code blocks
and break statements that can reference labels:
a: for (...) {
b: for (...) {
c: for (...) {
...
break a;
}
}
}
Now is is clear which loop/block to exit, and the exit is structured;
you can't get spaghetti code with this like you can with real gotos.
This is an old, old, old idea. Designing good control flow management
structures has been solved since the 70s, and the literature on all this
is long since written up. The Bohm-Jacopini theorem showed that
you could code anything with function call, if-then-else, and while loops.
In practice, to break out of deeply nested blocks, Bohm-Jacopini style
coding required extra boolean flags ("set this flag to get out of the loop")
which was clumsy coding wise and inefficient (you don't want such flags
in your inner loop). With if-then-else, various loops (while,for)
and break-to-labelled block, you can code any algorithm without no
loss in efficiency. Why don't people read the literature, instead
of copying what C did? Grrr.
Granted, I am not a PHP programmer, and I don't know what PHP's exact implementation of GOTO will look like, but here is my understanding of GOTO:
GOTO is just a more explicit flow control statement like any other. Let's say you have some nested loops and you only need to find one thing. You can put in a conditional statement (or several) and when conditions are met properly, you can use a GOTO statement to get out of all the loops, (instead of having a 'break' statement at each level of nesting with a conditional statement for each. And yes, I believe the traditional implementation is to have named labels that the GOTO statement can jump to by name. You can do something like this:
for(...) {
for (...) {
for (...) {
// some code
if (x) GOTO outside;
}
}
}
:outside
This is a simpler (and more efficient) implementation than without GOTO statements. The equivalent would be:
for(...) {
for (...) {
for (...) {
// some code
if (x) break;
}
if(x) break;
}
if(x) break;
}
In the second case (which is common practice) there are three conditional statements, which is obviously slower than just having one. So, for optimization/simplification reasons, you might want to use GOTO statements in tightly nested loops.
In the example given by steveth45 you can use a function instead:
function findItem(...) {
for (...) {
for (...) {
for (...) {
if (x) {
return theItem;
}
}
}
}
}
// no need for label now
theItem = findItem(a, b, c);
It looks like it's currently in PHP 5.3, but is not fully documented yet. From what I can tell it shares its goto syntax with C, so it should be easy to pick up and use. Just remember Dijkstra's warning and use it only when necessary.
#steveth45
My rule of thumb is that if you have nested code more than 3 levels deep, you are doing
something wrong.
Then you don't have to worry about using multiple break statements or goto :D
there is a goto in php -> http://php.net/manual/en/control-structures.goto.php, but i wouldn't use it, just write normal code...