検索対象: The Best Software Writing I. Selected and Introduced by Joel Spolsky
PAUL FORD 81 Languages like those mentioned previously reward study because they represent the place where aesthetics touches computation—ln CSound, for instance, there is a score file and an orchestra file; the orchestra contarns a set Of instruments, WhiCh are made up Of OSCiIIa- tors, sound samples, and all manner Of Other time-bounded constructs: signals, lines, and waves. The score file iS a collection Of beats and vari- ables that are fed tO the instruments. There is a great deal to learn from such a language; it represents a very focused attempt tO identify a cre- atlve grammar that is constrained by three things: ( 1 ) the computer's power t0 effectively manipulate only certain kinds 0f data, ( 2 ) the lan- guage developers' biases and understanding 0f their chosen discipline, and ( 3 ) the willingness of regular programmers to work within the lim- its of ( 1 ) and ( 2 ). l'm not suggesting that everyone learn these languages, but if, like me, you're interested in understanding what computers can do with media, and the cultural factors that go into building t001S that create media on computers, you'll find that these languages are fascinat- ing objects t0 study. CSound was the first programming language I learned, in 1996 , using online documentation Of such spotty quality that I was sent tO the library to better understand oscillator theory and the differences between additive, subtractive, and granular syntheses, finally building a homegrown oscilloscope out Of an 01d TV in order tO see the patterns Of energy inherent in the sound, trying tO understand why a camel-backed S1ne wave sounded SO different from a sawtooth wave's Matterhorn. One CSound file I compiled took 20 hours to build, because there were tens Of thousands Of interactlng instruments, manipulating each Other, reverbrating all over the spectrum 0f audible sound. lt sounded dreadful; I am not a good muslcian. But it was fascinating tO 100k inside sound through that small language. When 1 100k at Processing, I see much that I learned from CSound translated tO the visual realm (Processing supports sound, but only minl- mally). The oscillator in CSound is like a "for" 100P in Processing; in the COde I posted yesterday, squares rotate around a fixed point, each frame moving the squares forward a few pixels. ln CSound I might define a series Of oscillators that modulated one another; one oscillator's changing values might add tremolo tO another oscillator's noisy chord. ln processing, looping values can be added tO one another (with some data inserted from the mouse or Other sources) that, instead Of adding some
ERIC JOHNSON 131 The C programming language fit very naturally int0 this small, tran- quil world. On most systems, C functions could call into FORTRAN and vice versa. ln any glven system, C could be the dominant, the sub- ordinate, or the equal with its peers in a development context. Why is this so important? Because for any new technology to take root, it must successfully leverage existing legacy intO which the con- tender wants tO take over,. That's just a fancy way Of saying that it can't require an orgamzatlon tO rewrlte everything from scratch. Leverage what's already there, and you're a helpful contributor. SO C comes as a helper.What makes C 十 十 SO fascinating is that it first emerges as a helper, but with enough encouragement, it's transformed intO the conqueror and eventually the new master tO which all must yield. The C + + language was purposefully designed to subsume as much of the existing C language as possible. Only the most observant C + + language lawyer can articulate the areas in which C compatibility was not kept. SO what does such 、 。 subsumption" get you ~ Existing C developers could be dropped, almost entirely unaware, intO a C 十 十 compiler. Yes, there were performance differences in those early days, and yes, C + + compilers have a cranky streak t0 them. Most C developers could be guilted into accepting such pedantic 、 varmngs. Those random warmngs about undeclared functions always gnawed away at their consclence late at night anyway. And if that didn't get them, the high-falutin' talk 0f the wondrous powers 0f object- oriented programming shamed them intO using the compiler. But in reality, all this meant was that existing C developers would contlnue tO write C and merely append a few more letters tO their com- piler invocations and their world wasn't different. NOt yet. But the trap was set. C 十 十 made the switching easler SInce it easily consumed all Of the functionality in an existing C domain. There was nothing tO rewrite. The only real code change t0 make was t0 declare those old-school functions with their "extern magIC and C 十 + could easily consume them. ln years before, interoperability between a C function and a FOR- TRAN function required a little bit of thought and some understanding of how the two worlds work. How would floating-point values be passed? ls it pass by value or pass by reference? HOW d0 B001ean return values map between the two? C + + worked differently. Heck, it just worked.
80 THE BEST SOFTWARE WRITING I bare-bones but clever IDE that allows you to click "play" to compile your applet. Processing s programming constructs are consistent and well thought out—essentially simplified Java, although "simplified" is the wrong word; it might be better tO say "elegantized, " because the authors Of Processing have identified a target audience—geeky artists—and have created something out Of Java's baroque envlronment that geeky artists can learn quickly and explore immediately; they've whittled down Java's carved-oak throne intO a SliCk, SWiSS sling-back chair on an aluminum frame. y am I discussing this here?l have a passlon, which I do not discuss in polite or easily bored company,5 for languages like processing— computer languages that compile not tO executable COde but tO aesthetic objects, whether pictures, songs, demos, or websites. Doma1n-specific languages like this include CSound, which compiles t0 sound files; POV-Ray, which compiles to 3D images; TeX, which compiles to typo- graphically consistent manuscripts; or SVG (Scalable Vector Graphics), an XML schema that creates vector graphics. There are more general-purpose languages that are focused on meet- ing the needs 0f a particular kind 0f programmer: ActionScript undergirds Macromedia's Flash, and is ubiquitous across the Web; Graham Nelson's lnform, with its large library of community-developed enhancements, compiles tO lnteractive text adventures. At the far end of the spectrum are totally generallanguages like C, Java, Perl, and Python, languages that are intended tO let you dO anything a computer can dO. Processing lives somewhere between the former and the latter kinds Of languages—lt is, in one way, a general-purpose programming lan- guage (particularly as it can call any Java function), but it is also constrained by a very small set Of primitlves—polnts, spheres, rectan- gles, etc. —and a straightforward model 0f 3D space, and it compiles to a very specific kind 0f object: an interactive graphical widget. processing is most like lnform ln its focus on a specific goal: lnform would not be useful if you wanted tO write a word processor, nor would Processing. But if you want tO create a text adventure, lnform is a solid choice, much better than raw C, and if you want to create a 200X200 clickable thingy, Processing is a pretty good bet. 5. Now you know how I see my audience.
300 INDEX performance measurement, 157 performance ranking team development, 158 Perl programming, 101 permalinks, 29 Peters, Chris, 174 Pfeffer, Jeffrey, 169 PHP, 27 Pilgrim, Mark, 114 Plato BBS system, 185 pomt-to-polnt t 、 vo-way 151 , commumcation, pre-lnternet, 185 political influences lll software success, 171 ー 72 PowerPoint, why it's bad, 262 , 264 Probst, Larry, 65 Processing programnung language, 79 ー 81 product development schedule overruns, 145 product/program managers, 144 professional VS. amateur programming, 135 programmers lnterestlng work as motivation for, 98 , 101 management of, 97 , 101 and money, 97 productivity of, 97 vs. real world in pictures, 17 values Of as basis for software, 40 programmmg precislon vs. flexibility, 27 programming language as medium Of expression, 99 programming language b00k trends, 267 programming style as required language syntax, 27 , 6 punctuation in, 269 ー 70 programs as aesthetic objects, 80 Python executable pseudocode, 73 and great programming, 95 , 98 syntax, 72 use Of whitespace, 1 quality costs, getting programming right, 137 Raikes, Jeff, 174 ranking, 0f employees, 159 RDF, 27 reading programming code aloud for understanding, 269 ー 70 Representational State Transfer (REST), 86 ー 87 reqmrement for verSIOn control and bug tracking tools, 143 responsive SOft 、 sales success factors, 234 customer commumty support, 242 customer product awareness, 235 demo availability, 240 making web buying easy, 243
4 THE BEST SOFTWARE ・ WRITING I Think of it. AII the programming examples in one style. Web pages, Journals, papers, emails use one style. Reformatting issues gone. Arguments over whose style is better gone. Reformatters become a quaint historical artifact. And most of all: NO MO S り Ⅳ 4 ! Really! Think of all those cycles that we could then plOW intO something more productive, like vi/emacs wars! Or world peace! Or a 4 〃 ア good chocolate cookie recipe! You choose! Of course, you will never enforce any style globally unless people have literally no chOice. HOW many C programmers use "during" as a stylistic preference tO the keyword ? (Preprocessor abusers need not apply. On second thought, please do: We need t0 identify you for our eugemcs program. ) Or skip the parentheses around an if clause? They don't because they が た You know some would if they cou 旧 . The thing that stops these "personal styles" is that the C compiler will not accept them. If you can't compile your code you fix it. lt's so simple it's stupid. And therefore it works. SO I want the owners of language standards tO take this up. I want the next verSIOn Of these languages tO require any COde that uses new features tO conform tO some style. Let the standards committees gnash and snarl and wring their hands over which Of the common styles iS the W1nner. Sell tickets. 嶬 み e all get t0 comment and the language standards geeks decide. We know where they'll go—C will go t0 K&R; C + + will go with Bjarne's style (excuse me while I cringe); Java will go with the Sun style as shown in the language spec and most 0f the Java b00ks from Sun (including mine); Lisp style is almost already set mostly in stone. perl is a vast swamp of lexical and syntactic swill and nobody knows hOW tO format even their own COde well, but it's the only major language I can think 0f (with the possible exception 0f the recent, yet very Java- like (#) that doesn't have at least one style that's good enough. Some things are either uncheckable (Hungarian notation, using get" and "set" method prefixes) or not widely agreed upon (such as import/#include ordering). These can be left for future standards. Or not. The owners of the standard decide. But whatever they d0, they should set the style and build it into the actual freakin' grammar ・ ThiS heresy encompasses one major sub-heresy: That whitespace should matter. MOSt style rules have tO dO with the placement Of whitespace: new- lines before or after curly braces, whitespace around operators or not,
BRUCE ECKEL 75 expression Of concepts is simply not worth the danger—even if that ben- efit is a productivity increase Of 5 tO 10 times over that Of Java or C 十 十 . What happens when such a problem occurs in a Python program— an object somehow gets where it shouldn't be? Python reports all errors as exceptions, like Java and C# do and like C + + ought to do. So you do find out that there's a problem, but it's virtually always at runtime. "Aha ! " you say, "There's your problem: you can't guarantee the correctness Of your program because you don't have the necessary C01 れ - pile-time type checking. When I wrote T ん 〃 た g C + + , 7 計 E 市 行 0 〃 (Prentice Hall PTR, 1998 ) , I incorporated a very crude form of testing: I wrote a program that would automatically extract all the code from the book (using com- ment markers placed in the code t0 find the beginning and ending of each listing), and then build makefiles that would compile all the code. This way I could guarantee that all the code in my books compiled and so, I reasoned, I could say, "lf it's in the book, it's correct. '' I ignored the naggmg VOice that said, 、 。 Compiling doesn't mean lt executes properly, because it was a big step tO automate the COde verification in the first place ()s anyone wh0 100kS at programming books knows, many authors still don't put much effort intO verifying COde correctness). But naturally, some 0f the examples didn't run right, and when enough of these were reported over the years I began tO realize I could no longer ignore the issue Of testing. I came tO feel SO strongly about this that in the third edition of T ん 〃 た g ル , I wrote: lfit's not tested, it's broken. That is to say, if a program compiles in a statically typed language, it just means that it has passed some tests. lt means that the syntax is guar- anteed tO be correct (Python checks syntax at compile time as well— Just doesn't have as many syntax constraints). But there's no guarantee Of correctness just because the compiler passes your code. If your code seems tO run, that's alSO no guarantee Of correctness. The only guarantee of correctness, regardless of whether your lan- guage is statically or dynamically typed, is whether it passes all the tests that d 〃 〃 舫 じ 0 e じ ビ ss 0 ー ア 0 〃 r 々 og 川 . And you have tO write some Of those tests yourself. These, Of course, are unit tests, acceptance tests,
BRUCE ECKEL 50 川 ビ 坊 / れ g 〃 た ビ 4 川 ~ れ 〃 0 ー ル 0 for 舫 な れ た e 。 。 d ) 〃 4 襯 た 一 ) 々 / れ g ー 4 ー 〃 e. 1 ー ア 0 ″ ン e 〃 れ れ / れ g 4 ー 4 ア れ 0 ー ル , e わ S ビ レ ビ S , using 4 d ア れ 4 ′ れ 69 ca 〃 typed れ g 〃 age 川 4 ア 川 れ ル 酣 ) 0 〃 〃 d 〃 怩 れ 襯 お 〃 れ ア S ビ r レ ビ 一 0 5 レ ~ じ ー わ 54 ア れ ビ 〃 〃 ″ 2 わ 0 ー じ 〃 S ー 0 ア れ S , 比 ′ わ / C わ ca 〃 わ 怩 co 計 So do ビ ア 0 〃 r 0 ル 〃 担 dg 川 ビ れ 右 4 わ 0 〃 右 ル わ た d 0 一 々 ん 川 - 4 れ c ビ ア 0 ″ 4 々 々 〃 ca 行 0 〃 ビ 〃 耘 お , わ 〃 ー ア 0 〃 〃 ″ 5 な 々 0 レ / d ビ good co co レ ag ビ , d0 が feel 0 々 4 れ 0 4 わ 0 giving 〃 々 じ 0 川 が ル - 〃 川 ビ 々 ビ 訪 “ た g. ー Ed. n recent years my pnmary interest has become programmer produc- tivity. Programmer cycles are expensive, CPU cycles are cheap, and I believe that we should no longer pay for the latter with the former. HOW can we get maximal leverage on the problems we try tO solve ~ Whenever a new t001 (especially a programming language) appears, that t001 provides some kind Of abstraction that may or may not hide need- less detail from the programmer. I have come, however, tO always be on watch for a Faustian bargain, especially one that trles tO convrnce me tO ignore all the hoops I must jump through in order to achieve this abstraction. Perl is an excellent example Of this—the immediacy Of the language hides the meaningless details 0f building a program, but the unreadable syntax (based, I know, on backward-compatibility with Unix tools like awk, sed, and grep) is a counterproductive price to pay. The last several years have clarified this Faustian bargain in terms of more traditional programming languages and their orientation toward static type checking. This began with a two-month love affair with Perl, which gave me productivity through rapid turnaround. (The affair was terminated because Of Perl's reprehensible treatment Of references and classes; only later did I see the real problems with the syntax. ) lssues 0f static-vs. -dynamic typing were not visible with Perl, since you can't build pr0Jects large enough tO see these issues and the syntax obscures every- thing in smaller programs. After moving t0 Python (free at www.python.org/—a language that じ 4 〃 build large, complex systems—l began noticing that despite an apparent carelessness about type checking, Python programs seemed t0 work
Pa お 0 卍 PROCESSING PROCESSING 1 l've / 0 〃 g わ 〃 4 〃 0 ー Pa お 0 卍 ' ル 訪 , . co 川 . So ル わ e 〃 Apress た d 川 ビ 々 町 g ビ 舫 舫 な わ 00 た ユ た 〃 ル ″ わ ad cl 〃 50 川 ん 〃 g 0 ー わ な . SO 川 ビ 舫 ~ 〃 g 4 わ 0 〃 右 ー わ な 4 た 々 rec な ビ ca 々 右 〃 ビ s 舫 ビ ss ビ れ c ビ 0 ー ル わ 4 右 ー CO 〃 d ビ r ー 0 be 。 ga 〃 c ビ " 50 ″ ル 4 ビ ル 行 〃 g. T, わ cla り 4 〃 d 々 0 ル 〃 〃 & ル ビ 日 〃 4 ど 〃 〃 お 0 ー ル 0 〃 g わ な 舫 川 市 - 〃 0 塒 4 〃 d ル ビ わ あ 黻 わ 郷 ら 訪 0 曜 計 0 々 々 川 ⅲ d - 〃 〃 川 房 〃 g わ 町 / closing 々 4 g 々 あ … ー 舫 た l'm going な get 川 ビ 4 訪 4 E ″ わ ル 酣 it's 4 娵 川 々 ) , わ ル 酣 ' good 0. ー Ed. Late-night thoughts on little computer languages, the Web as a form, and my 0 Ⅵ ′ n lgnorance. 've been fiddling with Processing, a small computer language layered above Java. Processing makes it possible t0 quickly create hopefully interesting images and animations, like last week's Square/Sphere/StatIc or yesterday's Red R0tator.4 SO far l've only dabbled with it, but the sys- tem is engaging, easy t0 learn, and pops up out 0f the zip file with a 1. 2. 3. 4. PauI Ford, "Processing, Processing," Ftrain.com (http : //www.ftrain.com/, September 2 , 2003. See http://www.ftrain.com/ProcessingProcessing.html. See http://processing ・ 0てg/ ・ See http://www.ftrain.com/SquareSphereStatic.htm1#ProcessingProcessing. See http://www.ftrain.com/RotatingSquares.htm1#ProcessingProcessing.
132 THE BEST SOFTWARE WRITING I This gave considerable power to the C + + advocates who would arrive in an existing C organization. They could easily develop new functionality by leveraging the existing code base. They could co-opt the system. They were merely adding a new layer onto the existing edifice. On top 0f this, C + + at least made it feasible to declare functions such that the old-school C geezers could still consume them. Of course, the old C school couldn't get access to the newfangled classes or templates, but that was OK by both parties. Those mangled names that the C + + compiler brought into the world were mildly freakish. The geezers weren't entirely threatened by the C + + upstarts. And if the organization was growing, those old-timers were headed for man- agement real soon any 、 vay, SO it was Just a matter Of time before their protestations for a kinder, gentler world would no longer be heard. lt's at this point in the transformation that C 十 十 flexes lts muscles. This is the tipping point. Not only does it leverage the features of the existing COde base, but it alSO Offers a potpourrl, a smorgasbord, a verl- table endless supply of doodads and useful features that the willing and intelligent developer is able to use. The C + + language never rammed any features down your throat. Let's not confuse the languages stance with that Of the zealots in that commu- nity. You never had to use those OO features if you didn't want to. But they were so tempting, weren't they? They glistened like gold and were SO much fun tO use. You were young. You didn't know any better.. You needed the money. And it was fun t00. C + + looked like it could ful- fill the dreams of programming in the large. At first, the changes start in small ways. The comment style changes. / * * / evolves into / /. Shortly thereafter variable declarations are spnn- kled liberally in the middle of functions. Small and simple. Yet it hit a relevant sweet spot with many developers. Then the inevitable happens. References find their way into function declarations. The inexperienced developer begins to dabble with func- tion overloading, which results in the requisite name mangling. NOW the peer programming languages from the past have a huge barrier tO cross. Structs turn 1ntO classes with virtual functlons. Classes pick up non- trivial constructors, and critical high-level functions start throwing exceptions. Then comes the mind-bending multiple inheritance designs. When this phase appears, the old-school programming languages have no hope 0f participating.