"If anything can go wrong, it will" is a certainty!
Corollary: there is no uncertainty in engineering.
Hint: containment constraints (aka closure).
Too much talk and too much work
Radical Engineering
architectando.blogspot.com
Copyright © 2006-2025
Julio P. Di Egidio
http://julio.diegidio.name/
Internal contents under the GNU General Public License, external contents under their own respective licenses.
"If anything can go wrong, it will" is a certainty!
Corollary: there is no uncertainty in engineering.
Hint: containment constraints (aka closure).
As far as technical definitions go, agility is the antipole of formality along a methodological dimension. Specifically, agility is "low formality", where by formality we mean high level of control, extensive documentation, and heavy bureaucracy.
Note that the agile-formal dimension is orthogonal to the process models, such that we can have agile waterfall, agile iterative, etc. just as we can have formal waterfall, formal iterative, etc. (Corollary: there is no such thing as agile vs. waterfall!)
Note that the agile-formal dimension is also orthogonal to the cowboy-disciplined dimension, such that we can be agile or formal, still we are required to be disciplined. (Indeed, this was the greatest achievement with agility, that before it we only had "cowboy" vs formal!)
K : Competitiveness (aka Performance) Ea : Efficacy Ei : Efficiency Qp : Quality of Product Qs : Quality of Service T : Time C : Cost Ea =def Qp * Qs Ei =def 1 / (C * T) K =def Ea * Ei = (Qp * Qs) / (C * T)
The definition of competitiveness is common to all kinds of engineering, but, due to the very nature of the object matter, with software (in fact, with all knowledge-related production), contrary to what happens with conventional engineering (the "hard" kinds of production), efficacy and efficiency are directly proportional. In other words, contra the usual assumptions, with software, higher quality goes with lower costs.
In symbols:
Ea ∝ 1/Ei for "hardware" Ea ∝ Ei for "software"
To keep it simple you need to be *very* smart.
Corollary: simple and stupid is just stupid.
Hint: software engineering is the most complex engineering that there is.
One step back, two steps forward:
Deconstruct
Reconstruct
Extend
The essential software cycle.
Once upon a time we had:
Do it properly.
Keep it simple.
Follow the rules.
The old school of engineering.
[Draft manifesto, partly in response to the Software Craftsmanship manifesto.]
I am a software professional:
1) I build software that solves my customers' needs, explicit and implicit.
That is the only software I will qualify as "working".
2) The software I build not only works, it keeps working.
Always around the optimal balance between minimality and continuous improvement.
3) I build software with honesty, responsibility, vision, and passion.
My customer is king and I will tell him when he is wrong: no excuse, rather quit.
4) I believe in professional integrity and real competence.
This is no place for unscrupulous marketers and incompetent wannabies.
I am a software professional, and I am damn proud of it!
Radical engineering principle: on readability
Memento:
Engineering principles are true by good convention.
Principle:
Optimal "readability" is readable _optimality_.
Comment:
Never ever optimize. <*>
Do make code readable. <**>
Clean up the dark side. <***>
Readability before all. <****>
The only way to optimal code. <>
Extended:
<*> Includes refactoring, the semantic side of optimization.
<**> Includes restructuring, the syntactic side of readability.
<***> Includes comments, the dark side of readability.
<****> Includes the dark side of optimality.
<> Readability dis-including itself.
Hint:
Optimization of a sub-optimal program (algorithm, system, product, procedure, argument) is a pointless hack that leads to solutions at local minima. Improvement of such local-minimal solutions is impractical, given that the underlying landscape has been so redundancy-reduced as to result completely chaotic.
In practice, if a sub-optimal program gets optimized (once upon a time there was the blessed post-optimization-upon-need, nowadays we have optimization as an integral programming practice called refactoring and its cousin performance), any required improvement needs stepping back a number of iterations until another approach, more basic but broader enough for the extended problem, gets in sight. The more premature the optimizations, the more paralyzing the sub-optimized local-minimal results. And the iteration starts over...
To break the deadly cycle, just stop optimizing in any form, start instead striving for readability. To get a basic idea of readability, we can think of the optimal target as a program code that can be _read as easily_ by a professional in the field as something in between a technical article and a page of mathematics. That is, code must speak for itself!
[A side note to the casual reader: please don't get too strict on terminology, I'm using all terms in their _broader_ sense, so that, for instance, should you be a software engineer, where I say "coding", I actually mean any act of production, including all that there is from analysis to delivery. The same holds for other disciplines. The only restriction is maybe in that I try to stay within the bounds of "engineerings" and "applied sciences", although, sooner than later, we'll catch up with the "social sciences"...]
That said, besides avoiding the inconveniences of optimization (taken in its broadest and weakest sense), readability brings its own distinctive advantage, indeed an exclusive property: readability and only readability leads to optimal programs. We still miss a formal proof, but that might be apparent if we think what an _optimal_ program is: on a side, readable entails manageable so much as the latter requires the first; on the other side, every _ideal_ relates to needs that, in any ultimate sense, are "human" and only "human". Indeed, "who" needs _what_?
[For example, say one is programming and keeps readability in mind.
That means:
1) writing code with readability in mind (rather than "writability");
2) designing a system under permanent (re)structuring, down from its very (im)permanent foundations;
3) keeping the whole environment always clean and tidy, as if important guests are to arrive at any moment soon (and that includes documentation; yes, please, if in doubt, just DROP IT ALL!!).
That leaves plenty of room for movement, and the code stays always around the optimal balance between minimality and continuous improvement.]
We can't predict the future, we make it: we are pure induction in action.
Radical engineering principle: on correctness
Memento:
Engineering principles are true by good convention.
Principle:
Correct is good! Period.
Comment:
As far as it passes systems testing, a system is "correct", and the problem becomes "good" testing.
Extended:
We do solve the halting problem in everyday life, though asymptotically: up to the next failure.
Hint:
Consider the full set of systems for a given problem: IS* = S + oo + 0/0, where S is the set of bounded correct systems, oo is the set of full-correct systems, and 0/0 is the set of failing systems. IS* so defined can be treated in terms of interval arithmetic.
References:
G.W. Walster, "Introduction to Interval Arithmetic", 1997 (slightly adapted):
The interval paradigm has a number of valuable characteristics, including:
1. Fallible data can be represented using intervals.
2. Any arithmetic computation can be performed with guaranteed bounds on the set of all possible results.
3. Bounds can be provided on errors from all sources:
- observation or measurement errors;
- modeling errors;
- machine rounding errors; and
- interactions among all of the above and the inherent instability of the problem.
4. Problems can and have been solved that are otherwise thought by many mathematicians, scientists and engineers to be in principle unsolvable. Exemplars include:
- nonlinear systems of equations; and
- nonlinear programming (or nonlinear global optimization).
For additional information on interval arithmetic and how it can and has been used to compute guaranteed bounds on answers to otherwise unsolvable problems, see:
[*] As an alternative link: http://web.archive.org/.../walster-papers.html
Credits:
Thanks to the invaluable support I got from the sci.math group (no endorsement implied): Computing infinity modulus and zero modulus.
Radical engineering principle: on refactoring
Memento:
Engineering principles are true by good convention.
Principle:
You shouldn't refactor, you should clean up!
Comment:
You can refactor when finished, i.e. never.
Extended:
Clean up before and after yourself.
Hint:
You can be many, but you can't be one.