User Tools

Site Tools


emergence

This is an old revision of the document!


Emergence

What?

“Emergence” is defined in terms that seem, at first, to dance around rhetorical redundancy.

Aristotle (384–322 BC) is recognized as the first to describe emergence :

On Aristotle’s view, human beings, like other “secondary” substances, arise from a distinctive 
arrangement of the four material elements. While the mental powers of human beings require and 
are necessitated by such an arrangement, these powers are distinct from, and downwardly causally 
efficacious with respect to, any non-mental powers.

Let's bring this wording forward about 2300 years. Consider a system composed of elemental parts. The elemental parts are considered to be well-known in their properties and interactions. As this system increases in complexity, there can be observed additional behaviors, which are unique and distinct from the total of the properties exhibited by the elemental components. Furthermore, the newly exhibited behaviour of this complex system cannot be explained through any logical examination of the component elements and their properties. The new behaviour has “emerged” from the complex system of elemental components.

Darwin used the idea of emergence to describe new behaviours of living beings that, although possibly explained by evolutionary incremental response to the being's external environment, nevertheless exhibited behaviour to adapt that could not have been predicted in any logical way from analysis of the preceeding environment and behaviours.

Emergent Technology

We technologists, especially of the software engineering kind, discuss emergence most often in context of SystemArchitecture (and EnterpriseArchitecture). Our systems are built of components, often independent services, which we have created to have very specific, Mathematically complete, API's. Functions of those API, their methods, which we call “behaviour”. This system grows in complexity as we add other component-service to it, accomplishing more and greater processes. At some point, as we continue to observe the operation of this system in real-time, we begin to observe interactions of the system with client-callers that are beyond the original definition of the system nor any of it's component-services. This behaviour has emerged by it's complex composition, exhibiting a behaviour that previously was not predicted. Most often, this new behaviour is often surprising and could not have been predicted by any logical analysis of the component-services and their API functions.

Emergent Code

The code we write, within a single library or application, is a complex system of elemental components. In this context, the general limitation of the definition of “elemental” should be that of a simple function.

def add(x, y) { return x + y; }

When we write “code” it is common to start with the imperative, TopDownProgramming style. Step 1, Step 2, Step 3. “Lather. Rinse. Repeat.”. Instructions are not only concrete in the operation of our computers – Machine Language (“Assembly”). Instructions are ubiquitous within our society and culture.

So, we form the process of building an “idea” into code. Many steps at a time.

Many steps at a time. This is the critical part. A complex application, then, has a multitude of instructions – complex functions that perform many steps. Often these functions exhibit (or “perform”) more than one behaviour at a time. An “elemental” function as above, then, represents a function that exhibits exactly one behaviour. This is the basis of the SingleResponsibilityPrinciple.

Our complex application exhibits behaviours that are greater than the functions of which it is composed. These extended behaviours are our application's API.

What are the elemental functions though? We started writing this application with multi-step functions, steps to describe building our “ideas” from the nothingness of an empty environment.

Our complex application, as it continues to grow in complexity, also begins to cause pain to both users and developers. “Behaviours unexpected” begin to be exhibited as the user executes the application – BUGS!!! This state of the application is definitely exhibiting behaviours that could not be predicted!!

But wait… this is CODE! Mathematical! Cold, calculated, complete! How could we observe behaviours that cannot be predicted??

Come back to the construction of our application – multi-step functions. With an application of “sufficiently large size”, no human could be reasonably expected to be able to “memorize” the entire function set of the application. The minimum size for an “inscrutible” application is a lot smaller than anyone suspects. And this trick of complexity requires memory, which is often shorter than the time frame it takes to change or add functions to the system.

What do we do!? Refactoring!! The properties required of an “elemental function” are described by Kent Beck in Extreme Programming Explained : ch. Simple Design 1)

• Runs all the tests

• Contains no duplication

• Expresses the intent of the programmer

• Minimizes the number of classes and methods

Robert C. Martin in Clean Code : ch Emergence associates these properties with his own traits of “Clean Code”.

Neither author though tells us what to expect, nor how to achieve or observe “Emergence”.

Emergent Refactoring

Emergence in our CODE comes of Refactoring. Taking our multi-step function and first applying tests to it… to ensure all conditions (code-branches!) and exception-handling (null-check!) operate as expected… Expected Behaviour!

Then we perform a step that is not obviated by Simple Design… divide this function into “elemental functions” – one behaviour per function, one condition(branch) per function, exception-handling as an “elemental function”.

As we work through this process of splitting our molecular function into it's atomic components… Patterns will Emerge. Functions with similar behaviour can be collected together into modules or classes. Functions that act upon a single data-type can be collected together into classes. Common collections of arguments or data-blobs (Objects!) can be collected together into DataClass classes.

By the continual breakdown and gathering-up of “elemental functions” – we can begin to observe and Emergence of “behaviours” (data-classes, common function collections, etc) that we could not have predicted from a simple examination of the original multi-step functions. While breaking down into “elemental functions”… we continue to examine the correct execution of tests, adding tests to new “elemental functions” – data-classes, modules, libraries. Correct execution of tests ensures no Unexpected Behaviours are observed – Less BUGS!!

By this Emergence of Code, and improving the stability of our application (less BUGS!!), it is now easier to “reason” about how the application operates. The code, grouped together into common behaviours, matches the form of concept-processing that is used in our brain. Now we can more easily understand WHY our complex application behaves a certain way. We also can now easily determine what changes we could make to our complex application to add or enhance it's behaviours (API!).

CleanCode version

MonkeysAtKeyboards

Embrace

1)
Extreme Programming Explained: Embrace Change, Kent Beck, Addison-Wesley, 1999.
emergence.1620655952.txt.gz · Last modified: 2021/05/10 10:12 by 9gu1h