[net.lang] Superstition in Programmers

usenet@abnjh.UUCP (usenet) (12/29/83)

<<>>

>>While this is a glaring example, I've seen others.  In only 30 years, this
>>field has created more than its share of taboos, unjustified beliefs, and
>>religious sentiments.  My own feeling is:  Any rule or rule of thumb that
>>you can't provide good reasons for is probably at least partly wrong.\
>>
>>							-- Jerry
>>					decvax!yale-comix!leichter leichter@yale

I had a friend once, who always said he was going to write a paper
called "Superstition in Programmers" for publication in the psychology
journals.  The story goes that one of BF Skinner's grad students got
bored with using rewards to teach increasingly complex behavior
patterns to pigeons, and wondered what would happen if the pigeons
were rewarded at random, instead of systematicly.  What he found out
was that pigeons are very inclined to generalize from very little
evidence, and that such generalizations are hard to get rid of.
Specifically, if a pigeon got 'rewarded' (by chance) for standing on
one leg in the corner of its cage, it would spend a lot of time
thereafter standing on one leg in the corner of its cage.  The grad
student dubbed these behaviors "superstitions", and published a paper
titled "Superstition in Pigeons".

My friend's thesis was that programmers are not alot smarter than
pigeons, and if the computer rewards them once (by 'correctly' running
their program) for some bizarre behavior (like using a case statement
to add one to a number between ten and fifteen) then they will spend a
lot of time repeating that behavior, against all protestations of
their co-workers who are afflicted with a different set of superstitions.
My friend pointed out that two rich sources of such behaviors are compiler
and operating system bugs.  Programmers find out about a bug, and
devise a "workaround" for it, then continue to use the (complex and
inefficient) workaround long after the original bug has been fixed.

I wonder if this discussion has any relation to the discussion going
on in another newsgroup about people's tendency to find patterns in
sequences of random numbers.

		Rick Thomas
		ihnp4!abnji!rbt
		    or
		ihnp4!abnjh!usenet

minow@decvax.UUCP (Martin Minow) (01/02/84)

My favorite superstition (in my own programming) is to never
use an equality test where a magnitude test could be used.
For example:

	something(count)
	int	count;
	{
		while (count > 0) {
		    stuff(count);
		    count--;
		}
	}

