 As shown above, the distinction between software and hardware is not a sharp one. A different ontological approach to computational systems relies on the role of abstraction. Abstraction is a crucial element in computer science, and it takes many different forms. Goguen &amp; Burstall (1985) describe some of this variety, of which the following examples are instances. Code can be repeated during programming, by naming text and a parameter, a practice known as procedural abstraction. This operation has its formal basis in the abstraction operation of the lambda calculus (see the entry on the  lambda calculus)  and it allows a formal mechanism known as polymorphism (Hankin 2004). Another example is typing, typical of functional programming, which provides an expressive system of representation for the syntactic constructors of the language. Or else, in object-oriented design, patterns (Gamma et al. 1994) are abstracted from the common structures that are found in software systems and used as interfaces between the implementation of an object and its specification.