-2

Followed the do..while pattern recommended here:

for {
    work()
    if !condition {
        break
    }
}

Below code is implementing do..while(condition) using for loop:

var r *s
var err error
counter := 0

for { // do..while(specificerror && < MAX && trigger_not_initiated)

    r, err = f()
    counter = counter + 1
    if !(err != nil &&
        strings.Contains(err.Error(), "specificerror") &&
        counter < MAX &&
        !IsTriggerInitiated()) {
        break
    }
}

But review team suggests to make if condition more readable by removing negation in negation(condition) in if statement

How to remove negation in negation(condition) for if statement?

icza
  • 389,944
  • 63
  • 907
  • 827
overexchange
  • 15,768
  • 30
  • 152
  • 347

2 Answers2

7

The transformation you need is called De Morgan's Laws:

  • not (A or B) = (not A) and (not B)
  • not (A and B) = (not A) or (not B),

So if you have a statement like this:

if !(a && b && c) {}

It is equivalent to

if !a || !b || !c {}

In your example:

if !(err != nil &&
    strings.Contains(err.Error(), "specificerror") &&
    counter < MAX &&
    !IsTriggerInitiated()) {
    break
}

Translated version:

if err == nil ||
    !strings.Contains(err.Error(), "specificerror") ||
    counter >= MAX ||
    IsTriggerInitiated() {
    break
}

One thing that needs to be inspected: short-circuit evaluation. In a series of && if an expression is evaluated to false, the rest will not be evaluated (we know the result is false).

Luckily, this will remain the same in the translated version: short-circuit evaluation will be the same, because in a series of || if an expression is evaluated to true, the rest will not be evaluated (we know the result is true). So when in the original form a is false, that's exactly the same case when !a is true in the transformed form.

icza
  • 389,944
  • 63
  • 907
  • 827
  • 2
    not (A or B) ⟷ (not A) and (not B) holds in classical logic only. In constructive (ituitionistic) logic you have just not (A or B) ⟵ (not A) and (not B) which doesn't allow the translation you suggested. But I doubt that someone asking OP's question is not really interested in these finer parts of logic, so have an upvote. – Volker Oct 21 '21 at 11:31
4

How to remove negation in negation(condition) for if statement?

Exactly as suggested ("use ||")

if !(a && b) 

is equivalent to

if !a || !b

For more information, see De Morgan's laws.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367