Okay guys, this is something that blows my mind away! I've wiped everything 
redundant from my code and added Star Wars to make it funnier, but the problem 
is really terrifying me.

Consider we have a class Hero and a method for a Hero to kill another Hero: 
    
    
    # heroes.nim
    type
      Hero* = object of RootObj
    
    method kill*(self: var ref Hero, victim: ref Hero) {.base, inline.} = 
discard
    # by default no one can kill another Hero. kill() just does nothing
    

Now we create a bit of Jedi: 
    
    
    # jedi.nim
    import heroes
    
    type
      OB1* = object of Hero
      Yoda* = object of Hero
    
    method kill*(self: var ref Hero, victim: ref OB1) = echo("Obi Wan Kenobi 
was killed")
    method kill*(self: var ref Hero, victim: ref Yoda) = echo("Yoda was killed")
    # Even Jedi may be killed!
    

For the sith, let's add a Startrooper. I never liked them so we won't use it 
anywhere. However, its role is significant! (see below) 
    
    
    # sith.nim
    import heroes
    
    type
      Startrooper* = object of Hero
    
    method kill*(self: var ref Hero, victim: ref Startrooper) = 
echo("Startrooper was killed... one more")
    

Now let's play! 
    
    
    # main.nim
    import heroes
    
    import jedi
    # import sith  # <-- leave for now
    
    # this method will protect Yoda from being killed by anyone
    method kill(self: var ref Hero, victim: ref Yoda) = echo("Yoda may not be 
killed!")
    
    var
      darthVader = new(ref Hero)
      yoda = new(ref Yoda)
    
    # this call matches exactly the newly defined method above
    darthVader.kill(yoda)  # outputs "Yoda may not be killed!", as expected
    

Now we add sith... 
    
    
    # main.nim
    import heroes
    
    import jedi
    import sith  # <-- uncomment this
    # this method will protect Yoda from being killed by anyone
    method kill(self: var ref Hero, victim: ref Yoda) = echo("Yoda may not be 
killed!")
    
    var
      darthVader = new(ref Hero)
      yoda = new(ref Yoda)
    
    # this call matches exactly the newly defined method above
    darthVader.kill(yoda)  # outputs "Yoda was killed"... WAT?!
    

Do you see it too? We added a method to kill a Startrooper (method kill(self: 
var ref Hero, victim: ref Startrooper)) and suddenly our Yoda's protection is 
broken! What the hell?!

Now leave sith module included and let's comment killing Obi Wan Kenobi: 
    
    
    # jedi.nim
    import heroes
    
    type
      OB1* = object of Hero
      Yoda* = object of Hero
    
    # method kill*(self: var ref Hero, victim: ref OB1) = echo("Obi Wan Kenobi 
was killed")
    method kill*(self: var ref Hero, victim: ref Yoda) = echo("Yoda was killed")
    

Guess what?! "Yoda may not be killed!"

So, when you add sith module with Startrooper killing, Yoda's protection 
becomes broken, but when you make Kenobi immortal, Yoda's protection is back!

Now here's the question: how close to schizophrenia I am?

Reply via email to