General question about "continue" vs "nested ifs"
Community Forums/General Help/General question about "continue" vs "nested ifs"
| ||
Hi all, This is a general question, I'm not looking at optimisation issues just some general thoughts on the difference between the two approaches. I have a lot of code in a database package I work with that often can be written either as loop here: if some statement = true continue endif if another statement = true continue endif do processing end loop alternatively loop here: if some statement = true else if another statement = true else do processing endif endif end loop Usually the programs are pretty simple, the logic is pretty clear and easy to understand, but I'm not sure what the advantage is of doing it one way over the other in this instance. I can see for a more complex case it is useful to use one over the other but for something as simple as this - what differences does it make internally? Is it just a stylistic choice - aesthetic only? EDIT - I know I can make this more complex again by putting the whole if statement on one line in some cases - but not all simply because of the way the programs work... |
| ||
There's also ElseIf:While Not whatever If a=True Then Print "A is true" ElseIf b=True Then Print "whatever" Else Print "none of the above" EndIf Wend |
| ||
Are you using a Blitz product? what language are you in? If it's another language, try some hocus-pockery such as this... Switch(True) { Case (boolean expression 1): Case (boolean expression 2): Case (boolean expression 3): [...] Case (boolean expression n): Continue; Break; }Then all expressions give the same 'continue' result, but you're still individually checking each. @Yasha: Oh, I see what you mean. I'll leave it there so we can have a laugh at it. |
| ||
Is it just a stylistic choice - aesthetic only? Pretty much. Go with the one that makes it most visually obvious what's happening. For shortish blocks, that's probably the second one (at least... rewritten to test against "false"): if in one glance you can see that "do processing" is safely protected inside an if block, you know how the conditions will affect its execution. If on the other hand "do processing" is quite a long and possibly deeply-nested bit of code that doesn't cleanly fit on the screen or whatever you can take in in one glance, and you have several guard conditions you want to check all in a row, perhaps it's better to separate the action from the checks and think about them separately. It might make the code more readable if a single large block is not indented for little good reason, especially if there's no alternate path. (On the other hand, often if you have a block that breaks the visual flow in this way, it's a sign you should consider factoring some of it out and make the loop body smaller.) The correct one is the one which makes it less likely that you'll make a mistake when you see the code in context. For some code one will be clearer than the other, but they do the same thing. @Kryzon: most of the languages that call it "switch" don't allow you to put expressions on the cases, only constants. They want you to use "if" for that. |
| ||
If you're in blitz, there's no need for the EndIf (only required for IFs with more than one line). You can then write: If some statement Then Continue If another statement Then Continue If another another statement Then Continue If another another another statement Then Continue ;Do processing.Single line IFs, completely unrelated to each other. |
| ||
Thanks Yasha..I was mainly interested just in the thoughts behind the two stylistic approaches which you've answered nicely...Kryzon - language was not important here just the methodology so it was pseudocode... |
| ||
If the "variable" you are checking is received using a function/method-call, it will be better to use the switch/select-approach as the variable is only set once in the header of that block. If you use the "if"-approach you will then most likely have to cache the output using a local variable.if myobject.GetType() = "circle" then XY;continue if myobject.GetType() = "rectangle" then XY;continue if myobject.GetType() = "triangle" then XY;continue -> in the case of triangle the GetType() thing would be called 3 times. Select myobject.GetType() case "circle" XY;break case "rectangle" XY;break case "triangle" XY;break EndSelect -> GetType() is only evaluated once (but also checked 3 times in the case of "triangle"). So the Select-approach saves the caching in a local variable in the case of a functioncall which has to get compared. To add something to Kryzon's post: As soon as only "one" thing is compared to a may-be-growing-variety a Switch/Select-approach is most likely the better option (imagine EVENT-Type-Checks or other code using different CONST-values to distinguish things). It is also shorter to use the Switch/Select-blocks when doing things like: If myobject.GetType() = "triangle" or myobject.GetType() = "rectangle" or myobject.GetType() = "octagon" or myobject.GetType() = "spiral" print "not a circle" else print "no triangle, rectangle, octagon or spiral" endif Select myobject.GetType() case "triangle", "rectangle", "octagon", "spiral" print "not a circle";break default print "no triangle, rectangle, octagon, spiral" End Select Readability is improved the longer variablenames or object-chaining gets (as soon as the 80chars per line is reached one should linebreak and this makes the formatting even more work). I know Matty asked about the "methodology" but the readability is also depending on the structure your code uses. bye Ron. |
| ||
If you're in blitz, there's no need for the EndIf (only required for IFs with more than one line). There's no need for "Then" either.You can then write: If some statement Then Continue If another statement Then Continue If another another statement Then Continue If another another another statement Then Continue ;Do processing. Single line IFs, completely unrelated to each other. If some statement ContinueBut I find every shortcut taken makes your code less readable. I generally prefer Select/Case as it makes for more readable code. One neat little 'feature' of Select/Case is the ability to do this (which is really just expanding on what Kryzon said): Select True Case X >= 0 And X <= 5 'do something Case X >= 6 And X <= 10 'do something else End Select As far as I know, you can do that in any BRL product (don't know about Monkey), and since this is the Blitz site, it's definitely worth a mention. |
| ||
Several If Endif do not produce the same result than If Elseif Else Endif. See : |
| ||
Several If Endif do not produce the same result than If Elseif Else Endif. It's not meant to (is that what you were saying?)In a bunch of If/EndIfs, every one gets processed, whereas using If/ElseIf/EndIf, only the first one that returns True gets processed - the rest are skipped. |
| ||
loop here: if some statement = true continue endif if another statement = true continue endif do processing end loop I would do this as loop here: If not some statement and not another statement do processing Endif end loop Edit: Had it right the first time. |
| ||
It's not meant to (is that what you were saying?) Gfk>>Yes. This : if some statement = true ;continue endif if another statement = true ;continue endif Will not produce the same results as this : if some statement = true ; else if another statement = true ; else ;do processing endif endif "some statement" may be true and "another statement" may be true, and with the first code, the code concerning the "another statement" will be processed. |
| ||
@RemiD: actually they will do exactly the same thing. The whole point of the OP was to ask about the Continue command. Since Continue will jump back to the start of the loop, if the first condition is true the second will never be tested no matter whether it's in an Else block or not, because the presence of Continue is manually re-creating the functionality of the Else branch. (Note: Continue does not exist in B3D, so if you're not familiar with BlitzMax or C, this code may not do what you think it does!) |
| ||
The whole point of the OP was to ask about the Continue command. Since Continue will jump back to the start of the loop, if the first condition is true the second will never be tested no matter whether it's in an Else block or not, because the presence of Continue is manually re-creating the functionality of the Else branch. (Note: Continue does not exist in B3D, so if you're not familiar with BlitzMax or C, this code may not do what you think it does!) Ok, that is why, i thought continue was a way to say continue to do this and that. Sorry, forget about what i have explained. |