rather than

		while (count != 0) {

This habit -- don't trust the accuracy of the computer -- was
probably instilled in me in my first programming course, which
used Illiac 1.

Martin Minow
decvax!minow

rpw3@fortune.UUCP (01/03/84)

#R:abnjh:-34800:fortune:15100005:000:531
fortune!rpw3    Jan  2 23:44:00 1984

And now that we all have gotten superstitious and use "geq" where we
mean "eql", and "<=0" where we mean "=0", along come Edsger Dijkstra,
David Gries, and others saying "No, no, that makes proving your programs
harder! Make your termination conditions EXACT!"

Ref:	Discipline of Programming (Dijkstra)
	Science of Programming (Gries)

Can't win for losing...

Rob Warnock

UUCP:	{sri-unix,amd70,hpda,harpo,ihnp4,allegra}!fortune!rpw3
DDD:	(415)595-8444
USPS:	Fortune Systems Corp, 101 Twin Dolphins Drive, Redwood City, CA 94065

endres@ittvax.UUCP (Mack Endres) (01/04/84)

<>

The best discussion of programmer superstition of which I'm aware is
in a paper by Dan Freedman of Ethnotech, Inc. The material was first
presented as the keynote address of the 1973 Computer Personnel Research
Conference, and is distributed by Ethnotech as part of their Technical 
Leadership Workshop (A testimonial: well worth the time if you can convince 
someone to pay for it) and is titled "Computer Magic".

Summary:

Anthropologists since Bronislaw Malinowski have observed BOTH the practice
of science (where the people have a great deal of knowledge and control) and
magic (where there are factors not subject to control) in primitive tribes. For
esample, boats are built scientifically but magic is used to provide calm
sailing weather.

Freedman observed and classified several kinds of computer magic practiced by
late night sessions in an acedemic computing center:

Mana- a supernatural force found in an object or individual, for example,
the magical two cards which correct a documentation error are passed around
with no explanation of the error or correction.

Ritual- the magical power is obtained by correctly carrying out a ritual.

Name Magic- by naming the components of our universe, we gain power to
manipulate them.  We are all familiar with this.  

The desire to believe- 
	Q:	"Why does APL read from right to left?"
	A:	"It's more natural"
	or	"..because of the hardware"
	or	"Don't worry about it, just remember..."

Freedman concludes by observing that such magical beliefs must be 
identified early in the education of programmers- particularly important
is knowledge of when differences matter. Magic (and superstition) can
only be combated by science.

Mack Endres (...decvax!ittvax!endres)

ntt@dciem.UUCP (Mark Brader) (01/05/84)

Martin Minow (decvax!minow) writes:

	My favorite superstition (in my own programming) is to never
	use an equality test where a magnitude test could be used.
	For example:

		something(count)
		int	count;
		{
			while (count > 0) {
			    stuff(count);
			    count--;
			}
		}
	...

Actually, this is not entirely a superstition.  It's good insurance against
a runaway program, if the count may be decremented in several places
within the loop; then you don't have to make sure it will always hit 0
at the bottom of the loop.

However, if the count is only decremented once at the bottom of the loop,
then this code may be an example of two other superstitions:  using while
where for would be clearer, and counting downwards to 0 instead of upwards
to how_many_times.

In the spirit of "Software Tools",
Mark Brader

minow@decvax.UUCP (Martin Minow) (01/06/84)

Mark Brader pointed out that my example used a while loop where
a for loop would be more appropriate and that I counted from
a value down to zero where a more tool-oriented approach might
be, say,

	function(max_value)
	int	max_value;
	{
	    register int	count;

	    for (count = 1; count <= max_value; count++) {
		something();	/* count is only a counter */
	    }
	}

Note some interesting "superstitions" that the above illustrates:

1. I used the "fortran" style of loop (1 to N) rather than
   the C style (the count was not used as an index):
	for (count = 0; count < max_value; count++) {

2. I didn't write the loop in a bizarre (C and assembler hacker) fashion
   	while (--max_value >= 0) {
   or (ecch):
	do {			/* We know max_value is non-zero */
	    something();
	} while (--max_value > 0);

Furthermore, I didn't transmit the negative of max_value and
count UP to zero, as I learned on the 7090 of blessed memory.

Speaking of 7090's and superstition.  I always remove the write
ring from a tape as soon as I remove it from a tape drive.
Always.  Without fail.  Tapes with write rings in are writable.
You learned that lesson once.

Martin Minow
decvax!minow

keesan@bbncca.ARPA (Morris Keesan) (01/06/84)

----------------------------
    Actually, I don't consider "counting downwards to 0 instead of upwards to
how_many_times" to be superstitious behaviour, as Mark Brader does.  I do this
myself, but I do it on purpose and with the knowledge of why I do it, which is
that on many (most?) machines, a comparison with zero is cheaper than comparison
with other constants -- that is, the machine instruction takes fewer bytes ior
is faster.  Likewise, I will use comparisons like "i < 0" in favor of    
"i == -1" when possible (e.g. checking for error returns from U*IX system calls)
because I know that checking sign is smaller/faster than comparison to constant.
-- 
					Morris M. Keesan
					{decvax,linus,wjh12}!bbncca!keesan
					keesan @ BBN-UNIX.ARPA

andree@uokvax.UUCP (01/08/84)

#R:abnjh:-34800:uokvax:9000014:000:622
uokvax!andree    Jan  6 21:26:00 1984

/***** uokvax:net.lang / decvax!minow /  8:31 pm  Jan  4, 1984 */
My favorite superstition (in my own programming) is to never
use an equality test where a magnitude test could be used.

Martin Minow
decvax!minow
/* ---------- */

This is not a superstition. Consider the following:

	float	iter;
	for (iter = 0.0; iter != 1.0; iter += 0.1)
		stuff(iter) ;

On almost every computer around, this code WILL NOT TERMINATE. Something
about most floating point systems not realizing that 10 * .1 = 1. Or maybe
it has to do with the fact that you can't represent .1 in binary (or hex,
for those of you on IBM hardware).

	<mike

alan@apollo.UUCP (Alan Lehotsky) (01/09/84)

-------------
On the subject of "down-counting" and comparisons such as
"x<0" versus "x=-1", a good compiler would analyze what you
did and write the optimal tests in many situations.

I say this, because VAX-11 BLISS does exactly this trick.  This
kind of thing is exactly what I have against C, in that it is
a language for optimizing programmers; in that it encourages
the programmer to have a model of the machine which supports
such notions as auto-increment and decrement (which may not have
hardware support!), user-declared REGISTERs, rather than just
letting the compiler figure out what the best things in
registers would be, etc...  BLISS allowed you to do all these
things, if you were either PERVERSE, or actually smarter than
the compiler.  It's just that you got good code EVEN when you
didn't have intimate knowledge of the machine architecture.
And furthermore, when you recompiled using BLISS-36 (for the DEC-10)
or BLISS-16 (for the PDP-11), you still got good code!

ntt@dciem.UUCP (Mark Brader) (01/09/84)

Morris M. Keesan (bbncca!keesan) writes:
	Actually, I don't consider "counting downwards to 0 instead of upwards
	to how_many_times" to be superstitious behaviour, as Mark Brader does.
	I do this myself, but I do it on purpose and with the knowledge of why
	I do it, which is that on many (most?) machines, a comparison with
	zero is cheaper than comparison with other constants.

True enough, but... using code that is the most efficient, rather than the
*clearest to read*, is still superstitious behavior *unless* you have good
reason to expect that the program will spend enough time executing that
code, or will be critical enough for space, to make a difference.
When efficiency matters, of course, one does what is necessary.

I don't claim to be free from this practice myself -- that's how I
know about it.

In the spirit of "Software Tools",
Mark Brader

bob@onyx.UUCP (Bob Toxen) (01/12/84)

The reason why C programs count down to zero is that it generates
more efficient code on the PDP-11 (and most other computers).

preece@uicsl.UUCP (01/17/84)

#R:abnjh:-34800:uicsl:6200006:000:430
uicsl!preece    Jan 16 08:10:00 1984

I don't think counting down to zero is any more or less clearer, in
most cases, than counting up to some number.  When I'm performing an
iterative task manually, I often count the number of iterations
remaining rather than the number I've done.  People seem to do
this fairly naturally ("Only five more days until vacation," "the
Dodgers are only three outs away from the pennant," etc.).

scott preece
ihnp4!uiucdcs!uicsl!preece

decot@cwruecmp.UUCP (Dave Decot) (01/18/84)

I was formerly "for" the use of inequalities where equality is meant, but now
I am against it.  Although I don't understand how using them makes proving
correctness any harder, I disagree with their use on the ground that such use
is too fault-tolerant.  Off-by-one bugs are much more difficult to find
than those that cause "run-away" execution.

Dave Decot
decvax!cwruecmp!decot    (Decot.Case@rand-relay)

ags@pucc-k (Seaman) (01/18/84)

. <--  <The latest superstition?>

-- 

				Dave Seaman
				..!pur-ee!pucc-k:ags

guy@rlgvax.UUCP (Guy Harris) (01/20/84)

If you mean "is the sticking in of the ritual 'line that doesn't begin
with a blank or tab' at the front of an article whose first line would
otherwise begin with a tab the latest superstition", the answer is no.
It's not a superstition; several articles which have come through in the
past couple of weeks have been truncated.  It's a writearound; i.e., something
that really shouldn't have to be done which is being done to get around a
bug.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

liz@umcp-cs.UUCP (01/20/84)

x <- bug killer!

Ah, but the above is indeed a superstition -- especially when people
use it in an article like this which would not start with a blank
even if the bug killer was not there...  You see, this all started
out as a warning that you better not start an article with a blank
or tab and became a rule that you better always start with a bug
killer just to be sure.  Now, the bug has probably been fixed(*),
but no one is ready to trust it yet, so we continue to use bug
killers -- just to be safe, just because we're still suspicious or
superstitious or something...

Anyone care to generalize from this "superstitious behavior"?

				-Liz Allen

(*) Someone did post an article on net.news somewhere saying the
bug seemed to be fixed...
-- 
Univ of Maryland, College Park MD	
Usenet:   ...!seismo!umcp-cs!liz
Arpanet:  liz%umcp-cs@CSNet-Relay

andree@uokvax.UUCP (01/21/84)

#R:abnjh:-34800:uokvax:9000020:000:1555
uokvax!andree    Jan 19 19:02:00 1984

/***** uokvax:net.lang / bbncca!keesan /  4:45 pm  Jan 10, 1984 */
----------------------------
    Actually, I don't consider "counting downwards to 0 instead of upwards to
how_many_times" to be superstitious behaviour, as Mark Brader does.  I do this
myself, but I do it on purpose and with the knowledge of why I do it, which is
that on many (most?) machines, a comparison with zero is cheaper than comparison
with other constants -- that is, the machine instruction takes fewer bytes ior
is faster.  Likewise, I will use comparisons like "i < 0" in favor of    
"i == -1" when possible (e.g. checking for error returns from U*IX system calls)
because I know that checking sign is smaller/faster than comparison to constant.
-- 
					Morris M. Keesan
					{decvax,linus,wjh12}!bbncca!keesan
					keesan @ BBN-UNIX.ARPA
/* ---------- */

Ahh, yes, the good old "trying to outsmart the compiler" kludge. Are you sure
that what you are doing is faster for ALL compilers, and ALL machines? Take
a look at Kernighan & Plaugher's "Elements of Programming Style" (I THINK
thats where it's at) for an example of that kind of thing. Turns out that
on the compilers they tested, it either didn't make any difference, or made
the code run SLOWER!

This kind of thing belongs in the compiler. I don't know what PCC does
for any specific machine, but at least one z80 C compiler maps x == -1
into (x + 1) == 0, as the comparison is faster. I think the result is
even faster than the code generated for x < 0.

	"Let the compiler do the simple optimizations"
	<mike

stanwyck@ihuxr.UUCP (01/23/84)

In response to liz @ U of MD, the bug is not yet fixed everywhere.  Just
today I read in net.jobs the last few lines of some job offer.  Poor company
wasn't even able to announce the things it wanted in the way of an employee.
So, for now at least, I strongly encourage the use of non-white-space
characters at the start of the first line.  (Or do as I do, and start each
article fully left-justified.  You can get far more on the screen that way.)
-- 
 ________
 (      )					Don Stanwyck
@( o  o )@					312-979-3062
 (  ||  )					Cornet-367-3062
 ( \__/ )					ihnp4!ihuxr!stanwyck
 (______)					Bell Labs @ Naperville, IL

aaw@pyuxss.UUCP (Aaron Werman) (02/03/84)

About use of stronger comparisons in programming.

The point of comparisons is partitioning objects. Clearly, the
partitions do not hold if the comparison operators are changed.
This makes proof, etc. unnatural.


so why not:

	for (i=0; i != max; ++i) {assert(i<max); action();}

instead of:
	for (i=0; i <= max; ++i) action();

<except for the verbose ugliness>
			{harpo,houxm,ihnp4}!pyuxss!aaw
			Aaron Werman