A trellis code is a 'sliding window' method of encoding a binary data stream as a sequence of real or complex numbers that are input to a noisy transmission channel. Ungerboeck has constructed simple trellis codes that provide the same noise immunity as is given by increasing the power of uncoded transmission by factors ranging from two to four. His method is to specify an underlying convolutional code and a rule (mapping by set partitioning) that maps the output of this code onto a fixed signal constellation. A new description of a trellis code is given that combines these two steps into one. The new description is analytic rather than graphical. Many practical codes can be described very simply, and strict bounds on performance can be obtained. A method for differential encoding trellis codes is presented that was suggested by the authors' representation.