Ghost Logic

Ghost Logic is dead or unnecessary code that leads the reader to make false assumptions about values and states.

An example is better than a thousand words:

def recalculate_score(age : Int32?, iq : Float32, wealth : Money?) : PersonalScore
  return PersonalScore.UNKNOWN if !age
  return PersonalScore.UNKNOWN if !money

  if(age < 18)
    return PersonalScore.CHILD
  end

  if(iq > 200)
    Log.info { "Unusual IQ: #{iq}" }
    return PersonalScore.OUTLIER
  end

  age_factor = (1 / (age - 18))

  # the formula is not important for the example
  PersonalScore.new(age_factor * iq / 100 + Math.log(wealth.amount))
end

Ignore the formula for the score. The point is this: What if the system only handles people 18+, every person has an age, all IQs are normalized to be lower than 200 and every person has a money amount set? All of the if-statements are now effectively dead code (without the compiler knowing). But this is not obvious to the reader that is not familiar with the entire system / code-base. The reader starts making assumptions from reading the conditions:

  • It looks like there are people without known age
  • It looks like it is possible for children (age < 18) to be in the system
  • It looks like there might be people with IQ > 200
  • It looks like there might be people with an unknown amount of money

This is ghost logic. The worst thing is that this ghost logic can spread throughout the code base. The programmer learns the ghost logic from this method and later does modifications in other parts of the program. He notices that those special cases above were not handled and adds logic for that into other places, even in tests. The ghost logic spreads kinda like a meme or a myth.

The ghost logic is more likely to spread if the logic is:

  • very believable
  • hard to debunk

E.g. the parameters for recalculate_score might be deserialized from a queue made up of JSON messages. Then there is no easy way to use tooling to check for possible values and where they might come from. In addition, the values might be exceptionally rare, so you might not see them during testing.