S7-3

Variation, selection, and evolution as the reason biology looks the way it does

14 min

Back in S0.1 you accepted a claim on faith: living things are evolved, not designed. This lesson pays that debt. We are going to build the engine that produces evolution out of three plain ingredients you already have, and then use it to explain something a bioinformatician leans on every single day. Why do the sequences that barely change across species turn out to be the important ones? That is not a coincidence. It falls straight out of the engine.

The engine has exactly three parts

Variation, selection, inheritance. That is the whole machine.

Variation comes from mutation. Recall from S7.2 that every time DNA is copied the copy is imperfect, and from S5.5 that a substitution swaps one base while an indel shifts the frame for everything downstream. So the offspring in a population are never identical. They carry a spread of small differences.

Selection is the filter. In a given environment, some of those variants leave more surviving, reproducing offspring than others. That is the entire meaning of the loaded word "fitter." Nothing more.

Inheritance ties it together. Because the variation is written in DNA, it gets passed on. So the variants that copied a little better make up a larger slice of the next generation, which mutates again, gets filtered again, and passes on again. Run that loop over generations and the makeup of the population shifts. That shift is evolution.

Hold onto one correction here. Evolution is a property of a population across generations, not of an individual. You do not evolve during your life. The frequencies of variants in a population change. An individual is a single fixed draw from the deck.

Fitness is a counting word, not a compliment

Let us pin down fitness, because the everyday sense of the word will mislead you. Fitness is a variant's relative expected number of offspring that themselves survive to reproduce, measured in a specific environment. It is not strength, not size, not intelligence, not complexity. It is a count of surviving copies, relative to the other variants in the same population.

That relativity is load-bearing. A variant is fit only compared to its alternatives, and only here and now. Move the environment and the ranking can invert.

Evolution is a goalless parallel search

Here is the analogy for a programmer. Evolution is a massively parallel, randomized search over an enormous space of possible sequences. A population is a big batch of candidate solutions being evaluated at once. Mutation is a random perturbation applied to a candidate. Reproduction is the fitness function: candidates that score higher get more copies in the next batch. Selection is the step that keeps the higher scorers. Run that loop for enough rounds and the batch drifts toward regions of the space that reproduce well. If you have ever run a genetic algorithm or simulated annealing, this is the same shape you already know.

Now the failure edge, because this analogy misleads the instant you import intent. In the optimizers you write, you pick the objective in advance and the search aims at it. Evolution has no objective that anyone wrote down and nothing it is aiming for. No target, no foresight, no plan two steps ahead. It cannot deliberately hold a variant that is worse today because it will be useful later. It is greedy and local: it climbs whatever hill it happens to be standing on, and it can sit stuck on a mediocre peak forever because every first step off that peak is downhill and gets selected away. Worse, the fitness function is not even fixed. It shifts as the climate shifts, as predators evolve, as the organism's own neighbors change. So the honest picture is a search with no goal, no scorer who chose the goal, and a landscape that keeps moving under it. Calling reproduction a fitness function is a fine shorthand, as long as you never forget that nobody selected it and nothing is being sought.

Not all change is selected: neutral drift

You could be forgiven for thinking every difference between two organisms is an adaptation that selection carved. It is not. A great deal of change is invisible to selection entirely.

Many mutations are neutral. They do not change reproductive success at all. Recall the silent mutation from S7.1 (built on the codon redundancy from S5.5), a third-base swap that leaves the protein identical, plus changes in stretches of DNA that do not do much of anything. Selection cannot see a neutral mutation, because there is no fitness difference to filter on.

But the frequency of a neutral variant still changes across generations. It just changes by pure chance. In every generation only some individuals happen to reproduce, and which copies get passed on is a sampling coin flip. That random wandering of gene frequencies with no selection behind it is called genetic drift. Over long enough time, a neutral variant can drift all the way to fixed (present in everyone) or all the way to gone, without selection ever touching it.

Drift is strongest in small populations, for the same reason a run of 5 coin flips strays from an even split far more than a run of 5000 does. Small samples are noisy. And here is the fact that reshapes how you read sequence data: much of the molecular difference between two species is neutral change piled up by drift, not adaptation. So the correct default assumption for any given difference is drift. Claiming selection is at work is the stronger claim, and it needs evidence.

Conservation is the fingerprint of function

Now the payoff, and it is a good one. Put purifying selection and neutral drift together across long evolutionary time, and you can read functional importance straight off the raw sequence.

Mutations rain onto every position at roughly comparable rates, blindly. Picture two positions in a gene. Position A can be changed without hurting the organism, a floppy region or a silent site. Mutations there are neutral, drift lets them accumulate, and over hundreds of millions of years that position diverges freely between species. Position B is one where almost any change breaks a protein the organism cannot reproduce without. Mutations still arrive at position B just as often. But every individual carrying such a change reproduces worse or not at all, so selection deletes those carriers from the record before they leave descendants. This quiet removal of harmful variants is called purifying selection (also negative selection).

