4 ms·
Except where writing negative conditionals are clearer. For example turning: if(a) { if(b) { if (c) { // Do something. } } } I
by VBprogrammer 13y ago
Except where writing negative conditionals are clearer. For example turning:
if(a) {
if(b) {
if (c) {
// Do something.
}
}
}
Into:
if(!a) {
} elseif(!b) {
} elseif(!c) {
} else {
// Do something.
}
- meatcar 13y agoOr if (a && b && c) { // Do something. }
- jhaywood 13y agoUnless they actually are a VB programmer and And doesn't short circuit.
- joeframbach 13y ago`AndAlso` short circuits.
- jhaywood 13y agoFantastic! If only I could write Excel macros in vb.net
- VBprogrammer 13y agoYes, the that was a very simple example.
- Double_Cast 13y agoiirc, robotics commonly uses something similar called ladder logic.
- ChuckMcM 13y agoInterestingly I've been going back and forth on this lately. I have been playing around with SD cards on the STM32F4 and a typical SD Card transaction consists of 3 to 10 commands which, if any one fails, the transaction fails. I'm currently using negative conditionals of the form "Not Error" (the Error test is an affirmative, and so that seems ok to me) A typical sequence is like the one to set the bus width. err = sdio_select(rca); if (! err) { err = sdio_command(55, rca << 16); if (! err) { err = sdio_command(6, 2); } } sdio_deslect(); return err; I had originally done it the other way err = sdio_select(rca); if (err) { return err; } err = sdio_command(55, rca << 16); if (err) { sdio_deselect(); return err; } err = sdio_command(6, 2); sdio_deselect(); return err; I find the first form more readable. It also generates fewer branches in the generated code. The sample code I first looked at was doing Goto's to the exit code (deselect/return error) which was unacceptable :-). In the original article the confusion arose around negative test cases and then testing for them negatively (double negatives) which I think are always bad from a readability point of view.
- krzysz00 13y agoNot to drag the thread off topic, but this seems like the kind of situation where a version of Haskell's Maybe or Either monads might come in handy, so you could write: do command1 command2 ... and have the failures propagate automatically.
- nitrogen 13y agoWhat I've found myself doing in such cases is adding a function that processes multiple commands and indicates an error if any one of the commands failed (sdio_batch could be a varargs function): struct sdio_cmd { enum { SDIO_SELECT, SDIO_COMMAND } cmd; int reg; // Guesses at suitable names without int val; // knowing anything about SDIO } int sdio_batch(int count, ...); err = sdio_batch(3, &(struct sdio_cmd){ SDIO_SELECT, .val = rca }, &(struct sdio_cmd){ SDIO_COMMAND, 55, rca << 16 }, &(struct sdio_cmd){ SDIO_COMMAND, 6, 2 }, ); I've been doing it in Ruby with network remote procedure calls, where it's not quite as ugly to use inline lists and variable argument counts as it is in C, and where branch count isn't quite as important. The sample code I first looked at was doing Goto's to the exit code (deselect/return error) which was unacceptable :-). What's so bad about a little goto between friends?
- ChuckMcM 13y agoThis is a nice structure, It also suggests something like closures where you inverse stacked the functions and did something like: int do_command(sdio_command_chain *cmd) { int err = 0; if (cmd->next) { err = do_command(cmd->next); } return (err) ? err : call_command(cmd->parms); } Thanks for that!
- Roboprog 13y agoI actually prefer your second form: return as soon as you know you are done in the function/method -- if nothing more can be done, then don't pretend to do any more. In the case of cleanup that must be done in the end, perhaps 2 functions would be better: a top level func to acquire and dispose of resources, calling an inner func to do as much work as it can with the resources. (assuming something like C that doesn't have a "finally" clause like Java) I've never understood how finding the end of a long / nested mess of if/else blocks, rather than leaving the function, is somehow better. Which one feels more like a GOTO in terms of least astonishment?