Abstraction and Interfaces
Levels of abstraction
Large computer systems can only be understood by dividing them into levels of abstraction. Each level provides services to the level above it, implemented using services from the level below. The boundary between levels is the interface.
The interface must do two things:
- Supply the advertised services to the higher level
- Block access to the implementation details of the lower level
This abstraction barrier allows one level to be changed without affecting levels above. For example, when a manufacturer designs a faster processor, existing programs must continue to run — differences between old and new processors must be invisible to the program.
Recurring issues at every level:
- What services to provide at each level
- How to implement them using lower-level services
- The interface that defines how the two levels communicate
Example: dates
| Level | Detail |
|---|---|
| Abstract | Dates over a certain interval |
| Concrete | Six characters: YYMMDD (each character = 8 bits) |
Inadequate internal formats have caused real crises:
- Digital PDP-10 (1975): Used 12-bit dates — good for at most 2^12 = 4096 days, or about 11 years
- Year 2000 crisis: Most industry formats used two-digit years (YYMMDD). The common “solution” was adding two further characters, altering file sizes. Yet the existing six characters already provide 48 bits — sufficient for the projected lifetime of the universe: 2^48 = 2.8 × 10^14 days ≈ 7.7 × 10^11 years
The lesson: mathematicians think in unbounded ranges, but computer representations impose hard limits. A good programming language lets you change the representation easily, but compatibility with old file formats remains a problem.
Example: floating-point numbers
A floating-point number is represented internally by two integers (mantissa and exponent). The concept of a data type involves:
- How a value is represented inside the computer
- The suite of operations given to programmers
- Valid and invalid (exceptional) results, such as “infinity”
Because of finite precision, floating-point computations are potentially inaccurate. For example, computing (2^1/10000)^10000 on a calculator may yield 1.99999959 rather than 2. Certain computations can cause errors to spiral out of control.
Floating-point numbers are an abstract type: the programmer uses operations like *. and +. without knowing the mantissa/exponent representation, and can change the underlying precision without rewriting code.
Data types and type safety
Inside the computer, all data are stored as bits. In most languages, the compiler uses types to generate correct machine code — types are not stored during program execution. Early languages like Fortran barred programmers from mixing types (INTEGER, REAL, COMPLEX). Modern languages handle many kinds of data including text and symbols, and the type system prevents senseless combinations at compile time.