Ought to add a footnote to the entry, noting that the person who brought
it to Eric S. Raymond's attention was the same vigilant fellow who informed
a congressman that the Soviet Union was on the net.
--
| b...@epmooch.UUCP (Ben Mesander) | "Cash is more important than |
| ben%serval...@uokmax.ecn.uoknor.edu | your mother." - Al Shugart, |
| !chinet!uokmax!servalan!epmooch!ben | CEO, Seagate Technologies |
>A student of mine, Kent Williams, recently used a term that is new to me
>and might be worthy of inclusion in the jargon file.
>cargo-cult programming -- a style of programming dominated by ritual
> inclusion of code or program structures that serve no real purpose.
> A cargo-cult programmer will usually explain the extra code as a
> way of working around some bug encountered in the past, but usually,
> neither the bug nor the reason the code avoided the bug were ever
> fully understood (see shotgun debugging).
I wouldn't say this is jargon yet, but I like it. I would say it's even
better than the "cargo-cult science" that Feynman talked about. Credit
should be given to Feynman as well, but this is better.
I would like to suggest a further improvement:
A cargo-cult programmer often will not know the purpose of the extra
code, though some might explain it as a way of working around some bug...
> The term cargo-cult is a reference to aboriginal religions that
> grew up after World War II. The practices of these cults center
> on building elaborate mockups of airplanes and military style
> landing strips in the hope of bringing the return of the god-like
> airplanes that brought such marvelous cargo during the war.
Yes, this is Feynman's explanation for his definition of "cargo-cult
science." It fits "cargo-cult programming" so much better.
--
Norman Diamond dia...@tkov50.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.
As an example, people who ritually include:
TEST CSECT TES00040
STM R14,R12,12(R13) Save Registers TES00050
LR R12,R15 Load Base Register TES00060
USING TEST,R12 Establish Addressability TES00070
BAL R15,SAVEAREA+18*4 Branch around Savearea TES00080
SAVEAREA DS 18F 18 Fullword Savearea TES00090
ST R13,4(R15) Pointer to previous Savearea TES00100
ST R15,8(R13) Pointer to this Savearea TES00110
LR R13,R15 Load Address of our Savearea TES00120
0
and
RETURN L R13,4(R13) Restore Caller's R13 TES00240
L R14,12(R13) Restore Caller's R14 TES00250
L R0,20(R13) Restore Caller's R0 TES00260
LM R2,R12,28(R13) Restore Caller's R2-R12 TES00270
BR R14 Return to Caller TES00280
in subroutines that don't call other subroutines.
-jms
Oh, let's not be a twit, hm? In this day and age, considering that the
Eastern half of the world had opened considerably, even if not completely,
and considering the state of the rest of the world at this point, I'm sure
that congressmen have much more to worry about than whether or not the
Soviet Union is on the net.
This isn't computer folklore; followups are directed to alt.flame.
>
>--
>| b...@epmooch.UUCP (Ben Mesander) | "Cash is more important than |
>| ben%serval...@uokmax.ecn.uoknor.edu | your mother." - Al Shugart, |
>| !chinet!uokmax!servalan!epmooch!ben | CEO, Seagate Technologies |
--
On the 'Net: Why are more and more fourth-level wizard(-wannabe)s trying to
invoke ninth-level magic, instead of taking the time to climb the other
(quite essential) thirteen levels so they can do this properly?
...!{ucbvax,acad,uunet,amdahl,pyramid}!unisoft!greywolf
The minimum procedure frame looked like this. A7 is the stack pointer, A6 the
frame pointer (both are changed by the LINK), A5 points to the global
variables and is in fact never changed (and if a subroutine changed it it
wouldn't work anyway), and the FMOVEM.X instructions are a very expensive way
to tell the FPU (or the FPU emulator) to do nothing:
xyzzy LINK -#something, A6
MOVEM.L <A5-A7>,something(A6)
FMOVEM.X <>,somethingElse(A6) ; do not save any FPU registers
...
... ; actual code, heavily pessimized by the compiler
...
FMOVEM.X somethingElse(A6),<> ; and don't restore them either
MOVEM.L something(A6),<A5-A7>
UNLINK A6
MOVE.L D0,A0 ; another horrible kludge shows its ugly head
RTS
--
Matthias Urlichs -- url...@smurf.sub.org -- url...@smurf.ira.uka.de /(o\
Humboldtstrasse 7 - 7500 Karlsruhe 1 - FRG -- +49+721+621127(0700-2330) \o)/
>> cargo-cult programming -- a style of programming dominated by ritual
>> inclusion of code or program structures that serve no real purpose.
>> A cargo-cult programmer will usually explain the extra code as a
>> way of working around some bug encountered in the past, but usually,
>> neither the bug nor the reason the code avoided the bug were ever
>> fully understood (see shotgun debugging).
> As an example, people who ritually include:
[standard IBM 370 Assembler entry and exit sequence for S-type linkage]
> in subroutines that don't call other subroutines.
That can be defended on the grounds of maintainability. You never know
when you're going to modify a subroutine so that it *does* call other
subroutines. Most people have macros for ENTER and EXIT, and it's
silly not to use them. Many people also have other macros that may
or may not call other subroutines.
A better example might be the following code, which I put at the
beginning of programs that run as shells for certain logins:
strcpy(getenv("SHELL"),"SHELL=/bin/sh");
I can't remember what problem this fixes, why it's a call to getenv
and not putenv, or whose memory it's stomping on. If it ever
becomes important, I'll figure it out.
"Customs are the solutions to problems long forgotten."
-- Ben Kingsley
Mark Israel
user...@mts.ucs.ualberta.ca
>in subroutines that don't call other subroutines.
Maintainability is an EXCELLENT reason for using standard entry/exit sequences.
(Even better would be to use standard ENTER/RETURN/EXIT macros.) My experience
with big projects suggests that software shouldn't trust where it's called from
nor what it calls. Too many hands in the pie make a sticky mess.
A different but related reason is that many automated debugging aids,
dump interpreters, and the like can't tell you where they are unless
they can find a nearby standard entry or exit. A favorite example is
IBM's 'null program' (IEFBR14, needed as filler in some JCL decks, to
provide a null job step to hang things on) was originally only 1
instruction, 'BR 14', which idiomatically is 'return'. It had
something on the order of a dozen or two bug reports filed against it,
as it prevented a number of debuggers, tracers, profilers, and 3rd
party analysers from working correctly in jobs where it was used. It
has now grown into a 'standard' IBM program, complete with headers and
trailers. Still doesn't DO anything, but it does it right, now.
(As folklore, I strongly suspect that it holds the world record for
density of 'bugs per instruction', especially if you take its original
size as the appropriate instruction count.)
--
Paul Smee, Computing Service, University of Bristol, Bristol BS8 1UD, UK
P.S...@bristol.ac.uk - ..!uunet!ukc!bsmail!p.smee - Tel +44 272 303132
A related story of bugs in IEFBR14 has the earliest OS release with an
IEFBR14 with a single instruction:
BR 14 Return to system.
This introduced a bug, in that the exit was taken with a non-zero return
code in R15 (Which was actually the address that IEFBR14 was loaded at).
This caused problems with JCL condition code (IBMish for return code)
testing later in the job stream. IBM took an APAR, and the fix added
1 instruction. IEFBR14 now reads:
SR 15,15 Zero the return code
BR 14 Return to system
This fix doubled the number of executable instructions in the program.
How is that for a record?
(Of course the fix did not double the number of lines of code. Both of the
examples I showed need a CSECT or START, and an END assembler directives,
and the official IBM source had at least several pages of comments.)
Rich
IEFBR14 is more than just filler, though you're right about its basic
construction. BR14, as some of us old IBM hacks call it, is used
to do such things as create partitioned datasets prior to use in
later jobs or jobsteps (you must have already created the PDS in
order to actually open a member of it). BR14 is also used to delete
datasets, if you can believe that a null program can do such a thing.
Actually, of course, the operating system does the actual creation
or deleting, but in IBM MVS JCL the jobstep must contain an actual
executable program.
> [there were] a dozen or two bug reports filed against it,
>as it prevented a number of debuggers, tracers, profilers, and 3rd
>party analysers from working correctly in jobs where it was used. It
>has now grown into a 'standard' IBM program, complete with headers and
>trailers. Still doesn't DO anything, but it does it right, now.
Debuggers? Tracers? On MVS? What ever happened to the good old
//SYSUDUMP DD SYSOUT=*
statement? Nothing like dragging a fat 50,000 line core dump
back to the office to get the heart started in the morning. :-)
spl (the p stands for
perish the thought!)
--
Steve Lamont, SciViGuy -- (408) 646-2572 -- a guest at network.ucsd.edu --
NPS Confuser Center / Code 51 / Naval Postgraduate School / Monterey, CA 93943
"Unix is not a "A-ha" experience, it is more of a "holy-shit" experience."
- Colin McFadyen in alt.folklore.computers
I wonder what versions 1.1 through 1.4 looked like.
On HP-UX /bin/true looks like this:
# @(#) $Revision: 64.1 $
exit 0
Revision 64.1, gack! Or is this an inside joke?
--
Tor Lillqvist,
working, but not speaking, for the Technical Research Centre of Finland
More likely it's the NUXI problem, and it should be 1.46. On the other
hand, that still means 46 revisions minimum (better than 64, but...).
ObFolklore:
(For those who don't recall the apocryphal tale of booting UNIX for the
1st time on the Interdata 8/32, consider how many possible byte
orderings there are for 32-bit word oriented machines. When that UNIX
was booted, it announced itself as "NUXI" on the console.... I do
recall seeing that machine, but am unable to come up with a time frame
any better than "between 1976 and 1990" (the memory is the 2nd thing to
go -- I don't remember what the 1st is, though).)
(For the humor impaired: (-: I'm quite aware that RCS stores the
revision numbers in such a way that NUXI doesn't apply.)
--
Marty Shannon; AT&T Bell Labs; Liberty Corner, NJ, USA
(Affiliation is given for identification only:
I don't speak for them; they don't speak for me.)
Out of curiousity and boredom, I decided to look at the contents of /bin/true
and /bin/false on an RS/6000 workstation. To my surprise, neither of these
beasties are shell scripts:
lager.spl file /bin/true /bin/false
/bin/true: executable (RISC System/6000 V3.1) or object module
/bin/false: executable (RISC System/6000 V3.1) or object module
lager.spl ls -l /bin/true /bin/false
-r-xr-xr-x 1 bin bin 1850 Jul 20 1990 /bin/false*
-r-xr-xr-x 1 bin bin 1850 Jul 20 1990 /bin/true*
Why does this somehow not surprise me?
spl (the p stands for
probably some good
marketing reason for
this...)