The visible result, millions of years later: position B looks nearly identical across bacteria, yeast, fish, and you, while position A is a scramble of differences. So conservation, a position or stretch that has changed very little across species that split long ago, is a proxy for functional importance. The reasoning is a proof by absence. Mutations definitely happened there. The only reason they are not visible today is that their carriers got selected out, which means change there was not tolerated, which means the position does something the organism could not afford to lose. Conserved code is code so load-bearing that the codebase with no author from S0.1 never got to keep a single edit to it.

Read it yourself

Reach for the alignment tool you met in S6.3. Line up the same gene from two species and read down the aligned columns instead of along the rows. Columns where both species show the same letter are conserved, and are almost certainly doing something the organism cannot afford to break. Columns that differ are tolerating change. Try this: edit one input so it differs at a matching (conserved) column, then instead at a mismatching (variable) column, and watch how the identity score responds. Now picture the same view stacked across many species: a column identical in all of them is one you would bet a mutation cannot afford to touch. The conservation pattern is telling you which changes are dangerous before any lab does.

align.ts
The recurrence
matrix[i][j] = max(
  matrix[i-1][j-1] + s(a[i-1], b[j-1]),   // diagonal: align the two residues
  matrix[i-1][j]   + gap,                 // up: a gap in sequence b
  matrix[i][j-1]   + gap                  // left: a gap in sequence a
)
s(x, y) = match when x == y, else mismatch

Global alignment (Needleman-Wunsch) seeds row 0 and column 0 with k * gap and reads the score from the bottom-right corner.

-GATTACA
-0-2-4-6-8-10-12-14
G-21-1-3-5-7-9-11
C-4-10-2-4-6-6-8
A-6-30-1-3-3-5-5
T-8-5-210-2-4-6
G-10-7-4-10-1-3-5
C-12-9-6-3-2-10-2
U-14-11-8-5-4-3-2-1
GCATGCU
GATTACA
Score-1
Identity43%
Columns7
Gap penalty-2
Write it yourself: the DP fill

The grid above is not magic. It is one nested loop. Given the two sequences and the scores, fill every cell from the three neighbors you already computed, then trace back from the best cell to recover the alignment. Try writing the fill from the recurrence before you read it.

align.ts
// A thin sketch of needlemanWunsch (global). Local alignment is the same
// loop with a 0 floor and a traceback that starts at the largest cell.
function fill(a: string, b: string, match: number, mismatch: number, gap: number) {
  const m = a.length;
  const n = b.length;
  const matrix: number[][] = [];
  for (let i = 0; i <= m; i++) matrix.push(new Array(n + 1).fill(0));

  // Seed the borders: a run of k gaps costs k * gap. (Local leaves these at 0.)
  for (let i = 1; i <= m; i++) matrix[i][0] = i * gap;
  for (let j = 1; j <= n; j++) matrix[0][j] = j * gap;

  // Fill. Row i indexes a, column j indexes b.
  for (let i = 1; i <= m; i++) {
    for (let j = 1; j <= n; j++) {
      const s = a[i - 1] === b[j - 1] ? match : mismatch;
      const diag = matrix[i - 1][j - 1] + s;   // align a[i-1] with b[j-1]
      const up = matrix[i - 1][j] + gap;        // a gap in b
      const left = matrix[i][j - 1] + gap;      // a gap in a
      matrix[i][j] = Math.max(diag, up, left);
      // Smith-Waterman (local) instead: Math.max(0, diag, up, left)
    }
  }

  // The global score is the bottom-right corner.
  return matrix[m][n];
}

Key terms

Variation
The spread of small differences among individuals in a population, produced by DNA being copied imperfectly every generation.
Natural selection
The non-random filtering of variation by reproductive success, so variants that copy better in the current environment become more common over generations.
Fitness
A variant's relative expected number of surviving, reproducing offspring in a given environment, a count and not a judgement of worth.
Neutral mutation
A change that does not affect reproductive success, so selection ignores it and its frequency moves only by chance.
Genetic drift
The change in gene frequencies from generation to generation by random sampling alone, with no fitness difference involved, strongest in small populations.
Purifying selection
The removal of harmful variants by selection, which keeps functionally important positions nearly unchanged over long evolutionary time.
Conservation
A sequence position or region that has changed very little across distantly related species, used as a proxy for functional importance.

Closing the loop

Biology looks the way S0.1 promised it would, redundant, messy, riddled with exceptions, yet exquisitely tuned in exactly the parts that matter, because it is the output of a goalless parallel search that kept whatever reproduced and could only edit a running copy, never redesign it. Selection tuned the load-bearing parts and left the rest to drift. Conservation is where that whole history becomes legible to you: it marks the lines of the code that four billion years of selection never let anyone change.

Check yourself

1. What are the three ingredients that together produce evolution?

2. Bacteria are exposed to an antibiotic and a resistant population survives. What most accurately describes what happened?

3. A silent mutation with no effect on fitness rises from rare to common in a small population. What is the best explanation?

4. You find a variant in a column that is identical across 100 species, and another in a column that varies freely between species. Which variant is more likely to be damaging, and why?

4 unanswered