Search code examples
gotoconditional-statementsstructured-programming

Absolutely-DRY conditionals in a language that doesn't allow goto?


How do you fake conditionals that don't nest in a language that doesn't allow goto? I want to do the following:

if (condition1)
    action1;
if (!condition1 && condition2)
    action2;
if (!condition2 && condition3)
    action3;

Without:

  1. Needlessly evaluating any condition more than once.
  2. Needlessly storing the result of any such evaluation in a variable.
  3. Needlessly specifying more than once that any action should be performed.

The original snippet fails to meet requirement 1.

The following snippet fails to meet requirement 2:

if (condition1) {
    action1;
    c2 = false;
}
else if (c2 = condition2)
    action2;

if (!c2 && condition3)
    action3;

And the following snippet fails to meet requirement 3:

if (condition1) {
    action1;
    if (condition3)
        action3;
}
else if (condition2)
    action2;
else if (condition3)
    action3;

EDIT:

  1. It is impossible that condition1 and condition2 be true simultaneously.

  2. It is impossible that condition2 and condition3 be true simultaneously.

Here is the original code (in JavaScript):

// If only the array of elements was specified,
// wrap it inside an object.
if (info.constructor !== Object)
    info = {children: info};

// If no array of elements was specified, create
// an empty array of elements.
if (!info.children)
    info.children = [];

// If, instead of an array of elements, we have
// a single element, wrap it inside an array.
if (info.children.constructor !== Array)
    info.children = [info.children];

Solution

  • So how do you do this with goto anyway? This immediately comes to mind, but doesn't have quite the same result:

    if(condition1) {
        action1;
        goto a;
    }
    if(condition2) {
        action2;
        goto b;
    }
    a:
    if(condition3) {
        //This will run if condition1 && condition2 && condition3
        action3;
    }
    b:
    

    Either way, you do have a few tricks that can break out of nested "if"s. Try:

    do {
        if(condition1) {
            action1;
        } elseif(condition2) {
            action2;
            break;
        }
        if(condition3) {
            action3;
        }
    } while(false);
    

    It's essentially a goto, but...

    That version will duplicate the goto construct that I imagined, rather than the one in the OP. Note that "return" works about the same, in case that looks cleaner in your code (and it might be able to push the hack a bit further by returning a boolean).