• No results found

Elegance in Software Systems

In document Oops, page not found. (Page 169-173)

I often get the sense that people trained in the humanities have an im-age of computerscientists as Neanderthals with knuckles dragging on the ground. They see ourmismatched clothes and ourtaste forJolt Cola instead of wine as the stigmata of the geek and manifestations of a downtrodden people.

However, the quest for beauty and elegance occupies a substantial place in the hearts and minds of software engineers. There can easily be two programs that solve exactly the same problem, one of which is beau-tiful and the otherof which is ugly. And although beauty is only skin deep, ugliness goes clean to the bone as faras software is concerned.

What goes into making a beautiful program?

Readability – An understandable program is a pretty program. Explain-ing what makes programs readable is as easy (and hard) as it is to ex-plain what makes English text readable. You have to break the program properly into files and subroutines, which are analogous to chapters and paragraphs in English. You have to add meaningful documentation

and variable names much as you have to define any unusual vocabu-lary for the reader. You have to structure the program properly on the page just as you must use the proper fonts and formatting for your English document.

The importance of readable programs is emphasized by an Inter-net tradition, the annual International Obfuscated C Code Contest.

The enormously powerful programming language C incorporates the potential to write indecipherable programs. The goal of the Obfuscated C contest is to write short programs that do useful or interesting things but in such a way that no skilled programmer would be able to identify these things are by reading the program. The Best of Show winning program by Carl Banks is a particularly outstanding combination of beauty and illegibility. To see otherinspiring winners, visit the con-test’s official WWW page at http://www.ioccc.org/.

Comparing this code with that of our Monte Carlo simulation should convince you that clarity and legibility have their own beauty – especially if you are trying to make something work.

Creating readable programs is particularly essential in a world in which software gets passed from its author to those charged with main-taining it. Dario’s programs got passed to Meena, who passed them to Roger. Much of the trouble associated with the millennium bug was due to the unreadable programs Generation IX left to Generation X.

Generality – A beautiful program is one that can easily be made to do more than it was intended to do. This is a testament to the soundness of its underlying design more than it is about the programmer’s ambition orthe ability to anticipate what needs will be made of the system in the future.

The distinction between programs and data is a fundamental one;

programs are descriptions of how to do something, whereas data is a passive entity being acted on. In a well-written program, we can easily change the data without changing the program acting on it.

A good word processor can be used to edit English as well as Chi-nese text, computerprogram source code as well as tables of num-bers. The key is thinking generally enough about the task at hand to encompass a broader set of goals than may originally have been conceived.

An example of the quest forgenerality was Roger’s rewrite of Meena’s programs to tabulate statistics for each different type of bet – win,

#include <math.h>

XOpenDisplay( 0); z=RootWindow(e, 0); for (XSetForeground (e,k=XCreateGC (e,z,0,0) ,BlackPixel(e,0))

; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400, 0,0,WhitePixel(e,0) ) ,KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt∗1e6}

; K= cos(j); N=1e4; M+= H-; Z=D∗K; F+=-∗P; r=E∗K; W=cos( O); m=K∗W; H=K∗T; O+=D∗-∗F/ K+d/K∗E∗-; B=

sin(j); a=B∗T∗D-E∗W; XClearWindow(e,z); t=T∗E+ D∗B∗W; j+=d∗-∗D--∗F∗E; P=W∗E∗B-T∗D; for (o+=(I=D∗W+E

∗T∗B,E∗d/K ∗B+v+B/K∗F∗D)∗-; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D∗m-B∗T-H∗E; if(p [n]+w[ p]+p[s ]== 0|K <fabs(W=T∗r-I∗E +D∗P) |fabs(D=t ∗D+Z ∗T-a ∗E)> K)N=1e4; else{ q=W/K ∗4E2+2e2; C= 2E2+4e2/ K

∗D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=-∗(X∗t +P∗M+m∗1); T=X∗X+ 1∗1+M ∗M;

XDrawString(e,z,k ,20,380,f,17); D=v/1∗15; i+=(B ∗1-M∗r -X∗Z)∗-; for(; XPending(e); u ∗=CS!=N){

XEvent z; XNextEvent(e ,&z);

X-a∗130-J∗ .14)∗ /125e2+F∗ ∗v; P=(T∗(47

∗I-m∗ 52+E∗94 ∗D-t∗.38+u∗.21∗E) /1e2+W∗

179∗v)/2312; select(p=0,0,0,0,&G); v-=(

W∗F-T∗(.63∗m-I∗.086+m∗E∗19-D∗25-.11∗u )/107e2)∗ ; D=cos(o); E=sin(o); } }

