Proposals

Lynn H. Maxson lmaxson@pacbell.net
Sun, 16 Jul 2000 18:04:38 -0700 (PDT)


Billy wrote:
"Er -- no, it won't.  Any programmer you ask to 
code that algorithm for you
will either drop to the floor laughing or will be 
coding until he's dead.
Solving the problem that way is impossible."

I love the challenge of the impossible, infinite, 
and too finitely large that you raise.  That 
program's do in fact terminate is a part of my 
reality.  Thus I do not worry about computing in 
some manner when they will terminate, but about 
having that time as short as possible.  I have no 
conflict with Rice's Theorem as I have no interest 
in computing what is provably impossible.<g>  I 
deal exclusively with the possible, however 
challenging it may appear to others.

It does not strike you as strange that we can 
specify, analyze, design, and test systems as 
whole, but that we cannot do so in construction.  
We can specify, analyze, design, and test any 
system at any level down to its "atomic" units.  
Yet we cannot do so in construction.  While such a 
range from the very smallest unit to the very 
largest can occur elsewhere in the software 
development process, it cannot occur in 
construction.  Why?  Once the programmer laughing 
subsides, it is said (by you) to be impossible.

Well, in my system what you want to do is 
determined by the set of input specifications 
selected which can range from atomic units to 
assemblies of any scope.  The only writing which 
occurs within the process (thus excluding user 
documentation which lies outside) is that of 
specifications.  I do not worry about programmers 
laughing because no programmers nor programming (as 
a separate activity) is involved: executables are 
produced directly from specifications as they do 
now currently in Prolog.  The only difference is 
that so are the results of analysis and design.  In 
short the system (however defined) is developed as 
a whole throughout the entirety of the process.

If you concede that C (and PL/I) works the way it 
does, then you know that within a single external 
procedure you can have multiple internal ones and 
within each further multiples to an 
"implementation-" (not language-) defined depth.  
For some reason this seems "normal" to you and yet 
extending it one level upward (to begin with) in 
which multiple external procedures are considered 
as a single unit of work is somehow impossible. If 
they are all part of a single application system 
(of demand- and frequency-based) programs 
interconnected through data stores (persistent 
data), something which we achieve as a matter of 
course in dataflow analysis, you regard it as 
"impossible" in programming.

To make this transition easier let's switch to 
Prolog and logic programming.  Here we are given a 
named set of "unordered" specifications containing 
goals (main and sub), rules, relationships, and 
data.  From this the logic engine creates the 
organization (the logic) necessary to satisfy the 
(main) goal.  Nothing prevents having more than one 
set of main goals (other than the implementation), 
having main goals for each of the programs of an 
application system all included within a single 
input stream.  Far from being the impossible task 
you envision it is simply the addition of a list 
which contains as its entries the list created to 
represent the logic of a single program.  It is no 
more difficult, in fact a lot easier, to do this 
with a set of programs as a single unit of work 
than it is to do them individually as we do 
currently.

Now any LISP programmer reading this will confirm 
that it is relatively trivial to take a set of 
processes against a set of inputs up a notch to 
where you apply the same processes to a list of 
such sets.  That LISP does not currently do this is 
an implementation decision, not because it is 
impossible.  It may take awhile to get use to the 
idea of multiple executables from a single set of 
input, but that does not exclude its possibility.

Now let's take a different tack built upon 
something on which we should agree.  I am willing 
to concede for the moment the impossibility of an 
optimum solution if you will concede in turn that I 
at least can invoke existing code generation 
algorithms.  Further that with these algorithms we 
can create code whose performance is "good enough".

Now that we are off this "impossible dream" of 
optimized code generation we now have the ability 
to generate executables whose performance is (for 
the most part) good enough.  In general the issue 
plaguing the IT profession is not the performance 
of our software, but our inability to develop and 
maintain it at a rate commensurate with user 
demands.  Whenever supply falls below demand you 
create a "backlog".  It makes little sense to 
propose a solution, particularly one based on 
language, that does not relieve this backlog, that 
does not allow our "supply" ability to keep pace 
with demand.

Understand that this has been the major IT 
bottleneck for the last thirty years (or perhaps 
longer).  We have thrown one HLL after another at 
it without in any manner slowing down the growth of 
the backlog.  In the meantime our cost and the time 
involved in doing what we do managed to do has 
continued to climb.

Now why is our maintenance backlog so great?  The 
almost universal answer which came back was the 
distribution of processing for data (objects).  It 
was so scattered, involved so many changes, and 
coordination of those changes that it could not 
occur at the rate with which user change requests 
occurred.

How do we solve this?  End the distribution.  Put 
all the processing within the scope of the data 
itself.  Thus making a single change within an 
object will be automatically reflected in all its 
uses.  In looking around we found something else to 
"borrow" from PARC, Smalltalk.  Unfortunate much of 
its runtime performance fell outside the "good 
enough" boundaries.  Fortunately Bell Labs offered 
yet another cheap solution, C++.

Probably never has any other software methodology 
received the funds, the research, and the support 
than that which has gone into OO.  Even the three 
(competing) major analysis and design methods were 
merge into a single one, UML.  The net result so 
far as the backlog is concerned remains at less 
than zero as it continues to grow, as systems 
continue to cost more, and as the time to produce 
them increases.

Does anyone reading this seriously believe that 
whatever esoteric, exotic, exclusive, elusive, 
eccentric, elegant, excellent, eclectic and 
exquisite feature(s) water brings to Slate that it 
will in and of itself resolve the backlog issue, 
resolve our inability to introduce changes as fast 
as the need arises?  No.  The fault does not lie 
with Slate or any other HLL.  The fault lies in our 
implementation.

Anyone involved in using an editor and creating an 
input source file in construction is guilty of 
producing a seam in a seamless process.  It's that 
simple.  We are not executing the software 
development process as we have defined it: 
seamless.  

If we did, if we automated all stages after the 
introduction (or selection) of a set of input 
specifications, if we take people out of the 
process beyond this "initial" input stage, then we 
could introduce changes as quickly as they occurred 
(and in fact faster which allows us to reduce the 
backlog eventually to zero).

If the problem was the distribution of data-related 
processes, more than one solution is possible.  
Unfortunately IT picked the wrong one: OO.  The 
more correct one would have been to incorporate all 
the changes in all the processes automatically and 
concurrently.

Nothing exotic or special is involved in that.  
Eliminate the designation of external and internal 
procedures, simply allowing a set of procedures 
whose internal logic contains the references which 
allows their logical organization (hierarchical 
functionality) to be done dynamically as occurs in 
every logic programming system.  Then allow within 
that set of procedures multiple "root" procedures, 
those not invoked by any other, and create an 
executable for each functional hierarchy for each 
root.

You do that simply by adding an iterative level 
which processes a list of root procedures into the 
compilation process.  Now my experience says that 
adding an iterative process which contains an 
existing process (or set of processes) is a piece 
of cake, far from the impossible that you assign to 
it.