My godless code (v0.2)

I’ve been meaning to update this for a while now, so here’s my outlook on things variously religious and godless in a neat little codified nutshell:

A->(11)A+->(24)A++->(29)A+ : TR(B,T,FSM,DST,QUA,UNI,WIC) : r(B%100,K%80) : RI(p0,s0,u0) : ex(Fam(1.0),Wk(0.9),Fr(1.0) : SO(A+) : FB(RD,DD+,MS,SH,PJ,JR+,CS++,RI++) : M(blg) : MS(o,l+,n+) : GCD : [gc-0.2]

Godless Code 0.2 (and v0.1 for reference).

Pedro deals with the “one in a million” fallacy

Pedro over at Way Of The Mind has recently posted about the fallacy often used by creationists to argue that “life could never happen by chance”. Go and read it, then come back, and I’ll give you my take on it.

Back? Ok.

One of the things that Pedro didn’t address is his post was the notion of the passage of time. He’s quite correct in saying that rolling a dice however many time to get 66666666666666666666 is extremely unlikely in any realistic lifetime, but that’s if we think that all life came about because of a lucky of a one-time hit. Thankfully, that’s not what evolution (in the timescales offered by the evidence of geophysics, palaeontology, cosmology and the other long-time sciences) predicts.

So, carrying on with Pedro’s dice analogy, and written using simplified terms from the language of biology, I decided to knock-up this little Ruby program (because it’s relatively easy to read, even for a non-programmer) to demonstrate this:

AVAILABLE_GENES = (1..6).to_a
WINNING_GENES = [6]
SUCCESSFUL_GENERATIONS = 15
@genome = ""
@generations = 0
 
while @genome.length < SUCCESSFUL_GENERATIONS
  @generations = @generations + 1
  @point_mutation = AVAILABLE_GENES[rand(AVAILABLE_GENES.size)]
  puts "Generation #{@generations}: " + @genome + @point_mutation.to_s
  @genome << @point_mutation.to_s if WINNING_GENES.include?(@point_mutation)
end
 
puts "Successful genome #{@genome} took #{@generations} generations."

I’ll explain a little about the program works here:

AVAILABLE_GENES is the range of possible “genes”, including both “good” (aiding to survival and reproduction) and “bad” (no surviving offspring) mutation possibilities (in this case, the range of values from 1 to 5)
WINNING_GENES is the list of “genes” that allows a generation of offspring to survive and reproduce (in this case, just 6)
SUCCESSFUL_GENERATIONS is the number of generations of surviving offspring that we want
@genome is the “genome” of the current generation
@generations is a counter to see how many generations that we’ve tried so far

When we run this program, it adds “mutations” (in the form of dice rolls) to a “genome”. If the new mutation is advantageous (i.e. a ‘6′) and aids in survival and reproduction then the gene is added to the genome. If the gene is bad (not a ‘6′) then that generation dies without reproducing, and the current genome remains the same.

Each generation, it tries to “reproduce” with a new gene mutation, the successful survive and the unsuccessful remains the same

Of course, this program is (deliberately) incredibly simplistic (it doesn’t take into account populations, retrograde mutations, what constitutes a successful gene, predators, environment, etc.) but it should serve to illustrate the basic point that a successful genome can be arrived at quite easily over time given enough opportunity to reproduce.

Running the program, what do we see? I’ll save the full listings, but I’ll run it a few times to see what we get (further runs are truncated for space):

Desktop:$ ruby dice_simulation.rb 
Generation 1: 2
Generation 2: 4
Generation 3: 6
Generation 4: 66
Generation 5: 661
Generation 6: 663
Generation 7: 664
Generation 8: 661
Generation 9: 661
Generation 10: 661
Generation 11: 662
Generation 12: 663
Generation 13: 662
Generation 14: 661
Generation 15: 665
Generation 16: 662
Generation 17: 665
Generation 18: 666
Generation 19: 6661
Generation 20: 6663
Generation 21: 6666
Generation 22: 66662
Generation 23: 66666
Generation 24: 666666
Generation 25: 6666664
Generation 26: 6666664
Generation 27: 6666665
Generation 28: 6666666
Generation 29: 66666661
Generation 30: 66666661
Generation 31: 66666661
Generation 32: 66666666
Generation 33: 666666661
Generation 34: 666666663
Generation 35: 666666666
Generation 36: 6666666665
Generation 37: 6666666664
Generation 38: 6666666661
Generation 39: 6666666663
Generation 40: 6666666664
Generation 41: 6666666666
Generation 42: 66666666661
Generation 43: 66666666663
Generation 44: 66666666663
Generation 45: 66666666664
Generation 46: 66666666664
Generation 47: 66666666664
Generation 48: 66666666661
Generation 49: 66666666665
Generation 50: 66666666664
Generation 51: 66666666663
Generation 52: 66666666666
Generation 53: 666666666665
Generation 54: 666666666664
Generation 55: 666666666665
Generation 56: 666666666666
Generation 57: 6666666666663
Generation 58: 6666666666661
Generation 59: 6666666666664
Generation 60: 6666666666662
Generation 61: 6666666666666
Generation 62: 66666666666661
Generation 63: 66666666666665
Generation 64: 66666666666661
Generation 65: 66666666666662
Generation 66: 66666666666665
Generation 67: 66666666666666
Generation 68: 666666666666661
Generation 69: 666666666666662
Generation 70: 666666666666665
Generation 71: 666666666666666
Successful genome 666666666666666 took 71 generations.
Desktop:$ ruby dice_simulation.rb 
Generation 1: 3
...
Generation 7: 6
Generation 8: 62
Generation 9: 63
Generation 10: 65
...
Generation 16: 66
Generation 17: 665
...
Generation 27: 666
Generation 28: 6663
...
Generation 42: 6661
Generation 43: 6666
Generation 44: 66664
Generation 45: 66662
Generation 46: 66665
Generation 47: 66666
Generation 48: 666662
...
Generation 55: 666666
Generation 56: 6666662
...
Generation 62: 6666666
Generation 63: 66666664
...
Generation 78: 66666666
Generation 79: 666666665
Generation 80: 666666662
Generation 81: 666666666
Generation 82: 6666666666
Generation 83: 66666666663
...
Generation 90: 66666666666
Generation 91: 666666666663
Generation 92: 666666666665
Generation 93: 666666666666
Generation 94: 6666666666664
...
Generation 97: 6666666666666
Generation 98: 66666666666664
Generation 99: 66666666666662
Generation 100: 66666666666661
...
Generation 107: 66666666666666
Generation 108: 666666666666665
Generation 109: 666666666666662
Generation 110: 666666666666666
Successful genome 666666666666666 took 110 generations.
Desktop:$ ruby dice_simulation.rb 
Generation 1: 6
Generation 2: 61
Generation 3: 66
Generation 4: 665
Generation 5: 665
Generation 6: 666
Generation 7: 6662
Generation 8: 6662
Generation 9: 6666
Generation 10: 66662
Generation 11: 66665
Generation 12: 66666
Generation 13: 666663
...
Generation 23: 666666
Generation 24: 6666662
...
Generation 31: 6666666
Generation 32: 66666663
Generation 33: 66666666
Generation 34: 666666663
...
Generation 42: 666666666
Generation 43: 6666666664
...
Generation 48: 6666666666
Generation 49: 66666666663
Generation 50: 66666666666
Generation 51: 666666666665
Generation 52: 666666666666
Generation 53: 6666666666662
...
Generation 75: 6666666666666
Generation 76: 66666666666664
...
Generation 84: 66666666666666
Generation 85: 666666666666662
...
Generation 88: 666666666666666
Successful genome 666666666666666 took 88 generations.

As we can see, each time we run this, we get different numbers for how many generations it can take to get a successful gene, and sometimes there are 10 or 15 generations without a successful mutation. However we can also see that, eventually, there are successful mutations that add to the genome.

Another thing to note is that if we increase the range of AVAILABLE_GENES to, say 1..9, it will usually take more generations to see the target genome come about. If, however, we add genes to WINNING_GENES (e.g. [1,6,8]) we will reduce the number of generations required.

In fact, in relation to the one-time hit that I mention above, that’s exactly what the creationists propose, and who could blame them for invoking magic in the form of creator-gods with something so unlikely?

My point? One way we can get to a specific genome is by *poofing* it into existence in one step. The other is by adding a little bit per generation over a long period of time.

While evolution doesn’t deal with trying to achieve a specific genome, I know which situation the science supports better.