I'll assume something that I believe is uncontroversial: that natural living systems are, so far, capable of more coherent and robust complexity, and behavior, than are human-engineered computing systems.
So let's look at the ways biological systems develop and see how current software practice deviates from these.
There are many obvious differences, but I need to start somewhere, so let's start with differentiation during development.
In a program, we apply ourselves to a "soma", or "body of software", and change it, incrementally, attempting to make changes to the whole that are consistent, effective, efficient, simplifying, etc. We usually fail to do so, especially when the software becomes increasingly complex, and other demands draw our attention away from diligence. This happens because we are fighting against troubling truths: 1) the inherent difficulty in maintaining complete knowledge of the whole program, 2) the inherent difficulty in knowing and communicating good solutions to difficult problems, and 3) every system we interface with has faced these same truths, and so the failures have a tendency to compound.
Biological systems, however, are faced with the same truths. But there is no attempt to 1) create a single point of failure (equivalent to the programming team) which must have complete knowledge, or 2) resolve each issue and problem with a new sets of differentiations, created essentially from scratch, or 3) depend upon other failing systems.
The primary pattern for biological differentiation is the sequence. The genetic code modifies the soma by applying a series of operations, across the entire system, in the appropriate context.
So, let's try programming in this way. Say that we try to create a generative sequence that effects / creates a body of code.
There are three ways one might approach this. The first two are essentially implementable on top of current practice:
a. Create a "sequence reader / creator" that operates upon a passive codebase, analyzing it at each stage to see if an operation in the sequence is applied in the appropriate context. This "reader / creator" is essentially a code generator, and the sequences would be written in a language of "software unfolding" which I'll describe later, but which anyone with some time and introspection could create, if they follow some morphological principles (which I'll also describe later).
b. Create a "sequence reader / creator" that operates in conjunction with a class / object framework, and which assumes that emerging objects will maintain complete knowledge of their context, which they can provide to the "reader / creator", which then provides instructions to them, regarding their further differentiation.
c. Create "pieces" of software, of some sort, "cells" or "objects", which have access to the sequence, and which determine their own next differentiation (including the creation of new cells) based on their context and the instructions in the sequence.
It's clear that (c) is closest to living systems. It's pretty clear that this somatic mechanism is not hard to create: although a clear prerequisite is a system and language that emphasizes self-modifying code, making it extremely easy. Most systems are not like this, and in fact consider it dangerous -- but creating a system with this capacity is not difficult.
Given this somatic system of self-modifying/differentiating code, we still need to know what the language of differentiating software sequences looks like.
The language certainly depends upon the somatic system to which it provides instructions. This is clear from both a programming perspective and from a biological perspective, so we're still on the right track.
We need to make this a system which works in the real world -- that is, we need to be sure it can be deployed to bring coherence and robustness to existing systems. Otherwise it is only a biological simulation, and we'll discover nothing about the effectiveness of biological approaches on human engineering.
More on both the "sequence language" and the "soma" in the next post, and on core memory.