  Starting from Shannon's celebrated 1948 channel coding theorem, we trace the
evolution of channel coding from Hamming codes to capacity-approaching codes.
We focus on the contributions that have led to the most significant
improvements in performance vs. complexity for practical applications,
particularly on the additive white Gaussian noise (AWGN) channel. We discuss
algebraic block codes, and why they did not prove to be the way to get to the
Shannon limit. We trace the antecedents of today's capacity-approaching codes:
convolutional codes, concatenated codes, and other probabilistic coding
schemes. Finally, we sketch some of the practical applications of these codes.