Best of Show Winner in the 1998 Obfuscated C Contest – an actual working flight simulator program by Carl Banks.

/∗ Monte Carlo Simulation of Jai-Alai

This program simulates the results of a large number of jai-alai games to see if the Spectacular Seven scoring system inherently favors certain starting positions.

Steven Skiena -- January 18, 1987

Simulation of win, place, and show probabilities as a function of post position.

Dario Vlah -- March 12, 1997

Enhance simulation to support players with non-uniform point win probabilities.

∗/

#define TOTALPLAYERS 8 /∗ number of players per game ∗/

#define TOTALWINPOINTS 7 /∗ number of points to win ∗/

#define MAXLENGTH 100 /∗ maximum length of a game ∗/

int queue[TOTALPLAYERS+1]; /∗ next player queue ∗/

int queuesize; /∗ number of items in the queue ∗/

int p1, p2; /∗ active players ∗/

int points[TOTALPLAYERS+1]; /∗ scoring for a game ∗/

int doublepoint; /∗ how many points until doubling? ∗/

int scoreperpoint; /∗ single or double points? ∗/

int ngames; /∗ number of games in simulation ∗/

int i; /∗ counter ∗/

int results[TOTALPLAYERS+1][TOTALPLAYERS+1][TOTALPLAYERS+1];

/∗ total outcomes ∗/

int wins[TOTALPLAYERS+1], places[TOTALPLAYERS+1],

shows[TOTALPLAYERS+1]; /∗ cumulative outcomes in simulation ∗/

/∗ Added by Dario Vlah ∗/

double winprob[TOTALPLAYERS][TOTALPLAYERS];

/∗ winprob[A][B] is the probability that A wins a point against B ∗/

/ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗/

/∗ This procedure identifies the winner and loser of each point, according to the player win probabilities

∗/

void playpoint(int p1, int p2, int ∗winner, int ∗loser) {

if (random number() > winprob[p1-1][p2-1]) { /∗p2wins point ∗/

∗winner = p2;

/∗ Add the given player to the bottom of the queue.∗/

void addtoqueue(int loser) { queuesize = queuesize + 1;

queue[queuesize] = loser;

}

An initial section of our Monte Carlo jai-alai simulator program.

place, show, exacta, quiniela, and trifecta. Once Meena got the first program working (say to calculate win statistics), she basically copied this program and changed the word “win” everywhere it appeared to

“show”. She then repeated this process five times to build six sepa-rate programs, each computing results for one type of statistic. This was a reasonable response at the time to an unreasonable professor who wanted results yesterday, but this approach was not conducive to building small, reliable programs.

Rogerlooked at all six of the slightly varying programs and replaced them by a single program that did the right thing for each by only changing one word in a data file, say from “win” to “show”. This made the program much more general, because we could add functionality to all bet types by changing one program file instead of requiring us to make the change to all six of them. Roger’s change shortened the program by several hundred lines, and you can’t have bugs in lines you don’t have.

Robustness – A pretty program is robust and reliable. It detects prob-lems like faulty orunexpected data without crashing and burning.

Instead, it smoothly compensates forthe defective data and alerts the useras to the nature of the problem.

Anticipating the unexpected and developing a plan to respond to it are hallmarks of a top-notch programmer. I have said before that a good programmer must be paranoid, but that is not enough. You cannot get trapped in conspiracy theories, frozen by the impossibility of looking everywhere and seeing everything. You must be creative enough to eliminate the causes of yourparanoia, orat least bottle them up so these demons are constrained to a small part of the system.

In document Oops, page not found. (Page 169-173)