Mechanisms for defining and composing abstractions are essential elements of programming languages. The design style supported by the abstraction mechanisms of most current languages is one of breaking a system down into parameterised components that can be called upon to perform a function.
But many systems have properties that don't necessarily align with the system's functional components, such as failure handling, persistence, communication, replication, coordination, memory management, or real-time constraints, and tend to cut across groups of functional components.
While they can be thought about and analysed relatively separately from the basic functionality, programming them using current component-oriented languages tends to result in these aspects being spread throughout the code. The source code becomes a tangled mess of instructions for different purposes.
This "tangling" phenomenon is at the heart of much needless complexity in existing software systems. A number of researchers have begun working on approaches to this problem that allow programmers to express each of a system's aspects of concern in a separate and natural form, and then automatically combine those separate descriptions into a final executable form. These approaches have been called aspect-oriented programming.