<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-7618424</id><updated>2008-05-11T21:27:42.528-04:00</updated><title type='text'>raganwald</title><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/welcome.html'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default?start-index=26&amp;max-results=25'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>424</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7618424.post-7366845986780312404</id><published>2008-05-06T10:56:00.020-04:00</published><updated>2008-05-08T22:55:10.024-04:00</updated><title type='text'>Why Apple is more expensive than Amazon</title><content type='html'>Let&amp;rsquo;s say you would like to listen to one of the most amazing performances ever made, Glenn Gould&amp;rsquo;s 1981 recording of Bach&amp;rsquo;s &lt;a href="http://en.wikipedia.org/wiki/Goldberg_Variations"&gt;Goldberg Variations&lt;/a&gt;. And let&amp;rsquo;s say you have figured out the DRM is a really terrible idea, so you would like the hear it on high-quality MP3s.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed id="VideoPlayback" style="width:400px;height:326px" flashvars="" src="http://video.google.com/googleplayer.swf?docid=-6984208089899995423&amp;hl=en" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The good news is that there are a number of places to legally purchase the right to download DRM-free MP3s. Lots of music from the major labels is available on Amazon, and it costs the same or less per track than Apple&amp;rsquo;s iTunes Music Store (&amp;ldquo;iTMS&amp;rdquo;), and you can find more DRM-free tracks on Amazon than on iTMS.&lt;br /&gt;&lt;br /&gt;For example, &lt;a href="http://www.amazon.com/gp/product/B0013G2QZ2?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B0013G2QZ2"&gt;Bach: Goldberg Variations, BWV 988&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;l=as2&amp;o=1&amp;a=B0013G2QZ2" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; on 256-bit DRM-free MP3 is just $9.99 from Amazon. The same album is also &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=201258290&amp;s=143455"&gt;$9.99 from Apple&lt;/a&gt;, but you get DRM. And there are tons of tracks on Amazon that are actually &lt;em&gt;less expensive&lt;/em&gt; than on iTMS, so you get better music for less money without the DRM hassle. So is Apple screwing the customers?&lt;br /&gt;&lt;br /&gt;In a word, &lt;em&gt;no&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;The reason you can find more music on Amazon at a lower price is that the Record Labels want it that way. Do you think they charge Apple and Amazon the same price for each track and Apple simply charges you more and pockets the difference as a higher markup? The labels would like you to think that, but they actually charge Amazon less for each track, and that&amp;rsquo;s how Amazon can charge you less.&lt;br /&gt;&lt;br /&gt;Do you think Apple insists on the DRM but Amazon has the vision to see that &lt;a title="Thoughts on Music" href="http://www.apple.com/hotnews/thoughtsonmusic/"&gt;the future of music is DRM-free&lt;/a&gt;? Do you think Jeff Bezos is a better negotiator and he was able to get a better price per track than Steve Jobs? Without putting up with DRM?&lt;br /&gt;&lt;br /&gt;Really? How does that work, when iTMS is now the third-largest music retailer in the United States? How does the lower-volume store get better selection with fewer hassles and negotiate lower prices from its suppliers? When Steve Ballmer&amp;mdash;not an easy man to intimidate&amp;mdash;asked them for music to put in his Zune marketplace, these nice people extorted a $5 tax on each Zune sold from him. So how did Amazon get such a sweet deal?&lt;br /&gt;&lt;br /&gt;Price fixing is how.&lt;br /&gt;&lt;br /&gt;The major labels want nothing more than to break Apple&amp;rsquo;s dominance of the digital music business. They spin it as a good thing. More retailers means more competition, which is good for consumers. But let me ask you: if Amazon selling music for 89 cents a track is good for consumers, why isn&amp;rsquo;t iTMS also selling music for 89 cents a track good for consumers?&lt;br /&gt;&lt;br /&gt;It would be good for consumers, but it wouldn&amp;rsquo;t be good for the music labels. The reason it wouldn&amp;rsquo;t be good for the music labels is that they really don&amp;rsquo;t want consumers paying 89 cents a track for DRM-free music. They want consumers to stop using iPods and start using devices with DRM that the labels can control.&lt;br /&gt;&lt;br /&gt;They want consumers using devices in proprietary silos like old-fashioned cell phones, where you pay for the track, you pay for the bits transferred over the air, and then you pay all over again when you want to use a few seconds of the track as a ring tone.&lt;br /&gt;&lt;br /&gt;As soon as they can break this pesky iPod-iTMS-iPhone nonsense, the labels want to get back to dictating what you pay and how often you pay. The labels want to do business with people like Microsoft. Microsoft gets it: all the people who bought music using &lt;a href="http://www.microsoft.com/presspass/newsroom/msn/factsheet/musicfs.mspx"&gt;MSN music&lt;/a&gt;? They can buy it all over again at the Zune store.&lt;br /&gt;&lt;br /&gt;Do you think that the MP3 genie is out of the bottle and will never go back? You haven&amp;rsquo;t been paying attention to digital video media. The movie folks have succeeded in making DRM a standard for movies on DVD, and it is even worse on BlueRay. Have you seen the hoops a Microsoft PC has to go through to play video these days? Each piece of hardware has to promise to be a good boy and not let you actually do anything with the bits without permission.&lt;br /&gt;&lt;br /&gt;The movies people have imposed harsher DRM on movies, and the music labels like the look of that.&lt;br /&gt;&lt;br /&gt;The only&amp;mdash;I repeat only&amp;mdash;reason the labels allow competing stores to have DRM-free tracks is that it&amp;rsquo;s the only way to get music onto an iPod. Think about that for a moment: Apple&amp;rsquo;s dominance of the music player business is the actual reason you can buy a DRM-free track from Amazon. If anybody else had a substantial chunk of the player market, the labels would be busy trying to make the other player&amp;rsquo;s DRM the standard.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Imagine a world where every online store sells DRM-free music encoded in open licensable formats. In such a world, any player can play music purchased from any store, and any store can sell music which is playable on all players. This is clearly the best alternative for consumers, and Apple would embrace it in a heartbeat.&lt;br /&gt;&lt;br /&gt;If the big four music companies would license Apple their music without the requirement that it be protected with a DRM, we would switch to selling only DRM-free music on our iTunes store. Every iPod ever made will play this DRM-free music.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;Steve Jobs, &lt;a href="http://www.apple.com/hotnews/thoughtsonmusic/"&gt;Thoughts on Music&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I know, you&amp;rsquo;re going to bring up Apple&amp;rsquo;s DRM. Let me ask you a question: who do you think wanted DRM on iPods? Apple? Don&amp;rsquo;t make me laugh. Apple built a nice little business selling iMacs using the slogan &amp;ldquo;Rip. Mix. Burn.&amp;rdquo; They would love to keep building their nice little iPod business on the back of DRM-free music.&lt;br /&gt;&lt;br /&gt;Think about this: If you buy a 32 GB &lt;a href="http://www.amazon.com/gp/product/B0012JNQYK?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B0012JNQYK"&gt;Apple iPod touch&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;l=as2&amp;o=1&amp;a=B0012JNQYK" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; from Amazon for $472.54, do you think Steve Jobs stays awake all night worrying about whether you will buy tracks from Apple or from Amazon?&lt;br /&gt;&lt;br /&gt;If you answered &lt;em&gt;yes&lt;/em&gt;, then you understand that Apple would be delighted to offer DRM-free music for the same price as Amazon. Or even less, since the profit selling you an iPod can subsidize their on-line store.&lt;br /&gt;&lt;br /&gt;I personally answered &amp;ldquo;no,&amp;rdquo; because in my opinion, there are only three threats to Apple&amp;rdquo;s iPod business: Someone will actually out-design a music player and make that is actually better designed, cell phones will become the dominant music players, or someone else establishes a DRM standard that locks Apple out of playing downloaded music. I am not going to worry about anyone making nicer music players, I think we see what Apple is doing about the cell phone business, and now we understand what Apple is doing about the DRM business: If &lt;em&gt;nobody&lt;/em&gt; can establish a DRM business, if nobody can lock you into one player, then nobody can take the music business away from Apple simply by getting into a back room and doing secret, monopolistic deals.&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;m looking at you, Sony and Microsoft. If the whole world has DRM-free music, you have to compete with iPod by building better music players. Sony, at least, has a chance. And if the whole world can sell DRM-free music, then Amazon and the like would have to compete with iTMS by building a better music store. Except, of course, they don&amp;rsquo;t have to compete with iTMS because the labels are colluding to place Apple at a disadvantage.&lt;br /&gt;&lt;br /&gt;It&amp;rsquo;s delightful that for the moment, we have a choice of where to buy DRM-free music. It&amp;rsquo;s wonderful that today, we can legally purchase the right to listen to a lot of major label music on DRM-free MP3s. But let&amp;rsquo;s not kid ourselves. If the labels break Apple, this will not last. The genie will go right back into the bottle.&lt;br /&gt;&lt;br /&gt;Buy what you like, where you like. But remember why things are the way they are. Apple is more expensive than Amazon because the labels want you listening to music on a Zune.&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;font size="-1"&gt;&lt;br /&gt;&lt;em&gt;Update:&lt;/em&gt; Thanks for the links, &lt;a href="http://daringfireball.net/" title="Daring Fireball"&gt;John&lt;/a&gt; and &lt;a href="http://www.codinghorror.com/blog/archives/001113.html" title="Supporting DRM-Free Music"&gt;Jeff&lt;/a&gt;. I spotted an interesting idea in the comments on Jeff&amp;rsquo;s post: the labels may not succeed in breaking iPod, but if they can break iTMS, they might be able to salvage the ability to set arbitrary prices.&lt;br /&gt;&lt;br /&gt;One of the things they really hate about iTMS (alongside letting you burn your own CDs, transfer the music between computers, and share your music over a LAN) is that all music costs exactly the same. Breaking iTMS will restore the biggest weapons they have against artists. That has been discussed before, I recall Joel Spolsky&amp;rsquo;s &lt;a href="http://www.joelonsoftware.com/items/2005/11/18.html"&gt;Price as Signal&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!-- &lt;em&gt;Update II&lt;/em&gt;: People keep asking, &amp;ldquo;Why doesn&amp;rsquo;t Apple give up DRM on iTMS?&amp;rdquo; and &amp;ldquo;Why Doesn&amp;rsquo;t Disney give up DRM on their movies of Steve Jobs is committed to eliminating DRM?&amp;rdquo; I have the same answer for both questions, kinda-sorta. This post is not about whether Apple is naughty or nice. If you want to belive that Steve Jobs is a Sith Lord bent on Evil Domination of the Music Galaxy, rock on. This post makes no argument against that. Really.&lt;br /&gt;&lt;br /&gt;This post argues that Apple ought to have the &lt;em&gt;option&lt;/em&gt; of offering music without DRM at the same price as Amazon. Right now, Apple offers music without DRM for tracks from one semi-major label&amp;mdash;EMI&amp;mdash;because that&amp;rsquo;s the only label that allows them to offer music without DRM. Every other major label requires Apple to sell their tracks with DRM. If the labels gave Apple the right to sell music without DRM and Apple insisted on DRM, this post would not exist. Apple doesn&amp;rsquo;t abandon DRM because the labels won&amp;rsquo;t let Apple abandon DRM.&lt;br /&gt;&lt;br /&gt;So what does that have to do with Steve Jobs and his stake in Disney? Nothing, and that&amp;rsquo;s the point. The post is about the misbehaviour of the record labels, not a judgment of Apple one way or the other. If you want to talk about the misbehaviour of the movie studios, that&amp;rsquo;s a different post, one you ought to write, and one I will read with interest.&lt;br /&gt;&lt;br /&gt;The premise of this post was stated quite explicitly: If Amazon selling music for 89 cents a track is good for consumers, why isn&amp;rsquo;t iTMS also selling music for 89 cents a track good for consumers? Likewise, I ask: If Amazon selling music from all of the major labels without DRM is good for consumers, why isn&amp;rsquo;t iTMS also selling music from all of the major labels without DRM also good for consumers?&lt;br /&gt;&lt;br /&gt;It&amp;rsquo;s great that I can buy The Goldberg Variations without DRM from Amazon. Why won&amp;rsquo;t the labels allow me the option of buying it without DRM from Apple? Everything else&amp;mdash;OS X, what the CEO does in his spare time, and whether iPods are/were lame&amp;mdash;is incidental. My question remains, why won&amp;rsquo;t the labels give us the choice? --&gt;&lt;/font&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/05/why-apple-is-more-expensive-than-amazon.html' title='Why Apple is more expensive than Amazon'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=7366845986780312404' title='38 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/7366845986780312404'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/7366845986780312404'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-5046102363130432484</id><published>2008-05-01T13:29:00.008-04:00</published><updated>2008-05-01T13:43:16.971-04:00</updated><title type='text'>I have a truly marvellous title of this post which this field is too narrow to contain</title><content type='html'>&lt;blockquote&gt;Management saw this general-purpose mail reader and said, &amp;#8220;since this mail reader is popular with normal people, we must now pimp it out to &amp;#8216;The Enterprise&amp;#8217;, call it Groupware, and try to compete with Lotus Notes!&amp;#8221;&lt;br /&gt;  &lt;br /&gt;  To do this, they bought a company called Collabra who had tried (and, mostly, failed) to do something similar to what we had accomplished. They bought this company and spliced 4 layers of management in above us. Somehow, Collabra managed to completely take control of Netscape: it was like Netscape had gotten acquired instead of the other way around.&lt;br /&gt;  &lt;br /&gt;  &amp;#8220;Groupware&amp;#8221; is all about things like &amp;#8220;workflow&amp;#8221;, which means, &amp;#8220;the chairman of the committee has emailed me this checklist, and I&amp;#8217;m done with item 3, so I want to check off item 3, so this document must be sent back to my supervisor to approve the fact that item 3 is changing from &amp;#8216;unchecked&amp;#8217; to &amp;#8216;checked&amp;#8217;, and once he does that, it can be directed back to committee for review.&amp;#8221;&lt;br /&gt;  &lt;br /&gt;  Nobody cares about that shit. Nobody you&amp;#8217;d want to talk to, anyway&lt;/blockquote&gt;&lt;div&gt;&amp;#8212;Jamie Zawinski, &lt;a href="http://www.jwz.org/doc/groupware.html"&gt;Groupware Bad&lt;/a&gt; (2005)&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;The hallmark of an architecture astronaut is that they don&amp;#8217;t solve an actual problem.&lt;br /&gt;  &lt;br /&gt;  Groove had some early success selling secure networks to the military-industrial complex, but didn&amp;#8217;t make much of a ripple outside that niche. Their real success was in getting bought by Microsoft, which brought Groove&amp;#8217;s designer and chief architecture-astronaut Ray Ozzie to the role of &amp;#8220;Chief Software Architect&amp;#8221; at Microsoft&amp;#8230;&lt;br /&gt;  &lt;br /&gt;  Ray Ozzie just can&amp;#8217;t stop rewriting this damn app, again and again and again, and taking 5-7 years each time. And the fact that customers never asked for this feature and none of the earlier versions really took off as huge platforms doesn&amp;#8217;t stop him.&lt;/blockquote&gt;&lt;div&gt;&amp;#8212;Joel Spolsky, &lt;a href="http://www.joelonsoftware.com/items/2008/05/01.html"&gt;Architecture astronauts take over&lt;/a&gt; (2008)&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And my title?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Buying a company that makes shit that nobody cares about&amp;mdash;nobody you&amp;#8217;d want to talk to, anyway&amp;mdash;just so you can replace your product leadership and vision with theirs and so that you can stop building your products that people actually care about and start building shit that nobody will care about&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Still bad&lt;/strong&gt;.&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/05/i-have-truly-marvellous-title-of-this.html' title='I have a truly marvellous title of this post which this field is too narrow to contain'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=5046102363130432484' title='6 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/5046102363130432484'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/5046102363130432484'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-2926263837455237813</id><published>2008-04-27T08:02:00.012-04:00</published><updated>2008-04-29T06:53:37.744-04:00</updated><title type='text'>The single most important thing you must do to improve your programming career</title><content type='html'>Yes, I said improve your programming &lt;em&gt;career&lt;/em&gt;, not your programming prowess. And by career, I mean all of it in any form, whether your career is working for BigCo, launching a start up, consulting, whatever.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center;"&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/zJ12vNZ5yMY&amp;hl=en"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/zJ12vNZ5yMY&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;Let&amp;rsquo;s assume you&amp;rsquo;re already as smart as Steve Wozniak, the &amp;uuml;ber-engineer. Do you want to hack part-time for the rest of your life or do you want to change the world? To change the world, you must create the new, but you must also show people why it matters. And that&amp;rsquo;s why&amp;hellip;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The single most important thing you must do to improve your programming career is improve your ability to communicate.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;To program, you must elicit ideas from other people and share your ideas with them. Sharing ideas comes in many forms: explaining how you did something. Suggesting a new practice for the team. Demonstrating how something works. Convincing everyone to switch programming languages. Persuading a brilliant engineer to join your team. Persuading your manager to get out of the way and let you do your thing.&lt;br /&gt;&lt;br /&gt;Advancing your career is entirely about communicating. Getting a job. Turning down a job. Asking for a promotion. Turning down a promotion. Getting onto a good team. Politely extricating yourself from a good team. Persuading a brilliant engineer to co-found a company. Helping a brilliant engineer understand why co-founding a company isn&amp;rsquo;t the right thing to do. Asking for funding. Turning down funding. Getting clients. Turning down clients.&lt;br /&gt;&lt;br /&gt;It&amp;rsquo;s all communication. Now you know, I have a background in Sales and Marketing. So I worry that I am holding a Golden Hammer and suggesting to you that your career is all about nailing things. But here is the short and obvious truth: Human beings are all about &lt;em&gt;physical&lt;/em&gt; communication. It&amp;rsquo;s a huge, huge part of what makes us human, this talking and listening jibber-jabbering thing.&lt;br /&gt;&lt;br /&gt;Frankly, there is no substitute for actual speech with visible body language. We do not react to the written word the same way that we react to a speech where we can see the speaker. So let&amp;rsquo;s skip right past learning to write well. It&amp;rsquo;s phenomenally important, but learning to speak well trumps everything. At &lt;a href="http://mcommons.com/about-us"&gt;Mobile Commons&lt;/a&gt; we talk about technical things all the time, and the remote members of the team switch out of Campfire into iChat or Skype to hear each other&amp;rsquo;s voices and see each other&amp;rsquo;s faces at least once a day.&lt;br /&gt;&lt;br /&gt;If you take just one thing from this post, let it be this: To improve your programming career, the single most important thing you must do is improve your ability to communicate your ideas face to face.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What to do right now&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Would you like to improve? I have deliberately avoided suggesting &lt;em&gt;what specifically&lt;/em&gt; you might want to improve: My Latin teacher said we crave the three Ps: Power, Prestige, and Pecuniam. But the nu&amp;auml;nces of aspiration are many. You have ideas you want us to understand. You have people you want to associate with. You have things you want to build and you need to harness other people&amp;rsquo;s efforts to build them.&lt;br /&gt;&lt;br /&gt;Here is what to do today to shorten the line between where you are and where you need to be: Volunteer to give a presentation that you can entirely control, and invest the time and effort to do the best possible job.&lt;br /&gt;&lt;br /&gt;&lt;div class="book"&gt;&lt;hr/&gt;&lt;em&gt;&lt;a href="http://www.amazon.com/gp/product/0321525655?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321525655"&gt;&lt;img border="0" src="http://weblog.raganwald.com/uploaded_images/presentation_zen.jpg"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;l=as2&amp;o=1&amp;a=0321525655" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;br /&gt;&lt;br /&gt;Improving your ability to present takes practice. But it also takes study. Start with &lt;a href="http://www.amazon.com/gp/product/0321525655?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321525655"&gt;Presentation Zen&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;l=as2&amp;o=1&amp;a=0321525655" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;. Presentation Zen is not about how to make slides. It&amp;rsquo;s about how to think deeply about your ideas and how to transform them into a presentation.&lt;br /&gt;&lt;br /&gt;And that&amp;rsquo;s why it matters: Thinking deeply about your ideas from a new perspective engages your brain and makes you smarter.&lt;/em&gt;&lt;hr/&gt;&lt;/div&gt;Now, you may already be giving presentations. Maybe it&amp;rsquo;s part of your job already. But I am still recommending you add one to your workload, one that you entirely control. This is crucial: if you don&amp;rsquo;t control the subject, the content, the audience, everything, it may not be the very best way for you to improve.&lt;br /&gt;&lt;br /&gt;I recommend you find a venue that is begging for presentations&amp;mdash;local programming users groups are ideal&amp;mdash;and sign up to give a talk. Pick a topic. If you don&amp;rsquo;t have a burning desire to shout something across the roof tops, you can always fall back on giving an &amp;ldquo;Experience Report.&amp;rdquo; That&amp;rsquo;s where you discuss something you did or tried to do and how it worked out.&lt;br /&gt;&lt;br /&gt;Or go with &lt;a title="Three blog posts I'd love to read (and one that I wouldn't)" href="http://weblog.raganwald.com/2007/10/three-blog-posts-id-love-to-read-and.html"&gt;one of the ideas I suggested for blog posts&lt;/a&gt;: &amp;ldquo;What I learned from Language X that makes me a better programmer when I use Language Y,&amp;rdquo; &amp;ldquo;Something surprising that you probably wouldn&amp;rsquo;t guess about Language X from reading blog posts,&amp;rdquo; or &amp;ldquo;My personal transformation about Idea X.&amp;rdquo;&lt;br /&gt;&lt;br /&gt;By the way: If you already have a certain degree of comfort with presenting to an audience and you &lt;em&gt;really&lt;/em&gt; want to ignite your career, try doing a &amp;ldquo;Fish out of Water&amp;rdquo; presentation: Present to a group with whom you have very little in common. For example, give a presentation about how to work with programmers to a business networking breakfast club. Learning to present ideas to people who are not just like you will make you a superstar.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Here is what to do today to shorten the line between where you are and where you need to be: Volunteer to give a presentation that you can entirely control, and invest the time and effort to do the best possible job.&lt;/blockquote&gt;&lt;br /&gt;Now put together a presentation deck&lt;sup&gt;&lt;font size="-2"&gt;&lt;a name="from_1"&gt;&lt;/a&gt;&lt;a href="#to_1"&gt;1&lt;/a&gt;&lt;/font&gt;&lt;/sup&gt; for your talk. Do not give a talk without a deck, you will lose valuable experience giving presentations and this is about your experience. Furthermore, presentations are tougher than speeches because the presentation medium gives you many, many opportunities to screw it up (like having what you say and what&amp;rsquo;s on the screen be the same thing).&lt;br /&gt;&lt;br /&gt;Then give the talk. And then give another one. And keep going. And never stop, because presenting well is a skill that helps you from where you are now right up to when you are presenting the numbers to the Board of Directors or presenting a new product to a hall full of cheering customers or, or, or anything and everything.&lt;br /&gt;&lt;br /&gt;See you there!&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;ol&gt;&lt;li&gt;&lt;a name="to_1"&gt;&lt;/a&gt;That would be a &amp;ldquo;deck of slides.&amp;rdquo; Nowadays it&amp;rsquo;s a keynote, open office, or that-other-thing file, but once upon a time it was a set of 35mm transparencies you would load into a carousel.&lt;br /&gt;&lt;br /&gt;Stacked up, they looked a little like a deck of cards, thus the nickname &amp;ldquo;deck.&amp;rdquo; You can probably find one (and someone old enough to remember when they were called decks) in a museum somewhere.&lt;br /&gt;&lt;br /&gt;[&lt;a href="#from_1"&gt;back&lt;/a&gt;]&lt;/li&gt;&lt;/ol&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/single-most-important-thing-you-must-do.html' title='The single most important thing you must do to improve your programming career'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=2926263837455237813' title='20 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/2926263837455237813'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/2926263837455237813'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-2059750952168900416</id><published>2008-04-25T11:11:00.005-04:00</published><updated>2008-04-28T09:56:34.052-04:00</updated><title type='text'>Why we are the biggest obstacles to our own growth</title><content type='html'>&lt;blockquote&gt;When you&amp;rsquo;re old and everyone around you is doing or buying something you don&amp;rsquo;t understand, you think they&amp;rsquo;re assholes; when you&amp;rsquo;re young, you do it/buy one, too.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;John Gruber, &lt;a href="http://daringfireball.net/2008/04/stopped_clock" title="Stopped Clock"&gt;talking about Apple&amp;rsquo;s strength&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This statement is intriguing. I recall Michael Lewis making a similar point in his book &lt;a href="http://www.amazon.com/gp/product/0140296468?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0140296468"&gt;The New New Thing: A Silicon Valley Story&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;l=as2&amp;o=1&amp;a=0140296468" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;. Michael pointed out that change was being driven by the young because they didn&amp;rsquo;t have any sense of self to hang on to.&lt;br /&gt;&lt;br /&gt;This is crucial. If you think of yourself as a&amp;mdash;for example&amp;mdash;Lisp Programmer, learning &lt;a href="http://factorcode.org/"&gt;Factor&lt;/a&gt; and trying it on a project is not just an intellectual exercise, it&amp;rsquo;s a shedding of a little of who you think you are. If you have built software&amp;mdash;successfully&amp;mdash;using large teams with meticulous planning, working with a small team in a less structured setting is again more than an experiment, it&amp;rsquo;s walking away from part of what you are.&lt;br /&gt;&lt;br /&gt;When you are young, you don&amp;rsquo;t have that sense of self to protect. You&amp;rsquo;re driven by a need to find out who you are, to turn the pages of your biography and see how the story turns out. If people around you are doing something you don&amp;rsquo;t understand, you assume the problem is your inexperience and you go to work trying to understand it.&lt;br /&gt;&lt;br /&gt;But when you are old, when you know who you are, everything is different. When people around you are doing something you don&amp;rsquo;t understand, you have no trouble at all explaining why they are &lt;strike&gt;assholes&lt;/strike&gt; mistaken. Let me give you an real-life example.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[] is Ruby for &amp;ldquo;Swiss Army Knife&amp;rdquo;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;One of the examples I give for using &lt;a href="http://andand.rubyforge.org"&gt;andand&lt;/a&gt; is with regular expression matching. I had a bunch of code that looked like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;begin&lt;br /&gt;  md = 'The song "777-9311" is by The Time'.match(/"(\d{3}-?\d{4})"/)&lt;br /&gt;  md[1] if md&lt;br /&gt;end&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;And being the type of person who dislikes the proliferation of mutable variables, I rewrote my code to look like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;'The song "777-9311" is by The Time'.match(/"(\d{3}-?\d{4})"/).andand[1]&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;This week, I received a very tactful email from Cornelius Mika pointing out that Ruby has this use case covered:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;'The song "777-9311" is by The Time'[/"(\d{3}-?\d{4})"/,1]&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;My first reaction was rather unprintable. I have read the documentation for the String class many times, but for some reason this never stuck. My brain refused to parse the fact that [] means all of the following:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;'The song "777-9311" is by The Time'[7]&lt;br /&gt;=&gt; 103&lt;br /&gt;'The song "777-9311" is by The Time'[4..7]&lt;br /&gt;=&gt; "song"&lt;br /&gt;'The song "777-9311" is by The Time'[4,4]&lt;br /&gt;=&gt; "song"&lt;br /&gt;'The song "777-9311" is by The Time'['The Time']&lt;br /&gt;=&gt; "The Time"&lt;br /&gt;'The song "777-9311" is by The Time'['The Tyme']&lt;br /&gt;=&gt; nil&lt;br /&gt;'The song "777-9311" is by The Time'[/"(\d{3}-?\d{4})"/]&lt;br /&gt;=&gt; "\"777-9311\""&lt;br /&gt;'The song "777-9311" is by The Time'[/"(\d{7})"/]&lt;br /&gt;=&gt; nil&lt;br /&gt;'The song "777-9311" is by The Time'[/"(\d{3}-?\d{4})"/,1]&lt;br /&gt;=&gt; "777-9311"&lt;br /&gt;'The song "777-9311" is by The Time'[/"(\d{7})"/,1]&lt;br /&gt;=&gt; nil&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Quite obviously, my brain is hanging onto a bunch of stuff about regularity, and discoverability, and &lt;a href="http://weblog.raganwald.com/2008/02/turtles-all-way-down-please.html" title="Turtles all the way down, please"&gt;languages consisting of a small number of features that interact in powerful ways&lt;/a&gt;. I don&amp;rsquo;t understand why [] means index sometimes but search some others. Why does 'string'[5] return a character, 'string'[2,3] return a substring (but  &lt;em&gt;not&lt;/em&gt; the same substring as 'string'[2..3]) and 'string'[&lt;em&gt;regexp&lt;/em&gt;,1] look kinda sorta like but 'string'[&lt;em&gt;regexp&lt;/em&gt;][1] but with maybe Monad semantics thrown in? I am confused, and that is before thinking about the fact that [] also means &amp;ldquo;call&amp;rdquo; for lambdas!&lt;br /&gt;&lt;br /&gt;As you can see I was mightily resisting the idea that sometimes, a useful tool consists of a collection of things you need, put within easy reach. I know that I need the semantics that both my andand example and 'string'[&lt;em&gt;regexp&lt;/em&gt;,1] provide, and I simply need to embrace the Ruby way of doing it for a while.&lt;br /&gt;&lt;br /&gt;Recognizing that we need to let go of ourselves in order to learn and grow is difficult. Part of my job is to bring my experience to the table, to guide and grow the team using the things I have learned. But I also have to accept that there are things I still must learn. And because I am a fully formed person, to make room for a new idea I must be willing to let go of an old one, I must be willing to chuck a piece of myself overboard.&lt;br /&gt;&lt;br /&gt;How do I know when to hold fast and when to try something new? I don&amp;rsquo;t. Sometimes when a bunch of people are doing something, and my gut tells me they&amp;rsquo;re mistaken, I override my gut and try it, I go along with what everybody else is doing.&lt;br /&gt;&lt;br /&gt;If you want a new idea, you have to silence your inner critic. Your sense of right and wrong, of smart and stupid works by comparing new ideas to what you already know. Your sense of what would be a good fit for you works by comparing new things to who you already are. To learn and grow, you must let go of you, you must be young again, you must accept that you don&amp;rsquo;t understand and seek to understand rather than explaining why it doesn&amp;rsquo;t make any sense.&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;font size="-1"&gt;&lt;br /&gt;post scriptum: An &lt;a title="What does age have to do with learning new ideas?" href="http://codeodor.com/index.cfm/2008/4/28/What-does-age-have-to-do-with-learning-new-ideas/2194"&gt;interesting distinction&lt;/a&gt;.&lt;/font&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/why-we-are-biggest-obstacle-to-our-own.html' title='Why we are the biggest obstacles to our own growth'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=2059750952168900416' title='11 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/2059750952168900416'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/2059750952168900416'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-307943829798093215</id><published>2008-04-24T10:04:00.013-04:00</published><updated>2008-04-25T11:41:05.472-04:00</updated><title type='text'>Are we building Universities or Amphitheaters?</title><content type='html'>&lt;blockquote&gt;Advertising-supported media gains much more from your attention than it does from your edification. This is not coincidence. It is fundamental and inherent. There is a huge economic incentive to grab your attention, and there is no economic incentive at all to give you something worth reading.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;&lt;a href="http://gilesbowkett.blogspot.com/2008/04/jerry-springer-for-programmers-only.html" title="Jerry Springer For Programmers: Only A Matter Of Time"&gt;Giles Bowkett&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This explains why so many &amp;ldquo;social news aggregators&amp;rdquo; head downhill towards idiocrity so quickly that they produce small sonic booms.&lt;br /&gt;&lt;br /&gt;For the site owners, the money is in flame wars and troll-fests. Such things quickly drive out all useful information, but they bring slavering crowds into the amphitheater to watch the Christians battle the Lions. And as far as an advertisement for little blue pills is concerned, a slavering non compos mentis is actually worth more than a single, thoughtful programmer seeking self-improvement. Such folks often block advertisements, and even if they see them they won&amp;rsquo;t buy products just because of an animated, glitzy pitch.&lt;br /&gt;&lt;br /&gt;We know a little something about preventing trolls and encouraging thoughtful discussion on the web. But what I have observed is this: we only see lip service of these ideas in sites that are built for making money through traffic. We only see a serious attempt to maintain a site&amp;rsquo;s value and character when the site owner has an ulterior motive for maintaining a quality social experience.&lt;br /&gt;&lt;br /&gt;For example, &lt;a href="http://news.ycombinator.com"&gt;Hacker News&lt;/a&gt; and &lt;a href="http://discuss.joelonsoftware.com/default.asp?joel"&gt;The Joel on Software Discussion Group&lt;/a&gt;. YCombinator profits from having quality developers pitch their ideas to YCombinator for launching. FogCreek profits from having quality developers pitch FogCreek&amp;rsquo;s software and job board service to their employers. Neither profit from doubling their readership at the expense of driving their core audience away. Both have founders with strong opinions about how to maintain a social site (&lt;a title="Trolls" href="http://www.paulgraham.com/trolls.html"&gt;here&lt;/a&gt; and &lt;a title="Building Communities with Software" href="http://www.joelonsoftware.com/articles/BuildingCommunitieswithSo.html"&gt;here&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;At their best, such sites resemble our rosy view of Universities of old: places of learning where people shared and debated ideas for the purpose of advancing knowledge.I say at their best. Not always, of course, but far more frequently than the traffic-motivated sites, and that&amp;rsquo;s good enough for me.&lt;br /&gt;&lt;br /&gt;I think Giles has nailed it neatly in that paragraph. If you are interested in edification, you have to spend your time in places where people stand to benefit from your edification, not where people stand to gain from your hanging around clicking on things.&lt;br /&gt;&lt;br /&gt;&lt;hr/&gt;&lt;em&gt;&lt;font size="-1"&gt;post scriptum&lt;/em&gt;:&lt;br /&gt;&lt;br /&gt;This post does not say anything about whether Universities are better than Amphitheaters, or whether people who build Universities are somehow more noble than people who build Amphitheaters. I mentioned YCombinator. I have read that they give their investees t-shirts reading &amp;ldquo;Make something people want.&amp;rdquo; Statistically speaking, people want amphitheaters. The people who build them are making something people want.&lt;br /&gt;&lt;br /&gt;This post is not about whether Amphitheaters are reprehensible in some grand, social-engineering sense. Or about the nobility of founding a University. It is simply a speculation about what sorts of factors conspire to make one site behave like an Amphitheater and another site behave like a University. And also a far smaller thing that is of little importance to anyone except you and I, namely, a suggestion as to where should we spend our time learning how to make what people want.&lt;/font&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/are-we-building-universities-or.html' title='Are we building Universities or Amphitheaters?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=307943829798093215' title='6 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/307943829798093215'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/307943829798093215'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-487444309244544891</id><published>2008-04-23T10:23:00.005-04:00</published><updated>2008-04-23T15:15:36.313-04:00</updated><title type='text'>Good sense</title><content type='html'>&lt;blockquote&gt;Good sense is the most equitably distributed of all things because no matter how much or little a person has, everyone feels so abundantly provided with good sense that he feels no desire for more than he already possesses.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;Ren&amp;eacute; Descartes, via David Weiss&amp;rsquo; excellent essay, &lt;a href="http://davidweiss.blogspot.com/2008/04/metacognitive-miscalibration.html"&gt;Metacognitive Miscalibration&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;I regularly feel like I don&amp;rsquo;t know anything. I have been working as a software developer for around 8.5 years and I feel like a green newbie who just came out of University. The internet serves as the greatest asset to my professional life but also the greatest ego bruiser I have ever known.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;Bill, &lt;a href="http://cf-bill.blogspot.com/2008/04/confessional.html"&gt;A Confessional&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;blockquote&gt;Experience can be a handicap&amp;hellip; At forty-two (or three!), it's easy to think you know things. You&amp;rsquo;re at incredible risk of thinking you know things when you&amp;rsquo;ve achieved some measure of success, no matter how modest. You become &amp;ldquo;unconsciously incompetent.&amp;rdquo; You don&amp;rsquo;t know, but you don&amp;rsquo;t know you don&amp;rsquo;t know.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;&lt;a href="http://weblog.raganwald.com/2005/10/im-not-young-enough-to-know-everything.html"&gt;I&amp;rsquo;m not young enough to know everything&lt;/a&gt;&lt;/div&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/good-sense.html' title='Good sense'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=487444309244544891' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/487444309244544891'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/487444309244544891'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-3545857086741453295</id><published>2008-04-15T12:09:00.010-04:00</published><updated>2008-04-15T14:22:20.043-04:00</updated><title type='text'>Dear Raganwald: How do I...</title><content type='html'>Dear Raganwald:&lt;br /&gt;&lt;br /&gt;I &lt;em&gt;love&lt;/em&gt; the &lt;a href="http://andand.rubyforge.org"&gt;andand&lt;/a&gt; gem you posted, and I have been using it on all my projects. It really does help make the code easier to read because it focuses on what I am actually trying to do and not on the bookkeeping of writing extra if statements and superfluous local variables just to handle nil checking when it is really an edge case.&lt;br /&gt;&lt;br /&gt;How can any one argue with Person.find(...).andand.name? Fabulous!!!&lt;br /&gt;&lt;br /&gt;And when I am writing my own project, I simply laugh at the doom-and-gloom naysayers who howl about open classes leading to conflicts. andand doesn&amp;rsquo;t change any object&amp;rsquo;s existing behaviour, it &lt;em&gt;extends&lt;/em&gt; it, in the sense that your post about &lt;a href="http://weblog.raganwald.com/2008/04/is-strictly-equivalent-to.html" title="IS-STRICTLY-EQUIVALENT-TO-A"&gt;Strict Liskov Equivalence&lt;/a&gt; talks about subclasses extending superclass behaviour and not redefining it. Cool. It&amp;rsquo;s easy to use something like andand on a project and not screw things up. It just takes a modicum of common sense rather than a slavish fear of what-we-do-not-understand.&lt;br /&gt;&lt;br /&gt;Ok, now I have one question. I am sorry to write, but I couldn&amp;rsquo;t find the answer in the docs. Quite simply, how do I use andand to write a gem, or a library, or a Rails Plugin, or anything else that I have to share with other people?&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;How do I use andand to write a gem, or a library, or a Rails Plugin, or anything else that I have to share with other people?&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;Stan&lt;/div&gt;&lt;br /&gt;You see, I like andand but I don&amp;rsquo;t want to force my opinions on the people using my stuff. So for example, I have this great idea for a Ruby Gem that adds syntactic metaprogramming so that I have an answer for the Ocaml and Lisp folks when they &lt;strike&gt;sneer at&lt;/strike&gt; &lt;a href="http://enfranchisedmind.com/blog/2008/04/14/useful-things-about-static-typing/" title="7 Actually Useful Things You Didn’t Know Static Typing Could Do: An Introduction for the Dynamic Language Enthusiast"&gt;question&lt;/a&gt; Ruby. But while I desperately want to use andand to write the gem, I am worried that perhaps the people who use my gem don&amp;rsquo;t want to install andand into all of their work? Perhaps they will be annoyed if they discover that I have extended the Object class?&lt;br /&gt;&lt;br /&gt;You know that this is innocuous, and I know that this is innocuous, but perhaps they want to pick and choose their own way of handling nils? Perhaps&amp;mdash;misguided though this may be&amp;mdash;they don&amp;rsquo;t want Object altered in any way, no matter how much safer it is to extend rather than modify it?&lt;br /&gt;&lt;br /&gt;Or maybe they like andand. A lot. And maybe it&amp;rsquo;s worth it to them to figure out what it does and decide it&amp;rsquo;s a great addition. But if every gem they install installs one, or two, or even three things like andand, at some point they will throw their hands up in the air and yell, &amp;ldquo;Enough!&amp;rdquo; Decisions about projects should always be made with a certain perspective, I think you have said that yourself in some of your essays about &lt;a href="http://weblog.raganwald.com/2007/06/r-e-s-p-e-c-t.html" title="R-E-S-P-E-C-T"&gt;time management&lt;/a&gt;. It seems wrong to force the people who use my code to decide whether they want andand in their project when they have to decide whether to install its dependencies.&lt;br /&gt;&lt;br /&gt;So. How do I use something like andand without forcing it downstream on the people who use my code?&lt;br /&gt;&lt;br /&gt;Thanks in advance,&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Signed,&lt;/em&gt;&lt;br /&gt;Your biggest fan,&lt;br /&gt;Stan.&lt;br /&gt;&lt;br /&gt;&lt;font size="-1"&gt;p.s. I hope you can answer this, I&amp;rsquo;m sure the answer will also be interesting to people working on large teams who want to use something like andand but do not want to go through a big bureaucratic process getting the entire team to agree that it should be pervasive across the project. If you can use something like andand in one place without changing Ruby globally, that will make a lot of people happy. &amp;mdash;Stan&lt;/font&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/dear-raganwald.html' title='Dear Raganwald: How do I...'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=3545857086741453295' title='18 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/3545857086741453295'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/3545857086741453295'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-8397140725085611869</id><published>2008-04-11T09:12:00.014-04:00</published><updated>2008-04-12T12:20:46.748-04:00</updated><title type='text'>"Stuffy" Dowding</title><content type='html'>The other night I popped &lt;a href="http://www.amazon.com/gp/product/B000ASDFEK?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B000ASDFEK"&gt;The Battle of Britain&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B000ASDFEK" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; into my MacBook.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/O71FJDkfngY&amp;amp;hl=en"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/O71FJDkfngY&amp;amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Early in the movie (where &amp;#8220;the movie&amp;#8221; is understood to mean &amp;#8220;the highly sensationalized dramatic adaptation of a highly fictionalized book recounting the version of history written by the winners of WWII&amp;#8221;)&amp;#8230; Where was I? Oh yes, early in the movie there is a very telling scene between Harry Andrews, playing a senior civil servant, and Sir Laurence Olivier, playing &lt;a href="http://en.wikipedia.org/wiki/Hugh_Dowding"&gt;Air Chief Marshall &amp;#8220;Stuffy&amp;#8221; Dowding&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Both are anticipating an assault on Britain by the Luftwaffe, partly to beat it into submission, partly to damage its war capabilities for strategic reasons, and most urgently to destroy Britain&amp;#8217;s air force so that the Germans may enjoy air superiority, which would allow them to launch an invasion.&lt;br /&gt;&lt;br /&gt;Olivier has stirred up a hornet&amp;#8217;s nest by writing a report saying outright that the RAF is outnumbered and has too many inexperienced pilots. Andrews is pressuring him to give a more optimistic review of the situation. He explains that the report conflicts with what the Minister has told Churchill. There are hints that if Olivier does not buck up and go along with the way the rest of the chaps are running the war, he will be sacked.&lt;br /&gt;&lt;br /&gt;In real life, Dowding was sidelined during the First World War for insisting that pilots needed rest to be effective. In WWII, he had realized that France was a lost cause, concluding that sending men and machines to their death in France would leave Britain completely undefended, although he did provide air cover for the evacuation from Dunquerque. He exercised prudence and caution religiously, as befits a commander outnumbered 4-1, and in the end his methods were vindicated by success in defending Britain.&lt;br /&gt;&lt;br /&gt;So, an interesting semi-fictional anecdote. And?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Managing Software Development&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Managers have this incredibly hard problem: they have to push (or pull, or prod, or horsewhip, or cajole, or whatever) their teams into producing the optimum performance. In most cases, they rely on the team for information about what is to be done, how it is to be done, and when it can be done. In software, this is especially true: the people doing the work have the most expertise in determining what can be done, by when.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;It is almost impossible to be fired if you (a) Go along with the official plan cheerfully, (b) Are seen to work long hours, and (c) Can give plausible explanations for why people or circumstances unrelated to management are responsible for things not working out.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And then we add to the mix a very difficult social problem: The members of the team usually need the approval of the manager to keep their jobs. It is very, very difficult to have a relationship between a manager and a subordinate where the manager actively dislikes the subordinate. In almost all cases, one or the other will eventually have to go.&lt;br /&gt;&lt;br /&gt;So most subordinates have a great deal of incentive to tell the manager what he wants to hear, whether it&amp;#8217;s true or not. To this, you may add the fact that it&amp;#8217;s relatively easy to explain away failure in software development after the fact, provided you are seen to have worked your ass off. &amp;#8220;We worked around the clock, but there were too many bugs in the FizzBuzz library&amp;#8230;&amp;#8221;&lt;br /&gt;&lt;br /&gt;Seriously, it is almost impossible to be fired as a programmer on a team if you (a) Go along with the official plan cheerfully, (b) Are seen to work long hours, and (c) Can give plausible explanations for why people or circumstances unrelated to management are responsible for things not working out. It is much easier to find yourself looking for work if you (a) Dispute the feasibility of the official plan, and then (b) Blame poor planning and management for the team&amp;#8217;s failure.&lt;br /&gt;&lt;br /&gt;So there is a problem: there is an incentive for subordinates to give falsely optimistic information to managers. And guess what? In many organizations, managers have managers too. So they take the optimistic information and make it even more optimistic when reporting to their managers. Astronomy buffs will be amused to hear that this effect has a name: &lt;a title="The Green Shift Anti-Pattern" href="http://www.ddj.com/architect/191600661"&gt;Green Shift&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Information gradually changes in hue from red to orange to yellow to green on its way up the pyramid.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The Two Kinds of Managerial Behaviour&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Obviously this is an oversimplification, but I am going to posit that managers exhibit two kinds of behaviour around asking the team for estimates, progress reports, feasibility checks, and any other kind of information that validates or invalidates the &amp;#8220;official plan.&amp;#8221;&lt;br /&gt;&lt;br /&gt;Behaviour number one is to seek the most accurate information. The manager may still press the team to try to do difficult  things. For example, the team may say that they have a lot of confidence something can be shipped by September 15th, and the manager may overrule them and insist on September 1st. Or may laugh at their optimism and put October 15th down. But either way, the manager wants to know what the team really thinks.&lt;br /&gt;&lt;br /&gt;Behaviour number two is to manipulate the team into saying what  the manager wants them to say. At KL Group, we used to call this the &amp;#8220;Guess the date I&amp;#8217;m think of&amp;#8221; game. A certain manager would ask for an estimate. Then, he would reject it and ask the subordinate to think again, harder. This would go on until the subordinate gave the answer the manager wanted, and from then on the subordinate had committed to the date.&lt;br /&gt;&lt;br /&gt;The manager, of course, could blame the subordinate for any failure: Hadn&amp;#8217;t the subordinate volunteered the date?&lt;br /&gt;&lt;br /&gt;This latter behaviour is quite common, and one of my epiphanies in development project management practices was realizing that there is no practice, no methodology, no tool that can fix this problem. It is a social problem that requires a social fix. For example, FogBugz has a very interesting feature called &lt;a href="http://www.joelonsoftware.com/items/2007/10/26.html"&gt;Evidence-Based Scheduling&lt;/a&gt;. In short, Evidence-Based Scheduling takes your estimate and combines it with reality to produce a delivery date.&lt;br /&gt;&lt;br /&gt;For example, if Fred Fast is conservative on estimates but always delivers on time, Evidence-Based Scheduling doesn&amp;#8217;t change his estimate. But if Sally Slow is always late, Evidence-Based Scheduling adjusts her estimate accordingly. Terrific!&lt;br /&gt;&lt;br /&gt;But here is the question: does it solve the problem of Maligna Manager badgering her team into giving unrealistic estimates?&lt;br /&gt;&lt;br /&gt;You might think &amp;#8220;Yes!&amp;#8221; You might think that if Maligna pressures her people into giving unrealistically optimistic estimates, Evidence-Based Scheduling will adjust for that and fix the estimates. That is actually true if Maligna&amp;#8217;s own manager uses Evidence-Based Scheduling and doesn&amp;#8217;t tell her.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;If you are the CIO of BigCo, you can work on igniting positive change in your culture, incentivising your management structure to increase visibility into their process, perhaps leveraging the competencies of a strategic value-added think tank. In other words, hire consultants.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;But Maligna is fully aware that the company is using Evidence-Based Scheduling, and what actually happens is this: When Maligna wants things done on September 1st, she badgers Fred into giving September 1st as his date to be done, and she badgers Sally into giving August 1st as her date to be done. Maligna doesn&amp;#8217;t view Evidence-Based Scheduling as a system for finding out when things will actually be done: Maligna views Evidence-Based Scheduling as a system for finding out what estimates Fred and Sally need to give her to get the result she wants.&lt;br /&gt;&lt;br /&gt;Evidence-Based Scheduling is like a formula with an unknown team estimate on the left side and an unknown delivery date on the right side. One kind of manager finds the team&amp;#8217;s estimate, plugs it into the left side, and out pops the most likely delivery date. The other, Maligna, plugs her desired delivery date into the right side and out pops the estimates she demands from the team.&lt;br /&gt;&lt;br /&gt;To fix this, you have to change Maligna&amp;#8217;s motivation. There is no tweak to the algorithm that can prevent her from gaming it to get the result she believes is in her best interests.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;You Own Your Own Estimates&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Well, if you are the CIO of BigCo, you can work on igniting positive change in your culture, incentivising your management structure to increase visibility into their process, perhaps leveraging the competencies of a strategic value-added think tank. In other words, hire consultants to tell you what a strategic thinker you are.&lt;br /&gt;&lt;br /&gt;The rest of us are a little like Stuffy Dowding. It&amp;#8217;s our job to stand our ground and just say &lt;a href="http://www.codeodor.com/index.cfm/2008/4/11/Save-Your-Job-Just-Say-No/2136" title="Save Your Job: Just Say No"&gt;no&lt;/a&gt; when people pressure us to pretend we can warp the laws of space and time. I wish it were more complex than that. I would like to write what most people would like to hear about selling your boss. I would like to write an article about the three sure-fire ways to manage your manager into making realistic plans.&lt;br /&gt;&lt;br /&gt;But reality goes a little like this: If you &amp;#8220;play the game,&amp;#8221; you will obtain personal reward even though some or many of your projects will suffer. If you stand your ground and politely but firmly insist on telling what you believe to be true about what will be done by when, your career will go a little like Dowding&amp;#8217;s: you will suffer some setbacks, such as being sidelined during World War I. And you will, from time to time, save the country, as he did in World War II.&lt;br /&gt;&lt;br /&gt;It&amp;#8217;s really up to you. My old (and terrific) manager Steve Rosenberg used to say &amp;#8220;We own the compiler,&amp;#8221; meaning that no matter what product management demanded, we had the final say on what code was written. And so it is with estimates. No matter how it is couched, you own your own estimates. Your manager can write any plan, but you and you alone decide whether you agree or disagree. You and you alone answer questions like &amp;#8220;Do you think you can accomplish X by Y?&amp;#8221;&lt;br /&gt;&lt;br /&gt;Managers will try every trick. One President I recall used to come up with all sorts of scenarios, &amp;#8220;But what if this turns out to be easy? What if there aren&amp;#8217;t that many bugs?&amp;#8221; And I used to say, &amp;#8220;Then we will have good news for you in a few months. But today, this is my opinion of how things will go based on my experience and what we know to be true right now.&amp;#8221;&lt;br /&gt;&lt;br /&gt;No matter what, I would not allow him to get me to change my estimate. He had, of course, the final say on the plan. As he should. And it was my job to execute the plan as best I could, which meant getting the team of 23 or so people to execute the plan as best they could. That&amp;#8217;s the job, to do your best once the decision is made. Just as Dowding&amp;#8217;s job was to execute the plan that Churchill approved.&lt;br /&gt;&lt;br /&gt;But nothing can force you to fabricate false optimism or to allow your manager to tell you your opinion of the situation. You own your own estimates.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Stuffy, Again&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;It is easy to blame management, or blame certain kinds of corporate cultures for problems with unrealistic plans. That is very nice to think about, it relives us of responsibility for what happens: &amp;#8220;I had to go along, that&amp;#8217;s the way things work around here.&amp;#8221;&lt;br /&gt;&lt;br /&gt;This was Stuffy&amp;rsquo;s problem, too. His management were pressuring him to do unrealistic things like save France, or engage the Luftwaffe head on, or to promise things the RAF couldn&amp;rsquo;t deliver. There were many things the RAF had to do to win, like use Radar effectively, and take advantage of intelligence, and yes, to out-fly the enemy in combat.&lt;br /&gt;&lt;br /&gt;The Battle of Britain was not won in that office on that day, of course. But it could very easily have been lost there.</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/stuffy-dowding.html' title='&quot;Stuffy&quot; Dowding'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=8397140725085611869' title='13 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/8397140725085611869'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/8397140725085611869'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-6055522379664556632</id><published>2008-04-09T11:24:00.002-04:00</published><updated>2008-04-09T11:31:38.293-04:00</updated><title type='text'>Raganwald goes back to U(niversity)</title><content type='html'>I am delighted to announce that I will be presenting a workshop (title and subject T.B.A.) at the upcoming &lt;a href="http://www.meshconference.com/meshu/"&gt;meshU&lt;/a&gt; in Toronto on May 20, 2008. I am especially flattered to have been selected to present alongside people like Daniel Burka, Avi Bryant, John Resig, Ryan Carson, and Leah Culver.&lt;br /&gt;&lt;br /&gt;There will be just twelve workshops, roughly streamed into design, implementation, and management/inspiration/cat-herding tracks. I understand registration is just $239, a bargain for a full day of high-bandwidth, real-time learning.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.eventbrite.com/event/98569825"&gt;See you there!&lt;/a&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/raganwald-goes-back-to-university.html' title='Raganwald goes back to U(niversity)'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=6055522379664556632' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/6055522379664556632'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/6055522379664556632'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-997138353056250823</id><published>2008-04-09T07:48:00.008-04:00</published><updated>2008-04-10T15:29:24.869-04:00</updated><title type='text'>Design Matters</title><content type='html'>The recent hoo-haw over whether the Do-No-Evil Empire launched an Attack of the Clones gives us a great opportunity to think about design and its value:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[Some people are] more or less arguing that it&amp;rsquo;s ridiculous to claim that 37signals somehow owns the concept of web-based group chat. Which is stupid, because no one made that argument. (Does Artie MacStrawman have a web-app cousin?)&lt;br /&gt;&lt;br /&gt;Consider, say, Movable Type and WordPress. WordPress came along with a free (beer and freedom) package that does the same basic thing as Movable Type and took a big chunk of the market away. But I&amp;rsquo;ve never seen anyone call WordPress a rip-off or clone of Movable Type. Why? Because it isn&amp;rsquo;t. It&amp;rsquo;s an original implementation of the same basic idea.&lt;br /&gt;&lt;br /&gt;A new implementation of the same concept is competition; a clone of an existing implementation is a rip-off.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;&lt;a href="http://daringfireball.net/linked/2008/april#wed-09-tc"&gt;John Gruber&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;As is often the case, &lt;a href="http://daringfireball.net/"&gt;Gruber&lt;/a&gt;&amp;rsquo;s analysis of the difference between the concept and the implementation is spot-on. The distinction is important to John: he&amp;rsquo;s deeply involved in the design community, where people care very much about the value one can add by coming up with a better implementation of the same concept.&lt;br /&gt;&lt;br /&gt;We saw a variation of this thinking when Rails was released: more than a few people claimed there was nothing new in Rails, it was &amp;ldquo;just&amp;rdquo; a framework for building CRUD applications, and a lightweight framework by the measure of how many new things you could do with it.&lt;br /&gt;&lt;br /&gt;But the value in Rails is its &lt;em&gt;design&lt;/em&gt;, in the way you put those CRUD applications together. Love it or hate it, Rails is an exercise in design, an exercise in user interfaces for programmers. At the time, it was a unique implementation of an existing and well-known concept.&lt;br /&gt;&lt;br /&gt;Don&amp;rsquo;t we agree, for example, that &lt;a href="http://grails.codehaus.org/"&gt;Grails&lt;/a&gt; is a clone of Rails while &lt;a href="http://code.whytheluckystiff.net/camping/"&gt;Camping&lt;/a&gt; is not? One clones the implementation on a different platform, one does not.&lt;br /&gt;&lt;br /&gt;People claim that certain ideas are &amp;ldquo;obvious&amp;rdquo; and therefore should be copied at will. I find it easy to think that something is obvious after you&amp;rsquo;ve looked at it and studied it. But the true test of &amp;ldquo;obviousness&amp;rdquo; is to go into a clean room, having never seen the original, and come up with what you imagine is an original design that does a good job of fulfilling the requirements of the concept.&lt;br /&gt;&lt;br /&gt;If you arrive at the same design independently, you have a decent argument that the design is obvious.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What really matters&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I&amp;rsquo;m going to change tacks here. If you are sitting down to make something, don&amp;rsquo;t clone an existing thing. Why? Because you can do better!&lt;br /&gt;&lt;br /&gt;Before Rails was released, I&amp;rsquo;m quite certain that 999 out of 1,000 web developers would have told you that CRUD development was &amp;ldquo;mature&amp;rdquo; and &amp;ldquo;done.&amp;rdquo; If you wanted to create a new framework, most people would expect you to clone existing ideas.&lt;br /&gt;&lt;br /&gt;But guess what? It wasn&amp;rsquo;t done, there was still value to be had doing the old thing in a new way. Likewise with music players and&amp;hellip; must I make a list of 10,000 things where people thought the concept was mature and devoid of innovation, then someone found a new way to execute the existing concept, but their &lt;em&gt;design&lt;/em&gt; was better and they reinvented the whole thing without adding new features?&lt;br /&gt;&lt;br /&gt;You can do better. And that&amp;rsquo;s the point. Not whether the party of the first part should have done better, or whether the party of the second part should have complained about whether the party of the first part actually did better or not. I don&amp;rsquo;t care who did what, where it was hosted, when the concept was invented, and why it has generated so much debate. And in a few days, neither will you.&lt;br /&gt;&lt;br /&gt;But what will always matter is what you and I choose to do with our very limited time while we are here. Not what they choose to do or not do with their time and their talents.&lt;br /&gt;&lt;br /&gt;I hope you will alway choose to strive to create something new, to never take it for granted that we can&amp;rsquo;t do better with even the most allegedly mundane problems to solve. Like chat line, CRUD frameworks, design patterns, programming languages, choosing our team mates, or mobile telephones.</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/rip-off-by-design.html' title='Design Matters'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=997138353056250823' title='8 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/997138353056250823'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/997138353056250823'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-5225863504730281301</id><published>2008-04-07T07:54:00.012-04:00</published><updated>2008-04-07T15:14:34.472-04:00</updated><title type='text'>IS-STRICTLY-EQUIVALENT-TO-A</title><content type='html'>&lt;blockquote&gt;Favor object composition over class inheritance.&lt;/blockquote&gt;&lt;div&gt;&amp;#8212;Chapter one of &lt;a href="http://www.amazon.com/gp/product/0201633612?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0201633612"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201633612" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;&lt;/div&gt;&lt;br /&gt;Maxims like this drive me crazy. On the one hand, there in one sentence is some of the best advice I can imagine for designing Object-Oriented software. On the other hand, following this advice without any idea why one favors one over the other, without any idea when class inheritance is the right thing to do&amp;#8230;&lt;br /&gt;&lt;br /&gt;As &lt;a href="http://www.amazon.com/gp/product/1570627169?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1570627169" title="Narrow Road to the Interior: And Other Writings (Shambhala Classics)"&gt;Basho&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1570627169" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; said, &amp;#8220;Do not seek to follow in the footsteps of the men of old; seek what they sought.&amp;#8221;&lt;br /&gt;&lt;br /&gt;Perhaps of the maxim &amp;#8220;Favor object composition over class inheritance&amp;#8221; is what happens when we seek what they sought, when we question the fundamentals, when we ask ourselves, &amp;#8220;&lt;span style="font-style:italic;"&gt;What does inheritance really mean?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So: What does it mean when we go to the design white board (or pick up a 3x5 card in a design session) and boldly write:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;Manager IS-AN Employee&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;???&lt;br /&gt;&lt;br /&gt;Commenting on &lt;a href="http://weblog.raganwald.com/2008/03/is-is-has.html"&gt;IS-A IS-A HAS-A&lt;/a&gt;, Robert Fisher pointed out that there is no definitive meaning to inheritance in programming languages. Another reader reminded him that Bertrand Meyer&amp;#8217;s &lt;a href="http://www.amazon.com/gp/product/0136291554?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0136291554"&gt;Object-Oriented Software Construction&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0136291554" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; identifies no fewer than twelve(!) kinds of inheritance. I took that to support Robert&amp;#8217;s point: if there really are twelve different kinds of inheritance, it is easy to see how two reasonable, intelligent people could each write &amp;#8220;A IS-A B&amp;#8221; and mean two completely different things.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Should the compiler always win?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;There is one argument&amp;mdash;the compiler always wins&amp;mdash;where the only thing that matters is what a program &lt;em&gt;does&lt;/em&gt;. A program&amp;#8217;s code means whatever effect the program has when it runs. So when you organize your code around a result like the fastest possible performance, or the smallest possible program, and in doing so you use features like inheritance strictly because they help your technical objective and not because you think they carry any meaning.&lt;br /&gt;&lt;br /&gt;&lt;div class="book"&gt;&lt;hr&gt;&lt;em&gt;&lt;a id="lnx0" name="evtst|a|0262561158" href="http://www.amazon.com/gp/product/0262561158?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0262561158"&gt;&lt;img src="http://weblog.raganwald.com/uploaded_images/a_little_java-777624.jpg" border="0"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0262561158" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="evtst|a|0262561158" href="http://www.amazon.com/gp/product/0262561158?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0262561158"&gt;A Little Java, a Few Patterns&lt;/a&gt;: The authors of &lt;a name="evtst|a|0262560992" href="http://www.amazon.com/gp/product/0262560992?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0262560992"&gt;The Little Schemer&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0262560992" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt; and &lt;a name="evtst|a|026256114X" href="http://www.amazon.com/gp/product/026256114X?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=026256114X"&gt;The Little MLer&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=026256114X" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt; bring their deep and important insights about programming to the Java language. This post will help explain why I never say never use inheritance.&lt;/em&gt;&lt;hr&gt;&lt;/div&gt;This practice is programming for the compiler. Smeone who is programming for the compiler doesn&amp;rsquo;t even think in terms of &amp;ldquo;IS-A,&amp;rdquo;, they think directly in their language&amp;rsquo;s features&amp;mdash;like interfaces, abstract classes, or modules.&lt;br /&gt;&lt;br /&gt;I appreciate that point of view, but I believe that we can produce &lt;em&gt;even better&lt;/em&gt; software if we decide that language features like inheritance have a semantic meaning above and beyond what the compiler does with them. Especially when we are considering projects that have multiple programmers working on them over a substantial period of time. Such projects must produce &lt;em&gt;sustainable&lt;/em&gt; code, not just code that works today.&lt;br /&gt;&lt;br /&gt;When we have a shared understanding of inheritance&amp;rsquo;s semantic meaning, our code more closely resembles the problem it solves. If it is just an engineering tool, a statement like Manager IS-AN Employee may have no parallel in the real world. Are managers really employees? When we declare other relationships such as HAS-MANY, we work very hard to make our code model the real world. Why would IS-AN be any different?&lt;br /&gt;&lt;br /&gt;That being said, there seem to be as many opinions of what class inheritance means as there are programmers. Do any two programmers&amp;mdash;much less a full team&amp;mdash; agree on exactly what &amp;ldquo;Manager IS-AN Employee&amp;rdquo; means if Employee and Manager are both classes?&lt;br /&gt;&lt;br /&gt;All I can do is share is a meaning that has worked well for me: Strict Equivalence. I&amp;#8217;m going to describe what I mean and illustrate some of the consequences of adopting this as the standard meaning of &amp;#8220;IS-A&amp;#8221; on your project.&lt;br /&gt;&lt;br /&gt;(I am not trying to say that Strict Equivalence is the only or even best way to build OO systems: I have worked on many projects with a different understanding, and they worked out just fine.)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Strict Equivalence&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You know the &lt;a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;Liskov Substitution Principle&lt;/a&gt;, of course. In short, if X IS-A Y, then anywhere you could use a Y, you can substitute an X and things should Just Work. So if every Manager IS-AN Employee, every piece of code that operates on Employees can operate on Managers and Just Work.&lt;br /&gt;&lt;br /&gt;What I just said is the Liskov Substitution Principle, but there is a lot of room for discussion over what &amp;#8216;just works&amp;#8217; means. So here is something much more specific, Strict Equivalence.&lt;br /&gt;&lt;br /&gt;A &lt;em&gt;client&lt;/em&gt; is a piece of code that &lt;em&gt;uses&lt;/em&gt; an entity. Strict Equivalence is the following property: X IS-A Y if and only if it is the case that for every client that uses an object of class Y, you can substitute an object of class X and the results from the perspective of the client are &lt;em&gt;indistinguishable&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Note that clients expecting an &lt;em&gt;X&lt;/em&gt; can presumably distinguish an X from a Y, but that&amp;rsquo;s because they know about the differences between X and Y. Note also, and with emphasis, that we are talking about &lt;em&gt;classes&lt;/em&gt;. Specifically, concrete classes. If X and Y are Java interfaces or C++ abstract base classes, there is no difference between Strict Equivalence and Liskov Substitutability, which leads to a completely different maxim, &amp;ldquo;program to interfaces and not implementations,&amp;rdquo; or my preferred interpretation&amp;mdash;&amp;ldquo;Favour exposing interfaces over exposing implementations.&amp;rdquo;&lt;br /&gt;&lt;br /&gt;This is not the same as Liskov Substitutability. With Liskov Substitutability, X IS-A Y if and only if it is the case that for every client that uses an object of class Y, you can substitute an object of class X and the results will be &lt;em&gt;semantically valid&lt;/em&gt; although they may differ from the perspective of the client. Again, we are talking about a case where the client is using a Y, not using an interface. For example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public class OurClient {&lt;br /&gt;  public void consumeY(final Y someY) {&lt;br /&gt;    ...&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This code is a client that uses and depends on objects of class Y, not an interface that Y implements.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Strict Equivalence is a specialization of Liskov Substitutability&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;One of the nice properties of Strict Equivalence is that it also guarantees semantic validity: It guarantees that you can substitute an X for a Y and since the results are indistinguishable to a client expecting a Y, the results will be semantically valid as well. Therefore, Strict Equivalence is a specialization of Liskov Substitutability.&lt;br /&gt;&lt;br /&gt;So if you like Liskov Substitutability, you ought to also like Strict Equivalence. But it is still a specialization, and a very restricted specialization at that. Let&amp;#8217;s see how.&lt;br /&gt;&lt;br /&gt;Consider something very basic. Overriding a method. Isn&amp;#8217;t that what you&amp;#8217;re supposed to do? You have a method in a superclass, but you need a different, more specialized behaviour in the subclass. This is OOP 101. And it&amp;#8217;s usually wrong. Okay, wrong is a strong word. It&amp;#8217;s usually a violation of Strict Equivalence. Let&amp;rsquo;s have a look at why.&lt;br /&gt;&lt;br /&gt;Take our Employees and Managers, where every Manager IS-AN Employee. We want to have a calculate_annual_bonus method for employees. You can imagine writing it, blah-blah personal goals set in performance review, blah-blah overall division profit.&lt;br /&gt;&lt;br /&gt;Now what happens with managers? Perhaps the business rule is that managers get 10% of the bonus of each of their reports, like an &lt;abbr title="Multi-Level Marketing, a/k/a/ Pyramid Fraud"&gt;MLM&lt;/abbr&gt; plan. So you write something like:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class Employee&lt;br /&gt;  def calculate_annual_bonus&lt;br /&gt;    personal_goals.select(&amp;amp;:achieved).map(&amp;amp;:incentive).inject(&amp;amp;:+) +&lt;br /&gt;      self.division.declared_profit_share_amount&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Manager &amp;lt; Employee&lt;br /&gt;  def calculate_annual_bonus&lt;br /&gt;    reports.map(&amp;amp;:calculate_annual_bonus).inject(&amp;amp;:+) * 0.1&lt;br /&gt;  end&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;(You can easily imagine the Java equivalent, starting with public class Manager extends Employee&amp;#8230;)&lt;br /&gt;&lt;br /&gt;With Liskov Substitutability, everything is fine: you have some code that transfers a bonus to an employee&amp;#8217;s bank account. It asks the employee object to calculate the annual bonus, and it transfers that amount. Nice. But Strict Equivalence prohibits this simple and common construction.&lt;br /&gt;&lt;br /&gt;The reason this is prohibited is that if we allow a subclass to override the bonus calculation, we have effectively declared that the amount of annual bonus is arbitrary for employees. Our code &lt;em&gt;says&lt;/em&gt; that the correct calculation is &lt;code&gt;personal_goals.select(&amp;amp;:achieved).map(&amp;amp;:incentive).inject(&amp;amp;:+)&lt;/code&gt; &lt;code&gt;+&lt;/code&gt; &lt;code&gt;self.division.declared_profit_share_amount&lt;/code&gt;, but in reality when we have an employee object, that may not be true.&lt;br /&gt;&lt;br /&gt;Overriding the annual bonus calculation breaks the declared behaviour of the Employee class. It is no different than if some code in your Manager class reached out like a &lt;a href="http://avdi.org/devblog/2008/04/01/announcing-ninja-patching/" title="Announcing Ninja-Patching!"&gt;ninja&lt;/a&gt; and redefined the calculate_annual_bonus method in the employee class. From the perspective of a client using an employee object, how is that different?&lt;br /&gt;&lt;br /&gt;With Strict Equivalence, you may only override the annual bonus calculation if client code like pay_annual_bonuses cannot tell the difference. So when I am looking at the Employee class, I can&amp;#8217;t tell whether someone has written a Manager class. But I do have confidence that if they do write a Manager class, they are not to override the calculate_annual_bonus calculation in a way that breaks my code: whatever they do, it must be indistinguishable to me.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;But&amp;hellip; but&amp;hellip; but&amp;hellip;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Strict Equivalence seems at first to violate the whole point of polymorphism. Why should a client know or care what a method does? Why should it rely on a what an Employee defines as the correct calculation for an annual bonus?&lt;br /&gt;&lt;br /&gt;One argument in favour of overriding is to talk about the separation of interface and implementation. Orthodox OO teaches that a class&amp;rsquo;s &lt;em&gt;interface&lt;/em&gt; is its collection of method signatures, and its &lt;em&gt;implementation&lt;/em&gt; is what those methods happen to do. The notion is that clients should program to the interface only: the implementation is the class&amp;rsquo;s private business.&lt;br /&gt;&lt;br /&gt;This practice is reified in C++, where the public interface of a class is found in a separate header file from the implementation. Sounds good. Now what happens with Java? In Java, a class&amp;rsquo;s interface and its implementation are in the same file. But if you want to give someone just the collection of method signatures, Java provides interfaces. So if you as the author wish to have clients program strictly to method signatures, you can give them an interface.&lt;br /&gt;&lt;br /&gt;The point here is that Strict Equivalence is &lt;em&gt;not&lt;/em&gt; in conflict with orthodox interface-oriented design: they can live happily side-by-side if you simply use interfaces when you mean interfaces, abstract methods when you mean abstract methods, and if you think twice before providing a concrete method in a class your provide to clients.&lt;br /&gt;&lt;br /&gt;The difference comes up when you ask a client  to use a class and provide an actual working method. In our example, we deliberately put behaviour in the Employee class, even though we have alternatives. In Ruby, we could borrow an idiom from Smalltalk and write:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;def calculate_annual_bonus&lt;br /&gt;  raise 'implemented by subclass'&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In Java, we could declare it to be an abstract method:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;abstract class Employee {&lt;br /&gt;  abstract public Money calculateAnnualBonus();&lt;br /&gt;  protected final Money baseAnnualBonus() {&lt;br /&gt;    // helper calculation&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Contributor extends Employee&lt;br /&gt;  public Money calculateAnnualBonus() {&lt;br /&gt;    return baseAnnualBonus();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Manager extends Employee&lt;br /&gt;  public Money calculateAnnualBonus() {&lt;br /&gt;    return ...&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Is that so hard? This conforms perfectly to Strict Equivalence. The Employee class guarantees that there is a calculateAnnualBonus method, but it doesn&amp;#8217;t guarantee what it will be. There is a protected helper method so that each subclass doesn&amp;#8217;t have to repeat the calculation. And you can see that both the Contributor and Manager classes guarantee the exact calculation.&lt;br /&gt;&lt;br /&gt;We &lt;em&gt;chose&lt;/em&gt; to provide clients with an Employee class that defined the exact calculation for the annual bonus. Given that we could have written our code another way, why shouldn&amp;rsquo;t a client assume that we deliberately wanted them to depend on the calculation? Why shouldn&amp;rsquo;t a client infer that the annual bonus calculation is part of the definition of what it means to be an employee?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Theories X, Y, and Law Enforcement&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In Management Science, a &lt;a href="http://en.wikipedia.org/wiki/Theory_X_and_theory_Y#Theory_X"&gt;Theory X &lt;/a&gt; manager believes &amp;#8220;workers need to be closely supervised and comprehensive systems of controls developed.&amp;#8221; A &lt;a href="http://en.wikipedia.org/wiki/Theory_X_and_theory_Y#Theory_Y"&gt;Theory Y&lt;/a&gt; manager &amp;#8220;will try to remove the barriers that prevent workers from fully actualizing themselves.&amp;#8221;&lt;br /&gt;&lt;br /&gt;Some languages provide tools for enforcing some of the semantics of Liskov Equivalence. I personally have mixed feelings about this. I actually like this idea of the compiler noticing that I am trying to call the non-existent annual_bonus method of an Employee object. And enforcing Strict Equivalence would be terrific.&lt;br /&gt;&lt;br /&gt;But what I don&amp;#8217;t like is actually not the language&amp;#8217;s fault. I don&amp;#8217;t like it when I have to deal with a code base where people assume that as long as they are following the language&amp;#8217;s rules, the result must be well-designed OO software. So net-net, I like languages providing mechanisms for enforcing obvious things about inheritance. But philosophically, I want to &lt;em&gt;seek what the language designers sought&lt;/em&gt; and design to the principle of the law, not the letter of the law.&lt;br /&gt;&lt;br /&gt;Let&amp;#8217;s talk about Java first. Java provides two tools&amp;#8212;the abstract and final keywords&amp;#8212;for partially enforcing Strict Equivalence. As shown above, an abstract method lets us declare that all Employees have a calculate_annual_bonus method without making any guarantee as to what it will return. A final method lets us declare that its calculation is invariant. If we write:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class Employee {&lt;br /&gt;  final public Money calculateAnnualBonus() {&lt;br /&gt;    // calculation...&lt;br /&gt;  }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Then we know that all Employees have the same calculation. It is illegal to implement a different calculation for the Manager subclass. And by extension, if we fail to mark a method final, we know that its implementation is &lt;em&gt;not&lt;/em&gt; guaranteed. A non-final method in a non-final Java class is unreliable, it&amp;#8217;s just like functionality without a test in a test-infected program. It is &lt;strong&gt;not&lt;/strong&gt; part of a class&amp;#8217; contract with its clients.&lt;br /&gt;&lt;br /&gt;I conjecture that this is the basis of the suggestion that &lt;a href="http://cafe.elharo.com/blogroll/final-good/" title="Final == Good"&gt;methods should be final by default&lt;/a&gt;. If a class is not final and it has a non-final method, you can override it and break Strict Equivalence. So with Java, if you want a method&amp;#8217;s behaviour to be part of a class&amp;#8217; contract with its clients, you have to make it final.&lt;br /&gt;&lt;br /&gt;There is a shortcoming to this system. It &lt;em&gt;is&lt;/em&gt; possible to override a method without breaking Strict Equivalence. &lt;br /&gt;&lt;br /&gt;The limitation of using the final keyword (or whatever tool your compiler gives you to prevent overriding) is that it prohibits a very large class of specializations that are useful and do not violate Strict Equivalence. It is as if the Police Chief decided to fight crime by imposing a curfew on the entire town.&lt;br /&gt;&lt;br /&gt;It is not that &lt;em&gt;all&lt;/em&gt; ways of overriding a method break Strict Equivalence. Let&amp;#8217;s go back to our employees for a moment:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class Employee&lt;br /&gt;  attr_accessor :manager&lt;br /&gt;&lt;br /&gt;  def something_serious&lt;br /&gt;    # ... just do it&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class ProbationaryEmployee &amp;lt; Employee&lt;br /&gt;  def something_serious&lt;br /&gt;    returning(super) do&lt;br /&gt;        self.manager.notify(self, 'did something serious')&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is a little contrived, but the point here is that although a ProbationaryEmployee overrides the something_serious method, it does so in a way that is presumably indistinguishable from the perspective of client code. It does something serious and returns the same result, but there is an extra side-effect that matters to probationary employees and their managers.&lt;br /&gt;&lt;br /&gt;This conforms to Strict Equivalence because to a client method, the results are identical. A ProbationaryEmployee will pass the same tests and you can insert assertions as you see fit.&lt;br /&gt;&lt;br /&gt;The only problem is, how do we know that ProbationaryEmployee adheres to Strict Equivalence and Manager does not? How can programmers write code like something_serious? Just writing any old method, calling super, and hoping that you haven&amp;#8217;t broken the Employee class is rather like tossing salt over your shoulder to ward off evil spirits. And never overriding Employee methods is rather drastic. What to do?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;When the going gets tough, the tough redecorate&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Solving problems like this is a lot of the motivation behind Aspect-Oriented Programming systems like Lisp&amp;#8217;s &lt;a href="http://www.dreamsongs.com/NewFiles/ECOOP.pdf" title="The Common Lisp Object System: An Overview (PDF)"&gt;Flavors &amp;amp; CLOS&lt;/a&gt;, the &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;Decorator Pattern&lt;/a&gt;, and method chaining in Rails.&lt;br /&gt;&lt;br /&gt;The principle is that a subclass doesn&amp;#8217;t really override a superclass&amp;#8217; method, it &lt;em&gt;extends its functionality&lt;/em&gt;. Meaning, it typically does something before it, something after it, or something around it. It &lt;em&gt;decorates&lt;/em&gt; the method, it doesn&amp;#8217;t replace it.&lt;br /&gt;&lt;br /&gt;In the example above, it is not really obvious that we are decorating the Employee#something_serious method. That happens to be a side-effect of what we are doing, but it is not obvious at all. Compare and contrast with a little easy AOP magic based on Rails&amp;#8217; object life-cycle style of coding:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class ProbationaryEmployee &amp;lt; Employee&lt;br /&gt;  include EasyAOP&lt;br /&gt;&lt;br /&gt;  after :something_serious do&lt;br /&gt;    self.manager.notify(self, 'did something serious') &lt;br /&gt;  end&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;font size="2"&gt;(No, there is no &amp;#8220;EasyAOP&amp;#8221; module. If you are interested in adding AOP to Ruby, consider using the &lt;a href="http://aquarium.rubyforge.org/"&gt;Aquarium&lt;/a&gt; gem).&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;This style of coding makes it obvious that we are attempting to maintain Strict Equivalence. Of course, we can abuse AOP and write advice that breaks our equivalence. 100% enforcement of Strict Equivalence while permitting things like AOP is probably impossible in the compiler. But we can make languages that encourage good programming. I honestly believe that if I have a powerful way to write advice&amp;#8212;like CLOS or AOP&amp;#8212;I could live with &lt;em&gt;never&lt;/em&gt; overriding methods. Forget methods being final by default, I think I would be happy with methods always being final if I can have subclasses decorate them.&lt;br /&gt;&lt;br /&gt;&lt;div class="book"&gt;&lt;hr&gt;&lt;em&gt;&lt;a id="lnx0" name="evtst|a|0262610744" href="http://www.amazon.com/gp/product/0262610744?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0262610744"&gt;&lt;img src="http://weblog.raganwald.com/uploaded_images/art_of_mop.jpg" border="0"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0262610744" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt;&lt;br&gt;&lt;br&gt;&lt;a id="lnx1" name="evtst|a|0262610744" href="http://www.amazon.com/gp/product/0262610744?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0262610744"&gt;The Art of the Metaobject Protocol&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0262610744" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt; is one of the most important books ever written on the subject of building abstractions with objects. The &lt;a href="http://en.wikipedia.org/wiki/Metaobject"&gt;Metaobject Protocol&lt;/a&gt; is a system for defining your own object semantics, such as the simple aspects described here. While you&amp;rsquo;re learning how to make your programs better in your language, you just might pick up a little Common Lisp. Highly recommended.&lt;/em&gt;&lt;hr&gt;&lt;/div&gt;Ruby, of course, does not enforce anything. Java provides some enforcement with its final keyword, but at a cost: subclasses cannot decorate final methods. On the whole, Java is not worse than Ruby for enforcement, because if you don&amp;#8217;t declare a method final, you are no worse off than in Ruby. In Ruby&amp;#8217;s favour, you can actually write things like EasyAOP in a few minutes. Better still, you can tweak it to suit your project and its domain. For Java, you probably need to use a heavyweight AOP framework to do the same thing.&lt;sup&gt;&lt;font size="1"&gt;&lt;a href="#to_1" name="from_1"&gt;1&lt;/a&gt;&lt;/font&gt;&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;Or maybe you can chuck all of that and use &lt;abbr title="Common Lisp Object System"&gt;CLOS&lt;/abbr&gt;. You could do a lot worse.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;A Promotion: Manager WAS-AN Employee&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Wow, that&amp;rsquo;s a lot of &lt;a href="http://en.wikipedia.org/wiki/Flummery"&gt;flummery&lt;/a&gt; over the statement &amp;ldquo;Manager IS-AN Employee.&amp;rdquo; As we have seen, there are a lot of guarantees that statement makes, especially if you adopt Strict Equivalence. You may not want to make those guarantees. You may not really &lt;em&gt;mean&lt;/em&gt; that a manager is an employee, you may mean that a manager has a lot in common with an employee. So what to do?&lt;br /&gt;&lt;br /&gt;Well, all this trouble started because we said that a Manager IS-AN Employee. What if it isn&amp;#8217;t? What we want is a relationship often called WAS-A. Or it&amp;#8217;s technical name, implementation inheritance. We want to say that a Manager uses the code of an Employee, but it isn&amp;#8217;t to be used where you expect an employee.&lt;br /&gt;&lt;br /&gt;In C++, you can use private inheritance. The Manager class would obtain all of an Employee&amp;#8217;s members and methods, and it could expose the ones it wanted as part of its own interface:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;class Manager : private Employee { ... }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;A Manager is not an employee. It is its own thing that happens to behave a lot like an employee. In languages like Java that do not provide a WAS-A construct, you can achieve the same thing with delegation. You can say a Manager HAS-AN Employee. It doesn&amp;#8217;t really have one in the sense of a manager having an executive assistant, but it uses an Employee object internally to handle some of its work.&lt;br /&gt;&lt;br /&gt;This is very much like a manager who has two &amp;#8216;hats.&amp;#8217; It works well if you have been careful to separate things like the implementation of database persistence from the semantic hierarchy of public inheritance. In other words, you didn&amp;#8217;t decide that an Employee IS-AN ActiveRecord::Base.&lt;br /&gt;&lt;br /&gt;In other words&amp;hellip; If a Manager is &lt;em&gt;not&lt;/em&gt; an employee in the true sense of the word but is simply &lt;em&gt;like&lt;/em&gt; an employee, we can use object composition to achieve code re-use and communicate to our fellow programmers what managers and employees have in common, without muddying the meaning of IS-A.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What they sought&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;So what have we seen? First, that if you adopt Strict Equivalence, standard inheritance carries a great deal of meaning with it. You can infer that the code in a class describes the behaviour of that class and all of its subclasses: The Employee class describes all employees, even probationary employees and managers. Subclasses extend functionality but never break it.&lt;br /&gt;&lt;br /&gt;Second, that there are many alternatives to breaking Strict Equivalence, including refactoring the class hierarchy when you need polymorphism and using object composition when you do not. This means that we never &lt;em&gt;need&lt;/em&gt; to use inheritance, we only use it when we choose to make guarantees about equivalence.&lt;br /&gt;&lt;br /&gt;In &lt;a href="http://weblog.raganwald.com/2007/11/programming-conventions-as-signals.html" title="Programming conventions as signals"&gt;Programming conventions as signals&lt;/a&gt;, I advanced the view that when there was more than one way to do something, each should carry a different meaning. And furthermore, when one way is the obvious way to do it, using the non-obvious way was a signal that there was something non-obvious going on.&lt;br /&gt;&lt;br /&gt;This obviously applies to choosing between class inheritance and object composition. Both can be used to express the idea that two classes or objects have something in common. Class inheritance carries heavyweight baggage along with it about the semantics of IS-A. Object composition does not.&lt;br /&gt;&lt;br /&gt;Therefore, class inheritance is the more &amp;ldquo;expensive&amp;rdquo; of the two to maintain, because it has the most serious implications and constraints on code. Object composition is cheaper because it makes no guarantees, it is a convenience mechanism.&lt;br /&gt;&lt;br /&gt;If class inheritance required a pattern and some boilerplate to establish, while object composition was as simple as writing:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;delegate :calculate_annual_bonus, :something_serious, :to =&gt; @employee_helper&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&amp;hellip;then there would have been no need for the maxim. Unluckily for us, the popular OO languages make class inheritance &lt;em&gt;cheap&lt;/em&gt; to write in code even though it is expensive to maintain, while object composition is expensive to write in code while being cheap to maintain.&lt;br /&gt;&lt;br /&gt;Thus, we need a maxim to remind ourselves that while class inheritance is seductively easy to write, it should be reserved for those cases where it expresses our actual semantic meaning and where imposing its implications and constraints on our code is going to make things cheaper and not more expensive to maintain.&lt;br /&gt;&lt;br /&gt;Favor object composition over class inheritance. Now we understand a little of where those six words are heading.&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Digression: Test-Driven Equivalence&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Consider the requirement that a user of the code be unable to distinguish a subclass from a superclass in a Test-Infected project. You have dozens or even hundreds of tests for each major class. What about all of those unit tests. Should a unit test for the Employee class work when given Manager objects?&lt;br /&gt;&lt;br /&gt;Hmmm. If a Manager IS-AN Employee, it follows that a Manager can be substituted for an Employee and the tests will pass. If an Employee test breaks when given a manager, we must pick one of two possibilities: First, it is possible that we were wrong to state that a Manager IS-AN Employee. We should have chosen a different structure for our classes.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;In a test-infected project, the meaning of &amp;#8220;Manager IS-AN Employee&amp;#8221; is external to the Employee class, it is in the tests.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The second possibility is that the test is inappropriate. We might say that the bonus calculation for an employee is uncertain, that the exact amount of the bonus is not part of the &amp;#8216;spec&amp;#8217; for the Employee class. Therefore, we shouldn&amp;#8217;t have a test that validates the amount of an employee&amp;#8217;s bonus. I can address this point easily: if we can&amp;#8217;t test it, it doesn&amp;#8217;t work, therefore if there shouldn&amp;#8217;t be a test that works for every employee, then there shouldn&amp;#8217;t be code associated with every employee.&lt;br /&gt;&lt;br /&gt;&lt;div class="book"&gt;&lt;hr&gt;&lt;em&gt;&lt;a id="lnx0" name="evtst|a|0201379430" href="http://www.amazon.com/gp/product/0201379430?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0201379430"&gt;&lt;img src="http://weblog.raganwald.com/uploaded_images/object_design-719894.jpg" border="0" height="160" width="128"&gt;&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201379430" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt;&lt;br&gt;&lt;br&gt;&lt;a id="lnx0" name="evtst|a|0201379430" href="http://www.amazon.com/gp/product/0201379430?ie=UTF8&amp;amp;tag=raganwald001-20&amp;amp;link_code=as3&amp;amp;camp=211189&amp;amp;creative=373489&amp;amp;creativeASIN=0201379430"&gt;Object Design: Roles, Responsibilities, and Collaborations&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0201379430" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1"&gt; focuses on the practice of designing objects as integral members of a community where each object has specific roles and responsibilities. The authors present the latest practices and techniques of Responsibility-Driven Design and show how you can apply them as you develop modern object-based applications.  &lt;br&gt;&lt;br&gt;&lt;/em&gt;&lt;hr&gt;&lt;/div&gt;So above we stated that according to Strict Equivalence, the code in the Employee class makes a guarantee about all employees. However in a test-infected project, we can take another line. When I say test-infected, I mean specifically that the team has made a commitment to 100% functional coverage in the project, and the team considers the tests to be a form of executable documentation for the code.&lt;br /&gt;&lt;br /&gt;If this is the case for a project, it follows that the tests for a class must reflect the contractual obligations of that class to its clients. If we write a test that only passes when an Employee&amp;#8217;s annual bonus is such-and-such an amount, that is the amount of bonus for all employees. If we want subclasses of Employee to have their own bonus calculations, we are free to provide a default or base implementation, &lt;em&gt;but we are prohibited from writing a unit test for it&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;You may think &amp;#8220;That&amp;#8217;s ok, my unit test directly creates an Employee object, it doesn&amp;#8217;t create a Manager object, so the test is not making a guarantee about Managers.&amp;#8221; If you take that line, you have removed all possibility of using the tests to make guarantees about Employees. You cannot say &lt;em&gt;anything&lt;/em&gt; about objects that are Employees, because your tests don&amp;#8217;t apply to all employees. This effectively eliminates the IS-A relationship in your test-infected project, because when I am looking at a Manager class, the fact that it derives from Employee tells me &lt;em&gt;nothing&lt;/em&gt;, because I can&amp;#8217;t trust any of the Employee tests to tell me something about Managers.&lt;br /&gt;&lt;br /&gt;Therefore, if you believe that an Employee test does not constrain the behaviour of a Manager object, you are required to duplicate all of the Employee tests that apply to Manager instances in Manager tests. You have moved the problem of what is inherited and what is not inherited from the Employee and Manager classes into your test classes.&lt;br /&gt;&lt;br /&gt;In a test-infected project, the meaning of &amp;#8220;Manager IS-AN Employee&amp;#8221; is external to the Employee class, it is in the tests. It also conforms to the Liskov Substitution Principle: it demands that whatever the superclass provides its clients, all of its subclasses must also provide. However, it is more relaxed than Strict Equivalence.&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;ol&gt;&lt;li&gt;&lt;a name="to_1"&gt;&lt;/a&gt;There are other approaches: &lt;a href="http://en.wikipedia.org/wiki/Eiffel_%28programming_language%29"&gt;Eiffel&lt;/a&gt;&amp;#8217;s Design by Contract implementation provides preconditions and post-conditions for methods. As long as a subclass conforms to or narrows its superclass&amp;#8217; post-conditions, and conforms to or widens its superclass&amp;#8217; preconditions, it may override a method.&lt;br /&gt;&lt;br /&gt;Design by Contract takes the view that the pre-conditions and post-conditions are the contract for a method. Given that understanding of Liskov Equivalence, the language is provides both compiler and run-time enforcement options. Code that adds notification or logging to a superclass&amp;#8217; methods obviously conforms to its post-conditions, so Eiffel permits it without arguing about whether the method should be final or not.&lt;br /&gt;&lt;br /&gt;Design by Contract also lies in between Plain and Strict Equivalence: Although the Employee class contains code, you cannot rely on it as a guide to what an Employee does. In Eiffel, you can rely on the post-conditions to be enforced, which are typically looser than the method implementation but tighter than a method signature without conditions.&lt;br /&gt;&lt;br /&gt;[&lt;a href="#from_1"&gt;back&lt;/a&gt;]&lt;/li&gt;&lt;/ol&gt;</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/is-strictly-equivalent-to.html' title='IS-STRICTLY-EQUIVALENT-TO-A'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=5225863504730281301' title='11 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/5225863504730281301'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/5225863504730281301'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-55527513637537221</id><published>2008-04-06T09:34:00.003-04:00</published><updated>2008-04-06T09:39:16.024-04:00</updated><title type='text'>javascript at reddit.com</title><content type='html'>&lt;a href="http://javascript.reddit.com"&gt;javascript.reddit.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It&amp;rsquo;s pretty quiet at the moment, which means it&amp;rsquo;s a blank canvas. Go wild, post your favourite Javascript articles, up- and down-mod the articles already posted.&lt;br /&gt;&lt;br /&gt;The great thing about a new site is that you can have such a huge influence over its direction. Once there are thousands of people following it, your vote will be a drop in the ocean. But right now, you can set the direction, a direction that will establish its character forever.&lt;br /&gt;&lt;br /&gt;So what are you waiting for? &lt;a href="http://javascript.reddit.com"&gt;Off you go&lt;/a&gt;!</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/javascript-at-redditcom.html' title='javascript at reddit.com'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=55527513637537221' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/55527513637537221'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/55527513637537221'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-1183240892363101558</id><published>2008-04-03T19:29:00.005-04:00</published><updated>2008-04-03T19:51:57.546-04:00</updated><title type='text'>What is a Specialist's Skill Set?</title><content type='html'>My son &lt;a href="http://flickr.com/photos/thomasb/2346657034/"&gt;Thomas&lt;/a&gt; had his tonsils and adenoids out today. Huge thanks to his Surgeon, Dr. Chiodo, and the pediatric staff at Toronto Eastern General Hospital. He&amp;rsquo;s recovering pretty much as can be expected, thank you very much for asking.&lt;br /&gt;&lt;br /&gt;One thing I noticed about the process. It all started with a referral from a General Practitioner, in this case our Family Physician Dr. Kohut. She analyzed the situation and determined that an opinion from a specialist was appropriate. This being socialized medicine, you couldn&amp;rsquo;t pull out our wallet and go straight to the specialist, we had to have our GP do a little qualifying first.&lt;br /&gt;&lt;br /&gt;But the interesting thing is what happened next. We went to see Dr. Chiodo, he examined Thomas, and after discussing our options and the risks associated with the procedure with us, he booked Thomas for surgery.&lt;br /&gt;&lt;br /&gt;Then today, Dr. Chiodo removed his tonsils and adenoids. This is standard procedure, and I want to mention it to compare it to programming, of course. You notice that although Dr. Chiodo is a very busy specialist, he does his own diagnoses. There is no division of labour where one doctor determines that the tonsils need to come out and the first time the surgeon sees the patient is when the anesthetist signals it&amp;rsquo;s ok to proceed.&lt;br /&gt;&lt;br /&gt;The person performing the procedure is the most qualified to diagnose the patient and also&amp;mdash;mark my words carefully&amp;mdash;the person who discusses the options and risks with the patient. This is sometimes the case in programming and sometimes not.&lt;br /&gt;&lt;br /&gt;Right now, I don&amp;rsquo;t feel like talking about what kinds of organizations divide things up so that one person sells the service to the client, another writes down the requirements, a third person estimates when it will be done and manages the process, a fourth person turns the requirements into a design and a specification, and finally the hapless programmer, the &amp;ldquo;specialist,&amp;rdquo; performs the procedure without any meaningful influence over the diagnosis or the decision-making process. Let&amp;rsquo;s skip that rant.&lt;br /&gt;&lt;br /&gt;Let&amp;rsquo;s also skip a rant about how many programmers have the skills to diagnose the patient, by which I mean, the business acumen to discuss what a client actually needs to accomplish in business terms. Let&amp;rsquo;s not argue about how many programmers have the communication skills to present the options to a client in such a way as to guide a client to making a smart decision while still ensuring that the programmer&amp;rsquo;s business profits. (This is relevant even when programmer and client are employed by the same organization).&lt;br /&gt;&lt;br /&gt;Let&amp;rsquo;s talk about &lt;strong&gt;you&lt;/strong&gt;. Do you have the specialist&amp;rsquo;s skill set? Can you diagnose, inform, and operate?&lt;br /&gt;&lt;br /&gt;If not, why not?</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/chiodo-rhymes-with-kyoto.html' title='What is a Specialist&apos;s Skill Set?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=1183240892363101558' title='17 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/1183240892363101558'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/1183240892363101558'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-1465940092625540313</id><published>2008-04-01T12:19:00.007-04:00</published><updated>2008-04-01T12:58:45.123-04:00</updated><title type='text'>Raganwald in disagreement</title><content type='html'>Relax, this is not one of the 17,322 April Fool&amp;rsquo;s posts to arrive in your feed reader today. Quite seriously, I just discovered that I am inconsistent, and that is very interesting in a &lt;a href="http://www.amazon.com/gp/search?ie=UTF8&amp;keywords=raymond%20smullyan&amp;tag=raganwald001-20&amp;index=books&amp;linkCode=ur2&amp;camp=1789&amp;creative=9325"&gt;Raymond Smullyan&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; kind of way.&lt;br /&gt;&lt;br /&gt;Here&amp;rsquo;s the thing: Many of my posts extol the virtues of programmers to producing programs. Not everyone agrees, of course, many people claim what you need are these &amp;ldquo;engineering principles&amp;rdquo; and even complete idiots will magically produce working software with terrific ROI over the complete software lifetime. Naturally, when these principles are elucidated, they are quickly diminished, because if you can name one such principle, you can also find someone who tried it and failed.&lt;br /&gt;&lt;br /&gt;Of course, the same goes for smart people: it&amp;rsquo;s easy to hand wave and say, &amp;ldquo;You need smart people who can get things done.&amp;rdquo; But that&amp;rsquo;s begging the question: looking at a successful project and declaring that the people &lt;em&gt;were&lt;/em&gt; smart and &lt;em&gt;did&lt;/em&gt; get things done is easy. But coming up with an unambiguous and objective measure for deciding who &lt;em&gt;is&lt;/em&gt; smart and who &lt;em&gt;will&lt;/em&gt; get things done is hard.&lt;br /&gt;&lt;br /&gt;Any blogger can rant (as I rant) about smart people, but the easy reply is to ask for a repeatable process for selecting such people. What&amp;rsquo;s on their r&amp;eacute;sum&amp;eacute;? What questions do you ask in the interview? How many references do you check? What do you look for in their portfolio? What do you expect to see in their code samples?&lt;br /&gt;&lt;br /&gt;Not so easy, &lt;a href="http://weblog.raganwald.com/2008/02/naive-approach-to-hiring-people.html" title="The Na&amp;iuml;ve Approach to Hiring People"&gt;is it&lt;/a&gt;?&lt;br /&gt;&lt;br /&gt;Any ways, let&amp;rsquo;s accept that I rant about programmers being important without having any sort of objective, reproducible process for selecting such programmers. A scientist would laugh at me, but then again a scientist would laugh at everyone mumbling about software project management and the ROI from using Java instead of Lisp&amp;mdash;such claims are equally unproven.&lt;br /&gt;&lt;br /&gt;However, let&amp;rsquo;s be charitable and chalk it up to &lt;a href="http://weblog.raganwald.com/2007/11/i-think-it-funny-that-aspects-were.html" title="The Optimistic View"&gt;optimism&lt;/a&gt;. Fine.&lt;br /&gt;&lt;br /&gt;But what&amp;rsquo;s with my posts extolling the virtues of programming languages and suggesting they are important? If a better language (whatever that means) can make a good programmer better, why can&amp;rsquo;t it make a mediocre programmer acceptably average?&lt;br /&gt;&lt;br /&gt;And if good programmers are &amp;ldquo;All that and a fresh bag of chips,&amp;rdquo; why can&amp;rsquo;t they do just fine with Java or Visual Basic? Why do they need these so-called better languages?&lt;br /&gt;&lt;br /&gt;Well? What&amp;rsquo;s the deal? Is it the programmer? Or is it the tool?</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/04/raganwald-in-disagreement.html' title='Raganwald in disagreement'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=1465940092625540313' title='23 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/1465940092625540313'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/1465940092625540313'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-61570333898526208</id><published>2008-03-29T11:03:00.004-04:00</published><updated>2008-03-29T15:09:34.385-04:00</updated><title type='text'>The only workable system for generating interesting, cool, and relevant software</title><content type='html'>&lt;blockquote&gt;The only workable system for generating interesting, cool, and relevant software is well-known. Find a bunch of really smart programmers and point them at a large problem space for which there are actual users, and for which new solutions are unconstrained by old designs.&lt;/blockquote&gt;&lt;div&gt;&amp;mdash;Mencius Moldbug, &lt;a href="http://unqualified-reservations.blogspot.com/2007/08/whats-wrong-with-cs-research.html"&gt;What&amp;rsquo;s Wrong with CS Research&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Note the desired outcome: Interesting, cool, and &lt;em&gt;relevant&lt;/em&gt; software. Do not become mired in empty debate over the phrase &amp;ldquo;smart programmers.&amp;rdquo; Instead, ponder the other three preconditions: a &lt;em&gt;large problem space, actual users&lt;/em&gt; and most especially &lt;em&gt;unconstrained by old designs&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Alan Kay is purported to have said, &amp;ldquo;A fresh perspective is worth 80 IQ points.&amp;rdquo; You cannot have a fresh perspective when you are encumbered by backwards compatibility.</content><link rel='alternate' type='text/html' href='http://weblog.raganwald.com/2008/03/simple-truth.html' title='The only workable system for generating interesting, cool, and relevant software'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7618424&amp;postID=61570333898526208' title='7 Comments'/><link rel='replies' type='application/atom+xml' href='http://weblog.raganwald.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/61570333898526208'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7618424/posts/default/61570333898526208'/><author><name>Reginald Braithwaite</name><uri>http://www.blogger.com/profile/13132345822387028437</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-7618424.post-1249877025882698553</id><published>2008-03-24T05:00:00.012-04:00</published><updated>2008-03-25T10:10:03.363-04:00</updated><title type='text'>Is software the documentation of business process mistakes?</title><content type='html'>Some time ago, I learned an amusing but insightful maxim:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The user manual is a list of software design mistakes.&lt;/blockquote&gt;&lt;br /&gt;&lt;font size="-1"&gt;(It may have been from &lt;a href="http://www.amazon.com/gp/product/0465067107?ie=UTF8&amp;tag=raganwald001-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0465067107"&gt;The Design of Everyday Things&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=raganwald001-20&amp;l=as2&amp;o=1&amp;a=0465067107" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt;, I don&amp;rsquo;t remember and a cursory web search hasn&amp;rsquo;t been helpful.)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Well-designed things may not be perfectly discoverable and consistent and stable, they may not be obvious and &lt;a href="http://weblog.raganwald.com/2008/01/programming-language-cannot-be-better.html" title="A programming language cannot be better without being unintuitive"&gt;familiar&lt;/a&gt;, but in general, if something needs a lot of explanation, it may need rethinking.&lt;br /&gt;&lt;br /&gt;Note that this does not mean that you can&amp;rsquo;t introduce something new that needs explaining. But overall, you are seeking &lt;em&gt;economy&lt;/em&gt; in the user manual. So you want to introduce as few thing