The most fundamental paradigm of course is that of trees, and in particular trees in which nodes of various types appear. This structure appears in a number of ways in computer science. Parse tree nodes correspond to the terminal and non-terminal symbols of a context-free language, or more precisely, production instances of those symbols. Normally an abstraction of parse trees is used, in which irrelevant terminal symbols and non-terminal symbols are eliminated. Such trees are usually called abstract syntax trees. In abstract data type theory, trees denote expressions and a normal form of an expression denotes its value in a certain sense. Trees can also represent a prescription of the computation of a value, or more general, a program.
The reason for mixing paradigms is that we want to exploit the strong points of each paradigm, while at the same time avoiding their weak points. Examples of such weak points are the following. Attribute grammars allow only attributes to be computed over trees, where the computation can not have a circular dependency. Functional programming languages do not allow side effects to be expressed. Abstract data type rewrite systems can only rewrite terms to their normal form. Conventional programming languages, such as C, usually force the programmer to be fairly aware of the representation of data types.