Sunday, May 9, 2010

The single return point hypothesis

For many people it seems natural that functions (or methods) should have a unique point of return. To me it seems like a constraint imposed on problem resolution implementation that has the danger of reducing the understanding of the code.


OTOH, I consider that avoiding multiple return points IS programming to please some notion of 'structured' or to simplify work for the machine. Code readability usually suffers with those constraints, and functional structuring "magic" does not always simplify it (I think). Maybe, that code is more 'unified' and easier to reason about by compilers, optimizers ... but not to be READ by (untrained) humans. There are such things as base / recursive cases, early or fast returns for some (human) reason ... Maybe you miss postconditions?

I conducted an informal survey of the "best" implementation of linear search over an array of ints in Java (a beginner example). As a measure of simplicity we took the number of JVM instructions needed to implement the algorithm.

Code samples: (May 2010)

A. University code (30 to 35 instructions)


public static boolean exists(int [] data, int value) {
boolean matched = false;
for (int i=0; !matched && i< data.length; i++)
matched = value == data[i];
return matched;
}


There are variations on this one: going up or down, putting an if to avoid updating matched when the value is still false. They all have in common the use of a local boolean and the mixing of array limits with the found logic.




B. Spartan code (24 instructions)


boolean matches(int[] array, int value, int limit) {
for (int i=0; i < data.length; i++) {
if (value==array[i])
return true;
return false;
}

boolean exists(int [] data, int value) {
int i=0;
while (i < data.length) {
if (value==data[i++])
return true;
}
return false;
}


The above code shows C mastery. Those that think Java can be learned without learning any C are deluding themselves.

C. Professional code (20 instructions)

public static boolean exists(int [] data, int value) {
return Arrays.asList(data).contains(value);
}


The above code shows the user knows Java but has not kept up-to-date (generics and arrays). You need to create your own List implementation backed by an int array ...


And where is the single return? It is the one the compiler uses (ireturn, to return a boolean, use javap).
Some people should go to the original articles to understand what structured programming was about.

Sunday, March 1, 2009

Sw is engineering of a higher kind

I´m copying an author I admire for the title of this.

LIE 1 (bad mapping): Writing sw is implementing a paper design
Writing sw is PURE and ONLY design: implementation is what all our tools do, we do not implement anything directly! (this comes from Uncle Bob)
Programmer vs Developer: writing throwaway code is akin to doing pretty pictures of imagined buildings (vs designing and building them)
Sw deals with abstractions using well defined logical constructs. By following the rules of logic we can assure ourselves that a general purpose infrastructure (namely a Universal Turing Machine pseudo implementation or, if you are a "real-world" no-nonsense guy, a computer with an OS) can execute a implementation of that design (the final product of the code we wrote). The implementation is written by compilers, linkers ... and is used with the help of the Hw, OS, and even VM.

LIE 2 (convenient exploitation): Developing sw cannot be engineering
If the previous where true then, by logic engineering is a logical impossibility. If sw dev cannot be engineering THEN nothing can ...
Let's dissolve all the objections usually presented (again and again). Another story (extremely interesting) is if we want/need sw engineering in general ...

- Law, regulation, rights and obligations
We will say this is not an engineered product if you let us say it is not fit for anything ...
We will say this is not engineering so we can do things any way we want (possibly can)
We will call you are junior programmer and give you an H1B visa and some peanuts for your engineering (but I´ll have to manage you as I have an MBA ...). I just hope this crisis teaches us something about the 'virtual' lies we create ...

- Profession, Art, Experimentation or prototyping
Prof: But I like x so it must be either illegal, unhealthy or a hobby
Art: but I just want to do as I please, pretty please ... Ditto
Prot: I have no clue about this but let me try

Sw can be used and applied to as much areas as engineering, but we have lots of engineer types and only a few common ideas about all computable things ...

- Process
Process is a distillation of practice: traditionally sw process has been postulated the other way around. We started to get globally vocal against this in the last decade (extreme, light-weight, adaptive, evolutionary ...).
You cannot use the same process to build a bridge and to build a car: why do you expect the same process to work for a web site and an office suite (other than some very high level vagaries worthy of a con man)?

Historically getting to engineering follows a path: ingenuity, artist, artisan, guild, ...

LIE 3 (libertarian mind-body delusion): But sw is not real, no physical things ...
See point 1: sw development is design, repeat until fully understood.
We can, to a point, liberate ourselves from implementation machinery (compilers, VMs, interpreters, Operating systems, networking sw : infrastructure) that do the dirty implementation job ... And, like all design, we can pile up abstractions, with a cost.

The 1M monkeys typing idea (we are getting close to this ...): A monkey can do a mark on a bar and it will hold the whole wikipedia codified as a very long fraction. So just one monkey (after a few tries) can generate the distilled accumulated knowledge of the whole species ... Like, you know, there is no spoon (we wish).
Copying sw is as inexpensive as copying any other 'paper' plans, the 'theft' is done when you execute it ...
Car builders do not sell to end-users robot factories that allow you to build car designs (too expensive, bad business), but computing sells you the machines and base sw to execute, create and copy sw designs. That´s the computing revolution ...

And engineering of a higher kind is the one you get when you use your engineered tools to engineer betters tools to design and build other 'accepted' engineered products. We seem a bit lost now, but we are doing our job!

Monday, June 9, 2008

Hw vs Sw

Men and women, hawks and doves ...
Hw and Sw are like the ying and yang of the information revolution. Of course, all dualities hide a continuum and literally one cannot live without the other.
People think they understand hw (maybe they do), but I'm pretty sure they do not understand sw (I doubt I do either).
This entry tries to enumerate differences and synergies among both.


Sw predates Hw (in the sense of sw-running hw). Seems perplexing but it is true. It took some time to realize the minimal hw needed for sw to run on it. It is great that (finite) Turing-like hw is enough to run any computable sw.


Hw employs a minimal fragment of the people sw employs.
Hw produces a millionth of the different products sw produces.
Hw evolution has been consistently macro-predicted, the latest models of sw release take fixed points in time with no sure prediction of achieved functionality (but we get some).
Hw mistakes can destroy manufacturers. Sw mistakes have to be labeled as features.
A mistake in a hw piece requires its replacement. A mistake in a sw piece requires a patch write.
We have 2 centuries of experience with mass-produced goods, but only a few decades of sw quality evaluation.
A faulty Hw piece is easy to identify. A faulty Sw piece can take millions of people years to identify.
It is extremely expensive to produce 1 new piece of hw, a mass-market is needed. It is relatively inexpensive to produce a non-complex piece of sw, but it is extremely expensive to grow from it.
Hw duplication is expensive. Sw duplication is almost free.
Hw is Sw that has solidified too early. Sw is Hw that has not been fully debugged yet.
There is not such thing as a bug-free (non-trivial) sw.
Hw platforms change slowly. New sw platforms are developed every few years. (Understand platform as ecosystem, integration ...)
MS is a closed sw platform builder that owns an open hw platform. Apple is a closed hw platform builder that owns a (semi-)open sw platform. Linux is an open sw infrastructure to run sw on multiple hw platforms. (see open/closed, here open can be semi-open)
You can build Hw by componentization, duplication ... You can try to build sw by piling up stuff, but you usually just get a big mess.
Current Hw is no longer execution-predictable. Current sw no longer fits into one's head.
You cannot easily start again with a Hw architecture. You'd do better redesigning your sw architecture (and emulating the old one if needed).
The barriers to entry into Hw are colossal. A monkey with a PC could create good sw.
You can educate a Hw engineer predictably. Education alone cannot produce good Sw engineers.
A Hw engineer can plan his career. A Sw engineer considers himself lucky if he can plan his vacation.
When hw is badly done, only publicity can save you. When sw is badly done, you can get away with murder.
Good Hw guys usually were good mechanical tinkering children. Good Sw guys usually were insufferable philosophical kids.
Hw is provided as is but has full warranty. Sw is tailored to death, but has no warranty whatsoever.
Hw guys are to surgeons as Sw guys are to psychologists.

...