<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Steve Rowe&amp;#39;s Blog</title><subtitle type="html">Ruminations on Computing - Programming, Test Development, Management and More</subtitle><id>http://blogs.msdn.com/b/steverowe/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/b/steverowe/atom.aspx" /><generator uri="http://telligent.com" version="5.6.583.19199">Telligent Community 5.6.583.19199 (Build: 5.6.583.19199)</generator><updated>2009-04-30T10:04:41Z</updated><entry><title>Steve Jobs on the Value of Saying No</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2011/10/06/steve-jobs-and-the-value-of-saying-no.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2011/10/06/steve-jobs-and-the-value-of-saying-no.aspx</id><published>2011-10-07T02:29:00Z</published><updated>2011-10-07T02:29:00Z</updated><content type="html">&lt;p&gt;I ran across a great segment of Steve Jobs talking at the WWDC in 1997 just after he returned to Apple.&amp;nbsp; Similar to my post about &lt;a href="http://blogs.msdn.com/b/steverowe/archive/2011/09/27/pruning-the-decision-tree.aspx"&gt;pruning the decision tree&lt;/a&gt;, he speaks about the power of saying no to the bad ideas.&amp;nbsp; "Focusing is about saying no," he says.&amp;nbsp; His analysis of what was wrong with Apple at that time was that they had terrible engineering management.&amp;nbsp; They were doing too many things--interesting things--but had no direction.&amp;nbsp; When he took over, the decisions that had to be made were not to cut things that were bad, but to cut things that were unfocused.&amp;nbsp; A lack of focus makes the whole less than the sum of the parts.&amp;nbsp; Good focus allows the whole to become greater than the sum of the parts.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Two segments are worth watching.&amp;nbsp; The first is Steve Jobs explaining his philosophy:&lt;/p&gt;
&lt;p&gt;&lt;iframe height="315" src="http://www.youtube.com/embed/x7dqG9m9d44" frameborder="0" width="420" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;The second is him responding to a question about why they cut OpenDoc.&amp;nbsp; The interesting observation is that OpenDoc was probably better than anything else at some things.&amp;nbsp; That, by itself, wasn't enough.&amp;nbsp; It had to be part of a larger vision or it had to go.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;iframe height="315" src="http://www.youtube.com/embed/FF-tKLISfPE" frameborder="0" width="420" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;He ends with a great observation about how you have to let the vision dictate the technology and not the other way around.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10221407" width="1" height="1"&gt;</content><author><name>thornkin@hotmail.com</name><uri>http://blogs.msdn.com/thornkin_4000_hotmail.com/ProfileUrlRedirect.ashx</uri></author><category term="Management" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Management/" /><category term="Computing History" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Computing+History/" /></entry><entry><title>How much did Steve Jobs Mean To the Tech Industry?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2011/10/05/how-much-did-steve-jobs-mean-to-the-tech-industry.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2011/10/05/how-much-did-steve-jobs-mean-to-the-tech-industry.aspx</id><published>2011-10-06T03:55:15Z</published><updated>2011-10-06T03:55:15Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This picture says it all.&amp;nbsp; The front page of &lt;a href="http://news.ycombinator.com/"&gt;Hacker News&lt;/a&gt; is completely dominated by the news of Steve's death.&amp;nbsp; Even as someone who never owned an Apple product, he had a huge influence and raised the bar.&amp;nbsp; Not just once, but at least 5 major products from him changed the state of the industry.&amp;nbsp; The Apple // was a watershed for personal computers.&amp;nbsp; The Mac for UI.&amp;nbsp; The iPod and especially iTunes for digital music.&amp;nbsp; The iPhone completely changed the phone business.&amp;nbsp; The iPad created a whole new category of devices.&amp;nbsp; His influence will be greatly missed.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-33-97/5287.SteveJobs.png"&gt;&lt;img border="0" alt="" src="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-33-97/5287.SteveJobs.png" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10220983" width="1" height="1"&gt;</content><author><name>thornkin@hotmail.com</name><uri>http://blogs.msdn.com/thornkin_4000_hotmail.com/ProfileUrlRedirect.ashx</uri></author><category term="Computing History" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Computing+History/" /></entry><entry><title>Pruning the Decision Tree in Test</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2011/09/28/pruning-the-decision-tree-in-test.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2011/09/28/pruning-the-decision-tree-in-test.aspx</id><published>2011-09-28T14:26:00Z</published><updated>2011-09-28T14:26:00Z</updated><content type="html">&lt;p&gt;Yesterday I &lt;a href="http://blogs.msdn.com/b/steverowe/archive/2011/09/27/pruning-the-decision-tree.aspx"&gt;wrote&lt;/a&gt; about the need to reduce the number of things a project attempted to do in order to deliver a great product.&amp;#160; Too many seemingly good ideas can make a product late or fragmented or both.&amp;#160; The same is true of testing a product.&amp;#160; Great testing is more about deciding what not to test than deciding what to test.&lt;/p&gt;  &lt;p&gt;There is never enough time to test everything about a product.&amp;#160; This isn’t just the fault of marketing which has a go-to-market date in mind.&amp;#160; It is a physical reality.&amp;#160; To thoroughly test a product requires traversing the entire state tree in each possible combination.&amp;#160; This is analogous to the traveling salesman problem and is thus &lt;a href="http://en.wikipedia.org/wiki/NP-complete"&gt;NP-Complete&lt;/a&gt;.&amp;#160; In layman’s terms, this means that there is not enough time to test everything for any non-trivial program.&lt;/p&gt;  &lt;p&gt;When someone first starts testing, thinking up test cases is hard.&amp;#160; We often ask potential hires to test something like a telephone or a pop machine.&amp;#160; We are looking for creativity.&amp;#160; Can they think up a lot of interesting test cases?&amp;#160; After some time in the field, however, most people are able to think up a lot more tests than they have time to carry out.&amp;#160; The question then becomes no longer one of inclusion, but one of exclusion.&lt;/p&gt;  &lt;p&gt;In Netflix’s case the exclusion was for focus.&amp;#160; This is not the right exclusion criteria for testing.&amp;#160; It is improper to not test the UI so that you can test the backing database.&amp;#160; Instead, the criteria by which tests should be excluded is more complex.&amp;#160; There is no single criteria or set of criteria that work for every project.&amp;#160; Here are some to consider which have wide applicability:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Breadth of coverage – Often times it is best to try everything a little rather than some things very deep and others not at all.&amp;#160; Don’t get caught up testing just one part.&lt;/li&gt;    &lt;li&gt;Scenario coverage – Look for test cases which will intersect the primary use patterns of the users.&amp;#160; If no one is likely to try to put a square inside a circle inside a square, finding a but in it is not highly valuable.&lt;/li&gt;    &lt;li&gt;Risk analysis – What areas of the product would be most problematic if they went wrong?&amp;#160; Losing user data is almost always really bad.&amp;#160; Drawing a line one pixel off often is not.&amp;#160; If you have to choose, prefer focusing more on the data than the drawing.&amp;#160; Another important area for many projects are legal or regulatory requirements.&amp;#160; If you have these, make sure to test for them.&amp;#160; It doesn’t matter how well your product works if the customer is not allowed to buy it.&lt;/li&gt;    &lt;li&gt;Cost of servicing – If forced to choose, spend more time on the portions that will be more difficult or costly to service if a bug shows up in the field.&amp;#160; For instance, in a client-server architecture, it is usually easier to service the server because it is in one spot, under your control, rather than trying to go to hundreds or thousands of computers to update the client software.&lt;/li&gt;    &lt;li&gt;Testing cost – While not a good criteria to use by itself, if a test is too expensive to carry out or to automate, perhaps it should be skipped in favor of writing many more tests that are much cheaper.&amp;#160; &lt;/li&gt;    &lt;li&gt;Incremental gains – How much does this test case add to existing coverage?&amp;#160; It is better to try something wholly new than another slight variation on an existing case.&amp;#160; Thinking in terms of code coverage may help here.&amp;#160; It is usually better to write a case which tests 10 new blocks than one which tests 15 already covered blocked and 2 new ones.&amp;#160; It is very possible that two test cases are both great, but the combination is not.&amp;#160; Choose one.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are many more criteria that could be used.&amp;#160; The important point is to have criteria and to &lt;a href="http://blogs.msdn.com/b/steverowe/archive/2009/07/01/be-intentional.aspx"&gt;make intentional decisions&lt;/a&gt;.&amp;#160; A test planning approach that merely says, “What are the ways we can test this product?” is insufficient.&amp;#160; It will generate too many test cases, some of which will never be carried out due to time or cost.&amp;#160; It is important to prune the decision tree up front so that the most important cases are done and the least important ones are left behind.&amp;#160; Do this up front, in the test spec, not on the fly as resources dwindle.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10217279" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Testing" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Testing/" /></entry><entry><title>Pruning the Decision Tree</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2011/09/27/pruning-the-decision-tree.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2011/09/27/pruning-the-decision-tree.aspx</id><published>2011-09-27T15:54:00Z</published><updated>2011-09-27T15:54:00Z</updated><content type="html">&lt;p&gt;A great &lt;a href="http://marcrandolph.com/2011/09/26/did-netflix-screw-up-i-dont-think-so/"&gt;post&lt;/a&gt; by Marc Randolph got me thinking.&amp;#160; He tackles the question of why Netflix made the moves they made recently.&amp;#160; Specifically, why did they spin off their DVD option as a company called Qwixter?&amp;#160; The answer: focus.&lt;/p&gt;  &lt;p&gt;What separates successful ventures from failures is choosing to do the right things.&amp;#160; What separates great successes from merely good ones is choosing not to do the wrong things.&lt;/p&gt;  &lt;p&gt;When faced with a question about whether to add a feature, the decision often revolves around whether customers will like it.&amp;#160; This is a good first question, but stopping there leads to sub-optimal results.&amp;#160; It is important to ask the next question:&amp;#160; What can we not do by doing this?&amp;#160; Resources are limited.&amp;#160; For each feature that goes into a product, something else(quality, time, other features) comes out.&amp;#160; If that is forgotten, the product will end up with too many features that are good but not great and a product that feels the same.&lt;/p&gt;  &lt;p&gt;Shipping a great product then is about the decisions about what features not to implement and what bugs not to fix.&amp;#160; Netflix demonstrates what it looks like to take this very seriously.&amp;#160; They are jettisoning what is a popular part of their company so they can focus on what they think is the future.&amp;#160; Only time will tell if they chose the right strategy, but one has to commend them for making a clear choice.&amp;#160;&amp;#160; &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10217032" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Architecture" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Architecture/" /></entry><entry><title>Follow my adventures at //build/</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2011/09/15/follow-my-adventures-at-build.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2011/09/15/follow-my-adventures-at-build.aspx</id><published>2011-09-15T16:52:00Z</published><updated>2011-09-15T16:52:00Z</updated><content type="html">&lt;p&gt;This week I'm attending the &lt;a href="http://www.buildwindows.com///build/"&gt;//build/&lt;/a&gt; conference where Microsoft is revealing many of the details about Windows 8.&amp;nbsp; If you want to see what is going on, follow my Twitter feed at &lt;a href="http://twitter.com/steverowe"&gt;http://twitter.com/steverowe&lt;/a&gt;,&amp;nbsp; I'm posting some pictures, linking to summaries, etc.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10211823" width="1" height="1"&gt;</content><author><name>thornkin@hotmail.com</name><uri>http://blogs.msdn.com/thornkin_4000_hotmail.com/ProfileUrlRedirect.ashx</uri></author><category term="Windows" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Windows/" /><category term="Personal" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Personal/" /></entry><entry><title>Listening to the team</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2011/09/12/listening-to-the-team.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2011/09/12/listening-to-the-team.aspx</id><published>2011-09-12T08:00:00Z</published><updated>2011-09-12T08:00:00Z</updated><content type="html">&lt;p&gt;There is an old saying in software that goes something like this, &amp;ldquo;&lt;a href="http://37signals.com/svn/archives2/2005/04/getting_real_pi.php"&gt;Scope, Timeframe, and Budget: Pick two.&lt;/a&gt;&amp;rdquo;&amp;nbsp; Being a tester, I would rephrase this a little as, &amp;ldquo;Features, Timeframe, Budget, and Quality; Pick three&amp;rdquo;.&amp;nbsp; It&amp;rsquo;s usually possible to hit all three of the first choice as long as you are willing to sacrifice quality.&amp;nbsp; We&amp;rsquo;ve all seen products that do this.&amp;nbsp; They have such potential, but just don&amp;rsquo;t work.&amp;nbsp; Over the past year, there were lot of planning efforts going on around me and this was a great chance to observe different behaviors.&amp;nbsp; One pattern I have seen a few times is worth discussing.&amp;nbsp; That is managers trying to dictate all 4 aspects of a project.&amp;nbsp; There are two ways this tends to happen: the dictatorial manager and the persuasive manager.&lt;/p&gt;
&lt;p&gt;Before we jump in, it is important to define the four levers.&amp;nbsp; Features represent the complexity of the product&amp;mdash;how many things it can accomplish.&amp;nbsp; Timeframe is how soon the product needs to ship.&amp;nbsp; Budget is how much can be spent on the project.&amp;nbsp; For software projects, this corresponds largely with the number and skill of people that can be put on the task.&amp;nbsp; No discussion of budget can be complete without at least mentioning &lt;a href="http://en.wikipedia.org/wiki/Brooks%27_law"&gt;Brooks&amp;rsquo; law&lt;/a&gt;.&amp;nbsp; &lt;a href="http://www.amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0553277472"&gt;Quality&lt;/a&gt; is the ineffable attribute representing beauty, greatness, or merely suitability for a given task.&amp;nbsp; In practical terms it means how many bugs are exposed by the product.&amp;nbsp; Increasing the expectations for any of these increases the pressure on the project.&amp;nbsp; Within reason, each can be relaxed to achieve the desired levels of the other three.&amp;nbsp; It is important that managers understand that when they ask to increase features, they are trading off time or that when they ask to reduce time, they are trading off features.&lt;/p&gt;
&lt;p&gt;The dictatorial manager is the more obvious of the two.&amp;nbsp; This is the person that just says, &amp;ldquo;You will have the following specs done by this date.&amp;rdquo;&amp;nbsp; Implied is that this will be done with a fixed number of people (never enough) and of high quality.&amp;nbsp; This is the pointy haired boss from Dilbert.&amp;nbsp; When the team raises objections, this manager is unphased.&amp;nbsp; They stick to their position.&amp;nbsp; If the team can&amp;rsquo;t get it done in the timeframe they ask for, they will find someone else who will.&amp;nbsp; It never occurs to the manager that perhaps what they are asking for is impossible.&amp;nbsp; The only good news is that this type of manager is often self-correcting.&amp;nbsp; They are not enjoyable to work for.&amp;nbsp; The best members of the team have mobility and will leave.&amp;nbsp; This slowly guts the team of the most capable people and the project slowly fails.&amp;nbsp; At a quality company this manager will be seen for who he is and removed from such responsibility.&lt;/p&gt;
&lt;p&gt;The persuasive manager is less obvious but nearly as bad.&amp;nbsp; This is the manager who convinces their team that it can do the impossible.&amp;nbsp; In this case they don&amp;rsquo;t dictate an impossible situation, they merely get the team to agree to it.&amp;nbsp; This manager is usually a really nice guy who just can&amp;rsquo;t say no.&amp;nbsp; Instead they ask people nicely to sign up for everything marketing and upper management ask for.&amp;nbsp; Their team likes working for them, it just can&amp;rsquo;t figure out why it is so over-worked.&amp;nbsp; The quality of the project suffers as the team goes into an over-worked haze.&amp;nbsp; This sort of manager is not as quickly self-correcting.&amp;nbsp; The team does not leave except through burn-out.&amp;nbsp; They don&amp;rsquo;t blame the manager because signing up for the work was their idea.&amp;nbsp; Neither the dictatorial manager nor the persuasive manager will succeed.&amp;nbsp; Both will usually ship something close to on time because they cannot admit failure.&amp;nbsp; The quality, however, will be low.&amp;nbsp; People stop caring once they are made to attempt the impossible.&amp;nbsp; The team will be much weaker the next go-round because all of the good members leave through disgust or attrition.&lt;/p&gt;
&lt;p&gt;A better model is to listen to the team.&amp;nbsp; Most times a manager does not have control of all of the levers.&amp;nbsp; Typically timeframe and budget comes down from on high.&amp;nbsp; A manager cannot magically hire more people.&amp;nbsp; Except through brinksmanship, they cannot cause the project to ship later.&amp;nbsp; They do, however, have control over the expect level of quality and the number of features.&amp;nbsp; A team will usually give signals if they think they are being asked to do too much.&amp;nbsp; The wise manager listens to this and adjusts plans accordingly.&amp;nbsp; This is the genius of systems like Scrum and Agile development.&amp;nbsp; A tenet of these systems is listening to the team.&amp;nbsp; Using a system of cost estimates and burndown tracking helps bring an objective view of the picture.&amp;nbsp; Likewise, if the team hesitates or balks at signing up for work, a good manager will re-evaluate.&amp;nbsp; This doesn&amp;rsquo;t mean automatically reducing the ask, but it does mean making sure you are convinced it can be done.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If a manager senses that the workload is too much, it is their responsibility to reduce it.&amp;nbsp; As much of a manager&amp;rsquo;s job should be spent deciding what not to do as deciding what to do.&amp;nbsp; This may generate heat from upper management who wants everything in a limited time, with a fixed budget, and at the highest quality.&amp;nbsp; Helping upper management understand the situation and even taking the pain if understanding is not conveyed is the responsibility of the manager.&amp;nbsp; If failure is inevitable, it is better to fail in a place of your choosing (that with the least impact/priority) rather than risk failure on a broader scale at a later date.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10209303" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Management" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Management/" /></entry><entry><title>The Sidebar is Back!</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2010/05/11/the-sidebar-is-back.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2010/05/11/the-sidebar-is-back.aspx</id><published>2010-05-12T03:55:00Z</published><updated>2010-05-12T03:55:00Z</updated><content type="html">I'm apparently in the minority, but I really liked the sidebar in Windows Vista.&amp;nbsp; On a widescreen monitor, there is horizontal space to waste and it was really convenient to have all of my gadgets showing over on the right-hand side.&amp;nbsp; In Windows 7, the sidebar was removed.&amp;nbsp; Gadgets are still there, but to me they became less useful because they were either hidden below all my windows or obscuring them.&amp;nbsp; There was no way to have them always show and have windows flow around them.&amp;nbsp; I've just discovered a new gadget called 7 Sidebar that acts just like the Vista sidebar, but for Windows 7.&amp;nbsp; You can find it &lt;A href="http://nes.bplaced.net/sidebar7.html" mce_href="http://nes.bplaced.net/sidebar7.html"&gt;here&lt;/A&gt; if you too liked the look of the sidebar.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10011385" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Windows" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Windows/" /></entry><entry><title>Netcast List April 2010</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2010/04/29/netcast-list-april-2010.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2010/04/29/netcast-list-april-2010.aspx</id><published>2010-04-29T16:10:22Z</published><updated>2010-04-29T16:10:22Z</updated><content type="html">&lt;p&gt;It’s been a long time since I updated my netcast list, but my habits have changed a bit.&amp;#160; Here is what I currently listen to regularly:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.twit.tv/twit"&gt;This Week in Tech&lt;/a&gt; – Weekly Tech News Roundup&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.geekbrief.tv/"&gt;GeekBrief&lt;/a&gt; – Daily snippet of gadget news&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.threedonkeys.com/blog/"&gt;Games with Garfield&lt;/a&gt; – Monthly gaming podcast featuring the creator of Magic: The Gathering&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blog.stackoverflow.com/"&gt;StackOverflow Podcast&lt;/a&gt; – The podcast is changing so I have to decide whether the new format stays in heavy rotation.&amp;#160; It has been a good podcast for programming types.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.twit.tv/ww"&gt;Windows Weekly&lt;/a&gt; – Everything Microsoft&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I listen to these when I can:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.manager-tools.com/"&gt;Manager Tools&lt;/a&gt; – I’ve learned a lot about being a better manager from these guys.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://revision3.com/tekzilla/"&gt;Tekzilla&lt;/a&gt; – Video tech news&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.crankygeeks.com/"&gt;Cranky Geeks&lt;/a&gt; – More tech news&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.twit.tv/FLOSS"&gt;FLOSS Weekly&lt;/a&gt; – Interviews with open source projects.&amp;#160; Very interesting if you are a programmer.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.econtalk.org/"&gt;Econtalk&lt;/a&gt; – Interviews with economists.&amp;#160; Usually pretty accessible.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://webcast.berkeley.edu/courses.php?semesterid=2010-B"&gt;Berkeley Webcasts&lt;/a&gt; – All kinds of classes from Berkeley in podcast format.&amp;#160; I suggest &lt;a href="http://webcast.berkeley.edu/media/common/rss/Computer_Science_61A__001_Spring_2010_Video__webcast.rss"&gt;CS61a&lt;/a&gt; which teaches through &lt;a href="http://mitpress.mit.edu/sicp/"&gt;SICP&lt;/a&gt;.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.fundadvice.com/sound-investing/"&gt;Sound Investing&lt;/a&gt; – Investment discussion focused on buy and hold index fund investing.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you have suggestions, leave them in the comments.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10004622" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Netcasts" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Netcasts/" /></entry><entry><title>Resume Advice: List Your Classes and Projects</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2010/03/19/resume-advice-list-your-classes-and-projects.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2010/03/19/resume-advice-list-your-classes-and-projects.aspx</id><published>2010-03-19T15:28:00Z</published><updated>2010-03-19T15:28:00Z</updated><content type="html">&lt;p&gt;It is campus hiring season and I have been reading a lot of college resumes lately.&amp;#160; One thing I have noticed on many resumes is that they do not list what I consider to be some of the most relevant information.&amp;#160; As important as it is that someone made the Dean’s list or worked at Best Buy, it is even more important to know their experience that is directly relevant to the job.&amp;#160; Some have internships and these are directly relevant.&amp;#160; Others have not been so lucky.&amp;#160; That’s fine, but if you find yourself in this bucket, please, please list your classes and describe the major projects you have worked on.&amp;#160; Knowing what projects were worked on gives me, the interviewer, a much better sense of what you are capable of.&amp;#160; It also gives me more material to latch onto and ask questions about.&amp;#160; As a candidate, you want me asking questions about your projects because you should understand them well and be able to talk about them fluently.&amp;#160; Additionally, without classes and projects, a resume with jobs working at Home Depot or the local KFC looks just like every other resume.&amp;#160; It is your internships, projects, and possibly classes that set you apart.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9979222" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Other" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Other/" /></entry><entry><title>Pass Rates Don’t Matter</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2010/03/17/pass-rates-don-t-matter.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2010/03/17/pass-rates-don-t-matter.aspx</id><published>2010-03-17T12:50:00Z</published><updated>2010-03-17T12:50:00Z</updated><content type="html">&lt;p&gt;It seems obvious that test pass rates are important.&amp;#160; The higher the pass rate, the better quality the product.&amp;#160; The lower the pass rate, the more known issues there are and the worse the quality of the product.&amp;#160; It then follows that teams should drive their pass rates to be high.&amp;#160; I’ve shipped many products where the exit criteria included some specified pass rate—usually 95% passing or higher.&amp;#160; For most of my career I agreed with that logic.&amp;#160; I was wrong.&amp;#160; I have come to understand that pass rates are irrelevant.&amp;#160; Pass rates don’t tell you the true state of the product.&amp;#160; It is important which bugs remain in the product, but pass rates don’t actually show this.&lt;/p&gt;  &lt;p&gt;The typical argument for pass rates is that it represents the quality of the product.&amp;#160; This makes the assumption that the tests represent the ideal product.&amp;#160; If they all passed, the product would be error-free (or free enough).&amp;#160; Each case is then an important aspect of this ideal state and any deviation from 100% pass is a failure to achieve the ideal.&amp;#160; This isn’t true though.&amp;#160; How many times have you shipped a product with 100% passing tests?&amp;#160; Why?&amp;#160; You probably rationalized that certain failures were not important.&amp;#160; You were probably right.&amp;#160; Not every case represents this ideal state.&amp;#160; Consider a test that calls a COM API and checks the return result.&amp;#160; Assuming you pass in a bar argument and the return result is E_FAIL.&amp;#160; Is that a pass?&amp;#160; Perhaps.&amp;#160; A lot of testers would fail this because it wasn’t E_INVALIDARG.&amp;#160; Fair point.&amp;#160; It should be.&amp;#160; Would you stop the product from shipping because of this though?&amp;#160; Perhaps not.&amp;#160; The reality is that not all cases are important.&amp;#160; Not all cases represent whether the product is ready to ship or not.&lt;/p&gt;  &lt;p&gt;Another argument is that 100% passing is a bright line that is easy to see.&amp;#160; Anything less is hard to see.&amp;#160; Did we have 871 or 872 passing tests yesterday?&amp;#160; If it was 871 and today is 871, are they the same 129 failures?&amp;#160; Determining this can be hard and it’s a good way to miss a bug.&amp;#160; It is easy to remember that everything passed yesterday and no bugs are hiding in the 0 failures.&amp;#160; I’ve made this argument.&amp;#160; It is true as far as it goes, but it only matters if we use humans to interpret the results.&amp;#160; Today we can use programs to analyze the failures automatically and to compare the results from today to those from yesterday.&lt;/p&gt;  &lt;p&gt;As soon as the line is not 100% passing, rates do not matter.&amp;#160; There is no inherent difference in the quality of a product with 99% passing tests and the quality of a product with 80% passing tests.&amp;#160; “Really?“ you say.&amp;#160; “Isn’t there a difference of 18%?&amp;#160; That’s a lot of test cases.”&amp;#160; Yes, that is true.&amp;#160; But how valuable are those cases?&amp;#160; Imagine a test suite with 100 test cases, only one of which touches on some core functionality.&amp;#160; If that case fails, you have a 99% passing rate.&amp;#160; You also don’t have a product that should ship.&amp;#160; On the other hand, imagine a test suite for the same software with 1000 cases.&amp;#160; Imagine that the testers were much more zealous and coded 200 cases that intersected that one bug.&amp;#160; Perhaps it was in some activation code.&amp;#160; These two pass rates then represent the exact same situation.&amp;#160; The pass rate does not correlate with quality.&amp;#160; Likewise one could imagine a test case of 1000 cases where 200 were bugs in the tests.&amp;#160; That is an 80% pass rate and a shippable product.&lt;/p&gt;  &lt;p&gt;The critical takeaway is that bugs matter, not tests.&amp;#160; Failing tests represent bugs, but not equally.&amp;#160; There is no way to determine, from a pass rate, how important the failures are.&amp;#160; Are they the “wrong return result” sort or the “your api won’t activate” sort?&amp;#160; You would hold the product for the 2nd, but not the first.&amp;#160; Tests pass/fail rates do not provide the critical context about what is failing and without the context, it cannot be known whether the product should ship or not.&amp;#160; Test cases are a means to an end.&amp;#160; They are not the end in themselves.&amp;#160; Test cases are merely a way to reveal the defects in a product.&amp;#160; After they do so, their utility is gone.&amp;#160; The defects (bugs) become the critical information.&amp;#160; Rather than worrying about pass rates, it is better to worry about how many critical bugs are left.&amp;#160; When all of the critical bugs are fixed, it is time to ship the product whether the pass rate is high or low.&lt;/p&gt;  &lt;p&gt;All that being said, there is some utility in driving up pass rates.&amp;#160; Failing cases can mask real failures.&amp;#160; Much like code coverage, the absolute pass rate does not matter, but the act of driving the pass rate up can yield benefits.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9979208" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Testing" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Testing/" /></entry><entry><title>The Complexity Hammer</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2010/03/16/if-complexity-is-the-hammer-not-all-problems-are-nails.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2010/03/16/if-complexity-is-the-hammer-not-all-problems-are-nails.aspx</id><published>2010-03-16T12:30:00Z</published><updated>2010-03-16T12:30:00Z</updated><content type="html">&lt;P&gt;I’ve been doing a lot of interviewing lately, especially of college students.&amp;nbsp; There is one tendency I see a that really separates those that are good from those who still have more learning to do.&amp;nbsp; This is the tendency of the good programmers to see elegant solutions to problems and the corollary that less skilled programmers solve every problem by adding more complexity.&amp;nbsp; Stated another way, the thing that separates the best programmers from the rest is what happens when they run into a serious issue.&amp;nbsp; In my observation, the best coders step back and look for a more elegant solution.&amp;nbsp; The less skilled coders assume that their approach is correct and that another piece of state or another special case is the best choice.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Here is an example.&amp;nbsp; The problem has been changed to protect the innocent.&amp;nbsp; Often times I ask a question similar to the change-making problem.&amp;nbsp; That is, write a program to enumerate all of the ways to make change for a dollar.&amp;nbsp; A typical approach might look something like this.&amp;nbsp; Note, I didn’t actually compile this code so there could be typos.&amp;nbsp; If there are, I’m sure you’ll let me know.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;void MakeChange()&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; int moneyLeft = 100;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; for (int quarters = 0; quarters &amp;lt;= 4; quarters++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (quarters) moneyLeft –= 25;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int dimes = 0; dimes &amp;lt;= 10; dimes++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (dimes) moneyLeft –=10;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int nickles = 0; nickles &amp;lt;=20; nickles++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (if nickles) moneyLeft –=5;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int pennies = 0; pennies &amp;lt;= 100; pennies++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pennies) moneyLeft—;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (0 == moneyLeft) print…;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;I know what you are thinking, “That’s not the right way to solve this.”&amp;nbsp; And you would be correct.&amp;nbsp; However, I have seen a lot of people give basically this solution.&amp;nbsp; Their failure to solve it correctly the first time isn’t the point of this post.&amp;nbsp; Rather, it is their response to the problem.&amp;nbsp; If you haven’t spotted it yet, this will only work correctly for the first time down for loops.&amp;nbsp; After we get to zero, we never gain the money back from the pennies we spent during the last nickles iteration.&amp;nbsp; When I point this out, the solution is too often not to step back and re-examine the problem.&amp;nbsp; “Is there something wrong with this solution?”&amp;nbsp; Rather the typical reaction is to assume that the solution is mostly right and to tweak it.&amp;nbsp; One might think of this as a specific case of not asking the &lt;A href="http://blogs.msdn.com/steverowe/archive/2008/10/17/the-five-why-s-and-testing-software.aspx" mce_href="http://blogs.msdn.com/steverowe/archive/2008/10/17/the-five-why-s-and-testing-software.aspx"&gt;5-Why’s&lt;/A&gt;.&amp;nbsp; The initial reaction is often just to reset moneyLeft at the top of the quarters loop.&amp;nbsp; When that doesn’t work, more variables are added.&amp;nbsp; The result solution looks something like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;void MakeChange()&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; int moneyLeft = 100;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; int moneyLeftQuarters = 100;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; int moneyLeftDimes = 100;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; int moneyLeftNickles = 100;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; for (int quarters = 0; quarters &amp;lt;= 4; quarters++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeft = moneyLeftQuarters;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (quarters) moneyLeft –= 25;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeftQuarters = moneyLeft;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int dimes = 0; dimes &amp;lt;= 10; dimes++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeft = moneyLeftDimes&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(dimes) moneyLeft –=10;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeftDimes = moneyLeft;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int nickles = 0; nickles &amp;lt;=20; nickles++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeft = moneyLeftNickles;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (nickles) moneyLeft –=5;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeftNickles = moneyLeft;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int pennies = 0; pennies &amp;lt;= 100; pennies++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; moneyLeft—;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (0 == moneyLeft) print…;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Not exactly an elegant solution and not one that is easy to get right.&amp;nbsp; There are a lot of subtle cases to think through.&amp;nbsp; Unfortunately, code like this, or code trying to be like this shows up on my white board too often.&amp;nbsp; In a simple problem such as this, it is possible to keep all of the cases in your head and get it right.&amp;nbsp; When the problem becomes larger, however, this is no longer the case.&amp;nbsp; The programmer with the above solution will fail.&amp;nbsp; Thus the solution above is not an acceptable answer even though is technically solves the problem.&lt;/P&gt;
&lt;P&gt;If one takes a few moments to step back and re-examine the problem, it is easy enough to see that one doesn’t need to track the amount of money left.&amp;nbsp; It can be trivially calculated when necessary.&amp;nbsp; This is just a specific case of the principle that one should never keep state that can be calculated.&amp;nbsp; Tracking such state provides no benefit and offers the possibility that it will differ from the real state.&amp;nbsp; The solution might look like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;void BetterMakeChange()&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; for (int quarters = 0; quarters &amp;lt;= 4; quarters++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int dimes = 0; dimes &amp;lt;= 10; dimes++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int nickles = 0; nickles &amp;lt;=20; nickles++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int pennies = 0; pennies &amp;lt;= 100; pennies++)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (100 == (quarters*25 + dimes*10 + nickles*5 + pennies)) print…;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Much more elegant.&amp;nbsp; Fewer state variables and thus less to get wrong.&amp;nbsp; All of this stems from the idea that one need not track state.&amp;nbsp; There is no reason to keep a running total of the money.&amp;nbsp; It’s all readily available at any moment.&amp;nbsp; It is this key notion that one needs in order to come up with a much improved algorithm.&amp;nbsp; As long as the programmer doesn’t step back and question the need for tracking how much money has been used/how much is left, they will be stuck adding complexity on top of complexity.&amp;nbsp; This is a prescription for failure.&amp;nbsp; This is not an isolated case.&amp;nbsp; Now that I have noticed this tendency, I can often spot it in interviews or even in code reviews.&amp;nbsp; The moral of the story:&amp;nbsp; always look for the elegant solution first.&amp;nbsp; Can the problem be solved by eliminating something or by looking at the problem differently?&amp;nbsp; Only once you have eliminated these possibilities should you add more state.&amp;nbsp; Adding state isn’t always the wrong solution, but it can be a crutch to avoid deeper thinking.&lt;/P&gt;
&lt;P&gt;A few notes:&lt;/P&gt;
&lt;P&gt;The initial paragraph isn’t quiet accurate.&amp;nbsp; The best programmers often see the elegant solution up front and get themselves into such trouble much less often.&lt;/P&gt;
&lt;P&gt;The final solution is not optimal.&amp;nbsp; I know this.&amp;nbsp; Optimizing it would not benefit the example.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9979199" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Programming" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Programming/" /></entry><entry><title>Plan Intentionally</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2010/02/08/plan-intentionally.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2010/02/08/plan-intentionally.aspx</id><published>2010-02-08T15:36:00Z</published><updated>2010-02-08T15:36:00Z</updated><content type="html">&lt;p&gt;I previously wrote about being &lt;a href="http://blogs.msdn.com/steverowe/archive/2009/07/01/be-intentional.aspx"&gt;intentional&lt;/a&gt;, but focused mostly on intentionality in execution.&amp;#160; Being intentional is also important in planning.&amp;#160; When planning a new product or the implementation of a feature, it is important to explicitly consider all aspects.&amp;#160; It can be a temptation to move past the hard problems too quickly.&amp;#160; “We’ll get back to that later.”&amp;#160; Doing this can be disastrous.&amp;#160; It is important to note that the decision on how to solve a hard problem *will* be made.&amp;#160; It can be made up front in a thoughtful way, or it can be made on the fly at a later date, but it will be made.&amp;#160; Putting off the hard decisions merely makes it more likely that they will be made on the fly.&lt;/p&gt;  &lt;p&gt;This advice may seem obvious, but people don’t always follow it.&amp;#160; For critical-path decisions, people know better than to leave them for later.&amp;#160; It is the difficult peripheral issues that are sometimes left undecided.&amp;#160; The boundaries between two modules might be such a place.&amp;#160; The decisions on how to implement the module will certainly be decided, but might the way it is extended by or interacts with others be left for later?&amp;#160; &lt;/p&gt;  &lt;p&gt;I recall working on a feature for WindowsMe (this feature never shipped) which allowed video playback to be conditioned on some criteria.&amp;#160; Perhaps the parental levels were too high or the rights were not present to play a piece of video.&amp;#160; In that case, this feature would recognize this fact and stop playback.&amp;#160; The developer responsible for this feature had created a complex infrastructure with plug-in providers and a great signaling mechanism.&amp;#160; I was brought in to test the project late and took over from someone else.&amp;#160; After looking at the documentation and playing around with it for a bit, I thought I understood what was going on, but there was one part that confused me.&amp;#160; I went to the developer and asked him what happened when he sent the message that playback should stop.&amp;#160; Who listened to this event?&amp;#160; His response was that he didn’t know.&amp;#160; This hadn’t been specified.&amp;#160; Stop the presses!&amp;#160; Here we had a conditional playback system that was just shouting at the wind, hoping someone would hear it and do the right thing.&amp;#160; The developer of this system as well as the developer of the playback pipeline had both written fine pieces of software, but one detail hadn’t been intentionally planned and the end to end feature would not work.&amp;#160; Admittedly this is an extreme case, but similar things happen on a less obvious scale if people are not careful to plan intentionally.&lt;/p&gt;  &lt;p&gt;It isn’t always that the decisions are considered unimportant.&amp;#160; It is that time runs out.&amp;#160; When a hard decision is bypassed because it takes too long to decide, the chances of circling back to it before time pressure says coding has to start is high.&amp;#160; It is better to take the time to make the hard decision up front and leave the easier decisions to be made on the fly.&amp;#160; Acknowledge that there may not be enough time to do all the planning desired.&amp;#160; There never is.&amp;#160; Then decide on the most critical items first.&amp;#160; Be intentional about what is and is not going to get planned.&amp;#160; This way the unplanned items end up being those that are most conducive to being planned on the fly. &lt;/p&gt;  &lt;p&gt;In short: Tackle the hard issues early.&amp;#160; If you wait, they will be decided in a default/easy way.&amp;#160; If the issue was hard to decide up front, it will never be decided well in the midst of coding.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9959259" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Software Process" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Software+Process/" /></entry><entry><title>Resolved:  To Blog More in 2010</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/12/31/resolved-to-blog-more-in-2010.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/12/31/resolved-to-blog-more-in-2010.aspx</id><published>2010-01-01T01:38:00Z</published><updated>2010-01-01T01:38:00Z</updated><content type="html">&lt;P&gt;As the year closes I look back and see that my blogging really dropped off this past year.&amp;nbsp; I intend to try to blog more over this upcoming year.&amp;nbsp; My position at work has changed from a lead to a manager and that gives me a whole new perspective on things and a lot of new ideas to blog about.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;I hope your 2009 went well and that 2010 goes even better.&amp;nbsp; For those who are hurting in this bad economy, hang in there.&amp;nbsp; The sun always rises even if the night is long.&amp;nbsp; Don't give up improving your skills.&amp;nbsp; It will pay off in the long term.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9942749" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Personal" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Personal/" /></entry><entry><title>A Taste of Stack Overflow DevDays</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/11/23/a-taste-of-stack-overflow-devdays.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/11/23/a-taste-of-stack-overflow-devdays.aspx</id><published>2009-11-23T19:38:15Z</published><updated>2009-11-23T19:38:15Z</updated><content type="html">&lt;p&gt;If you missed Stack Overflow &lt;a href="http://blogs.msdn.com/steverowe/archive/2009/10/22/stackoverflow-devdays.aspx"&gt;DevDays&lt;/a&gt;, there is some audio from it available on &lt;a href="http://blog.stackoverflow.com/2009/10/podcast-71/"&gt;Stack Overflow Podcast #71.&lt;/a&gt;&amp;#160; I wish there was a longer version of this.&amp;#160; It’s only about 1/2 hour of outtakes from the conference, but it is still interesting to hear.&amp;#160; These snippets are followed by a long discussion with some of the speakers.&amp;#160; The conversation rambles and the audio quality is poor so feel free to stop listening after the conference outtakes.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9927475" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Programming" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Programming/" /><category term="Netcasts" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Netcasts/" /></entry><entry><title>Design Patterns Are Not Outdated</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/11/19/design-patterns-are-not-outdated.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/11/19/design-patterns-are-not-outdated.aspx</id><published>2009-11-19T16:43:00Z</published><updated>2009-11-19T16:43:00Z</updated><content type="html">&lt;P&gt;A &lt;A href="http://stackoverflow.com/questions/1761109/practical-uses-of-oop/1761169#1761169" mce_href="http://stackoverflow.com/questions/1761109/practical-uses-of-oop/1761169#1761169"&gt;comment&lt;/A&gt; left on my answer to a question over on Stack Overflow has me a little worked up.&amp;nbsp; I've seen this meme come out of programmers more and more and it just doesn't seem accurate.&amp;nbsp; The statement goes something like this, "Design Patterns were only useful because C++ (or Java) was so broken."&amp;nbsp; The implication is thus that design patterns belong in the dustbin of history now that we have moved on to more enlightened languages like Python or Ruby.&amp;nbsp; In this particular instance the commentor was talking about the &lt;A href="http://en.wikipedia.org/wiki/Strategy_Pattern" mce_href="http://en.wikipedia.org/wiki/Strategy_Pattern"&gt;strategy pattern&lt;/A&gt;.&amp;nbsp; His (?) assertion was that the need for the strategy pattern is not present in a language with first class functions.&amp;nbsp; My response is three-fold.&amp;nbsp; First off, this argument is historically ignorant.&amp;nbsp; The design patterns came as much from Smalltalk as from C++.&amp;nbsp; Second, it is not strictly true.&amp;nbsp; First class functions alone don't obviate the need for the strategy pattern.&amp;nbsp; Finally, providing an alternative implementation does not make the first implementation bad.&lt;/P&gt;
&lt;P&gt;The argument that design patterns generally are due to flaws in C++/Java are historically innaccurate.&amp;nbsp; Design patterns (like &lt;A href="http://blogs.msdn.com/steverowe/archive/2007/07/05/we-owe-it-all-to-smalltalk.aspx" mce_href="http://blogs.msdn.com/steverowe/archive/2007/07/05/we-owe-it-all-to-smalltalk.aspx"&gt;much of modern programming&lt;/A&gt;) originated in the Smalltalk community.&amp;nbsp; Smalltalk is dynamic.&amp;nbsp; It has first-class functions.&amp;nbsp; Most of the flaws pointed to in C++ which "modern" languages solve did not exist in Smalltalk.&amp;nbsp; The patterns, then, have value independent of that flaws and the accused language.&amp;nbsp; For instance, the Strategy pattern is covered not just in the &lt;A href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612" mce_href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612"&gt;Gang of Four&lt;/A&gt; (where it happens to have a C++ example), but also in the &lt;A href="http://www.amazon.com/Design-Patterns-Smalltalk-Companion/dp/0201184621" mce_href="http://www.amazon.com/Design-Patterns-Smalltalk-Companion/dp/0201184621"&gt;Design Patterns Smalltalk Companion&lt;/A&gt; which points out that it is used in Smalltalk in the MVC framework at the heart of Smalltalk's GUI.&amp;nbsp; The controller is a strategy pattern.&amp;nbsp; It is also used ImageRenderer and a few other examples.&lt;/P&gt;
&lt;P&gt;First class functions do not, by themselves, obviate the need for a strategy pattern.&amp;nbsp; This is more a nit than a real argument, but it remains true nonetheless.&amp;nbsp; To say a language has first class functions means merely that functions can be passed as data types.&amp;nbsp; It does not necessitate that the language implements &lt;A href="http://en.wikipedia.org/wiki/Closure_(computer_science)" mce_href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;closures&lt;/A&gt;.&amp;nbsp; Closures are a way of capturing the context of the function.&amp;nbsp; They can be used to retain state between calls to a particular function instance.&amp;nbsp; Without closures, there is no state.&amp;nbsp; Without state, many of the strategy pattern uses fail.&amp;nbsp; Consider for a moment using a strategy pattern to encapsulate encryption algorithms.&amp;nbsp; Without closures (or objects), you would have to pass the encryption key to the function every time it was used.&amp;nbsp; This is possible, but not terribly elegant.&lt;/P&gt;
&lt;P&gt;The existence of an alternate implementation does not make the original implementation any less useful.&amp;nbsp; The fact that I can get much of the power of OO out of first class functions and closures does not mean OO is now of no value.&amp;nbsp; There are advantages to both techniques.&amp;nbsp; Empirically there does appear to be power in OO that is not captured (easily) by purely functional languages.&amp;nbsp; Most successful functional (or psuedo-functional) languages have adopted OO features eventually.&amp;nbsp; See Python, Ruby, Common Lisp, Scala, etc.&amp;nbsp; All added or have object-oriented features.&amp;nbsp; Let us return to the&amp;nbsp;example of the strategy pattern.&amp;nbsp; Is its utility obviated by the use of first class functions plus closures?&amp;nbsp; In many cases it is.&amp;nbsp; Certainly it could be in the encryption example.&amp;nbsp; On the other hand, strategies are often more complex than mere functions can express.&amp;nbsp; The controller in MVC is a strategy.&amp;nbsp; In anything but a toy application, the controller will consist of multiple functions.&amp;nbsp; Sure, one could create these functions with the same closure and thus share state, but is that really a superior model?&amp;nbsp; I would argue that it is not.&amp;nbsp; In this case it would seem a less clear mechanism because the fact that the functions are tied together is less discoverable.&amp;nbsp; OO languages and functional languages each do things differently.&amp;nbsp; Things that are easy in one are more difficult in the other.&amp;nbsp; Neither is superior in all respects.&lt;/P&gt;
&lt;P&gt;It should be noted that when I say "design patterns" above I am referring to it in&amp;nbsp;the common sense of the object-oriented programming design patterns made popular by the Gang of Four book.&amp;nbsp; In a more general sense, each language has its own set of patterns and these can also be thought of as design patterns.&amp;nbsp; Some of the&amp;nbsp;OO patterns are specific to OO languages and the need doesn't translate to functional languages.&amp;nbsp; Others are more "in the large" and likely translate well to all languages trying to solve big problems.&amp;nbsp; It is my claim, however, that most of the GoF patterns will be useful in any OO language.&amp;nbsp; They are not artifacts of particular implementations such as C++ or Java.&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9925222" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Programming" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Programming/" /></entry><entry><title>Is there really a benefit in lossless audio formats?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/11/18/is-there-really-a-benefit-in-lossless-audio-formats.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/11/18/is-there-really-a-benefit-in-lossless-audio-formats.aspx</id><published>2009-11-19T07:14:55Z</published><updated>2009-11-19T07:14:55Z</updated><content type="html">&lt;p&gt;Lossless codecs are all the rage amongst those who aspire to be audiophiles.&amp;#160; Whether it is ripping CDs in a format like &lt;a href="http://flac.sourceforge.net/"&gt;FLAC&lt;/a&gt; or &lt;a href="http://www.microsoft.com/windows/windowsmedia/forpros/codecs/audio.aspx#WindowsMediaAudio9Lossless"&gt;WMA Lossless&lt;/a&gt; or listening the &lt;a href="http://www.dolby.com/consumer/understand/playback/dolby-truehd.html"&gt;TrueHD&lt;/a&gt; track on Bluray movies, there are those who swear by it.&amp;#160;&amp;#160; Most audio formats like MP3, AAC, and WMA are lossy formats.&amp;#160; They compress the audio by throwing away parts that humans theoretically cannot hear.&amp;#160; This is called “perceptual coding.”&amp;#160; Lossless codecs don’t throw away any information but instead compress more like Zip.&amp;#160; Lossless formats require a lot more space to store and a lot more bandwidth to transmit.&amp;#160; Are they worth it?&amp;#160; Can people really hear the difference?&lt;/p&gt;  &lt;p&gt;TrustedReviews says &lt;a href="http://www.trustedreviews.com/mp3/review/2009/11/18/Sounds-Good-To-Me/p1"&gt;no&lt;/a&gt;.&amp;#160; They go so far as to suggest than anything over 192kpbs MP3 is virtually impossible to differentiate.&amp;#160; “[A] few people in the last six months or so - people who take their audio gear seriously and have spent thousands of pounds on Hi-Fi equipment - have admitted privately to us that 256kbps MP3 is easily good enough for serious listening, and that they struggle to hear much difference over 192kbps MP3 in many situations.”&amp;#160; They conducted some A/B listening tests to see if ordinary people could perceive a difference.&amp;#160; The results did not support the extra expense and size of lossless formats.&amp;#160; In fact, most people couldn’t even differentiate between the 192kbps MP3s and a FLAC encoded version of the same songs.&amp;#160; The test wasn’t scientific, but there’s a pretty good chance it matches what those reading this blog will experience.&amp;#160; &lt;/p&gt;  &lt;p&gt;Considering that most people listen to their music in noisy environments, on suboptimal speakers, or on tiny headphones from an MP3 player like the Zune, the chances they will ever be able to perceive the differences in audio are quickly diminishing.&amp;#160; &lt;/p&gt;  &lt;p&gt;The short of it:&amp;#160; don’t waste the space ripping everything to lossless unless you plan to do a lot of transcoding in the future.&amp;#160; Don’t go out of your way to get a TrueHD movie setup.&amp;#160; AC3 is going to be just fine.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9925158" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Audio" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Audio/" /></entry><entry><title>A Review of a Kindle</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/11/13/a-review-of-a-kindle.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/11/13/a-review-of-a-kindle.aspx</id><published>2009-11-13T18:14:00Z</published><updated>2009-11-13T18:14:00Z</updated><content type="html">&lt;p&gt;Six months ago I purchased a &lt;a href="http://www.amazon.com/kindle"&gt;Kindle 2&lt;/a&gt;.&amp;#160; I originally bought the Kindle to make travelling easier.&amp;#160; I tend to carry a lot of books with me when I take a trip and those books get heavy.&amp;#160; With the Kindle, I could carry just this one device instead of 5 books.&amp;#160; The Kindle didn’t disappoint.&amp;#160; It weighs less than the typical paperback book.&amp;#160; It fits nicely in my Scottevest jacket.&amp;#160; I typically have about 80 books on mine at any given time giving me plenty of potential reading material.&amp;#160; If that isn’t enough, there is the Kindle store with some 360,000 books.&lt;/p&gt;  &lt;p&gt;The Kindle satisfied the purpose I bought it for, but has exceeded my expectations.&amp;#160; Not only do I use the Kindle when travelling, but it has become my preferred reading device.&amp;#160; The screen is a delight to read on.&amp;#160; The contrast may not be quite what it is on a real book, but it is plenty good.&amp;#160; The screen on the Kindle is much more comfortable to read on than the screen on a phone or a laptop.&amp;#160; There is no refresh rate and no backlighting.&amp;#160; This results in a significant reduction in eye fatigue.&amp;#160; I can read on the Kindle as easily and as long as I can read a paper book.&lt;/p&gt;  &lt;p&gt;In addition to being a great place to read, there are several features of the Kindle that make it my preferred reading tool.&amp;#160; The first is the built-in dictionary and the second is the ease of taking notes.&amp;#160; When reading a dead tree book, if I come across a word that I don’t know, I will usually guess at the meaning from the context and move along.&amp;#160; With the Kindle, I can just move the cursor over the word in question and get a definition at the bottom of the screen.&amp;#160; In this way I am able to understand the nuances of the text and expand my vocabulary.&amp;#160; The Kindle is also a great place to take notes.&amp;#160; Want to add a note?&amp;#160; Just start typing using the integrated keyboard.&amp;#160; Want to highlight some text?&amp;#160; Move the cursor to the start, press down, move to the end, press down again.&amp;#160; The notes and highlighted areas are collected in a text file that you can upload to your computer.&amp;#160; They are also available on &lt;a title="http://kindle.amazon.com/" href="http://kindle.amazon.com/"&gt;http://kindle.amazon.com/&lt;/a&gt;.&amp;#160; The notes will follow the book to other devices (like the new Windows software).&lt;/p&gt;  &lt;p&gt;So what isn’t to like?&amp;#160; The Kindle is an excellent book-reading platform.&amp;#160; It is a single-task device.&amp;#160; It is great at what it does and not good at anything else.&amp;#160; It has a built-in web browser, but it is the sort of thing you would only want to use in case of emergencies.&amp;#160; It does not render pages well, is difficult to navigate, and is very slow.&amp;#160; For instance, when composing an e-mail via either hotmail or gmail, it writes the letter, deletes it, then writes it again.&amp;#160; It is very easy to get well ahead of the cursor even on the limited keyboard.&lt;/p&gt;  &lt;p&gt;The Kindle supports MP3 playback, but not in any useful fashion.&amp;#160; You cannot see the songs.&amp;#160; You cannot select the songs.&amp;#160; You can skip to the next song, but that is all.&amp;#160; There is no shuffle.&amp;#160; Playback happens in the order the songs were put on the Kindle.&amp;#160; To say this feature is limited is an understatement.&lt;/p&gt;  &lt;p&gt;The Kindle only reads its own formats.&amp;#160; It can read variations of the mobipocket format but cannot read pdf, epub (the standard ebook format for everyone else), or even the encrypted mobipocket format found for free at many libraries.&amp;#160; This choice perplexes me.&lt;/p&gt;  &lt;p&gt;The note-taking is simple and works well, but it is capped.&amp;#160; If you highlight too much of a book, the highlights will continue, but the material will not end up in the notes file.&amp;#160; This wouldn’t be quite so bad if you were warned but you aren’t.&amp;#160; Instead you find out later when you go to the notes file and see a warning instead of the highlighted text.&lt;/p&gt;  &lt;p&gt;Perhaps the most disappointing part is the lack of software innovation going on.&amp;#160; As someone accustomed to the rate of innovation on other devices, it is disappointing to see no new firmware or features being pushed.&amp;#160; The hardware platform is stable, but why not improve the mp3 playback?&amp;#160; Why not add new formats?&amp;#160; Why not add support for tags or folders?&lt;/p&gt;  &lt;p&gt;A few questions and answers:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;How is the battery life?&lt;/em&gt;&amp;#160; It is amazing.&amp;#160; With the wireless left on, it will last several days.&amp;#160; With the wireless off (and there is no reason to leave it on), it will last weeks.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Is it economical?&lt;/em&gt;&amp;#160; No.&amp;#160; If you buy a Kindle, don’t buy it to save money on books.&amp;#160; Sure, they are a little cheaper than the hardcover, but maybe 10%.&amp;#160; At $259 for a Kindle 2, it is going to take a long time to make up the difference.&amp;#160; If you watch, there are many free books available which can help, but it is not a cheap device.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Are most books available?&amp;#160; &lt;/em&gt;That depends what sort of books you like to read.&amp;#160; I have found that a large percentage of what I read is available.&amp;#160; I still run into many books I want that are not available, but I’m not running out of books on it either.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;How about technical books?&amp;#160; &lt;/em&gt;Surprisingly, it is pretty good.&amp;#160; I have read a few programming books on it including Programming Clojure and Javascript:&amp;#160; The Good Parts.&amp;#160; It renders them just fine.&amp;#160; Where it falls down is in the random access.&amp;#160; I don’t recommend using it for reference material.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;How does it compare to the Nook?&lt;/em&gt;&amp;#160; I don’t know.&amp;#160; I haven’t used the Nook.&amp;#160; It appears to have superior hardware in most respects, but the book pricing is much worse.&amp;#160; If I were making the choice today, I would still choose the Kindle.&amp;#160; The Nook does appear to be giving it a run for its money though.&amp;#160; Strong competition is probably what the Kindle needed.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Do you recommend the Kindle?&lt;/em&gt;&amp;#160; Yes.&amp;#160; Highly.&amp;#160; If you like to read, get one.&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9921789" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Other" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Other/" /></entry><entry><title>StackOverflow DevDays</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/10/22/stackoverflow-devdays.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/10/22/stackoverflow-devdays.aspx</id><published>2009-10-22T07:38:00Z</published><updated>2009-10-22T07:38:00Z</updated><content type="html">&lt;P&gt;I spent the day at &lt;A href="http://www.seattlesymphony.org/benaroya/" mce_href="http://www.seattlesymphony.org/benaroya/"&gt;Benaroya Hall&lt;/A&gt; for the 1st (annual?) &lt;A href="http://stackoverflow.com/" mce_href="http://stackoverflow.com/"&gt;StackOverflow&lt;/A&gt; &lt;A href="http://stackoverflow.carsonified.com/" mce_href="http://stackoverflow.carsonified.com/"&gt;DevDays&lt;/A&gt; conference.&amp;nbsp; Overall eight speakers took the stage on topics from .Net MVC to Python to the Google App Engine.&amp;nbsp; The &lt;A href="http://www.seattlesymphony.org/benaroya/plan/venue/recital.aspx" mce_href="http://www.seattlesymphony.org/benaroya/plan/venue/recital.aspx"&gt;room&lt;/A&gt; appears to hold just over 500 people and it was filled to capacity with programmers.&amp;nbsp; There were some vendors in attendance including Amazon.com, Fog Creek Software, and someone showing off &lt;A href="http://www.hexbug.com/" mce_href="http://www.hexbug.com/"&gt;HexBugs&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The day started off with a short video titled &lt;EM&gt;Scrumms&lt;/EM&gt; which was a funny spoof on life at Fog Creek and the StackOverflow &lt;A href="http://blog.stackoverflow.com/category/podcasts/" mce_href="http://blog.stackoverflow.com/category/podcasts/"&gt;podcast&lt;/A&gt;.&amp;nbsp; It was quite entertaining.&amp;nbsp; I hope they release it on the web after the conferences complete in a few weeks.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://joelonsoftware.com/" mce_href="http://joelonsoftware.com/"&gt;Joel Spolsky&lt;/A&gt; was the first speaker.&amp;nbsp; I always enjoy reading and listening to him.&amp;nbsp; This speech was not a disappointment.&amp;nbsp; He was as entertaining as ever.&amp;nbsp; The subject matter under discussion was that of design elegance.&amp;nbsp; He began by pointing out that software often gives the user too much choice.&amp;nbsp; Often times it interrupts the user’s work flow to ask a question most users are unprepared to answer.&amp;nbsp; Other times there are options pages with myriad options which no one could know enough to actually use.&amp;nbsp; What is a “trusted user” on GMail anyway?&amp;nbsp; He cited a study where one store put out a lot of varieties of jam (24?) for people to try.&amp;nbsp; Many did, but substantially fewer actually purchased than when the same store put out only a half dozen varieties.&amp;nbsp; People are intimidated when given too much choice.&amp;nbsp; Joel recommended the book,&lt;EM&gt; &lt;/EM&gt;&lt;A href="http://www.amazon.com/gp/product/0060005696" mce_href="http://www.amazon.com/gp/product/0060005696"&gt;&lt;EM&gt;The Paradox of Choice&lt;/EM&gt;&lt;/A&gt;.&amp;nbsp; He then went on to talk about the simplicity offered by companies such as &lt;A href="http://37signals.com/" mce_href="http://37signals.com/"&gt;37 Signals&lt;/A&gt; whose products do only one thing, but do it well.&amp;nbsp; He argued that this isn’t the solution.&amp;nbsp; Customers will demand more features and to grow, a company must grow its feature set.&amp;nbsp; More sales leads to more features.&amp;nbsp; Choice must be offered then, but how to do it in a way that doesn’t alienate the customer?&amp;nbsp; The solution Joel offered up was to make sure the choices support what the user is doing.&amp;nbsp; The users should be modeled and choices aligned along the path of their behavior.&lt;/P&gt;
&lt;P&gt;Joel was followed by &lt;A href="http://www.hanselman.com/blog/" mce_href="http://www.hanselman.com/blog/"&gt;Scott Hanselman&lt;/A&gt; who gave an overview of the &lt;A href="http://www.asp.net/mvc/" mce_href="http://www.asp.net/mvc/"&gt;ASP.Net MVC&lt;/A&gt; framework.&amp;nbsp; This is a web framework built on top of the ASP.Net framework, but which exposes much more direct control to the programmer.&amp;nbsp; For instance, they now have direct control of their URL’s (yeah!).&amp;nbsp; Scott was an entertaining speaker although I think he was a bit too self-deprecating about Microsoft.&amp;nbsp; He spent most of the talk showing the audience various features in existing and upcoming Visual Studio products which make ASP.Net MVC programming easy.&lt;/P&gt;
&lt;P&gt;Next up was &lt;A href="http://www.rory.me/" mce_href="http://www.rory.me/"&gt;Rory Blyth&lt;/A&gt; talking about iPhone development.&amp;nbsp; He was an engaging speaker who obviously knows a lot about what he is doing.&amp;nbsp; I had never looked at iPhone or Objective C development before.&amp;nbsp; I can’t say I’m terribly impressed.&amp;nbsp; The tools like adequate, but aren’t as good as Visual Studio or even Eclipse.&amp;nbsp; Objective C looks like a mishmash of C and Smalltalk.&amp;nbsp; Rory described learning to develop for the iPhone as the Stockholm Syndrome where you eventually come to love your oppressor.&amp;nbsp; The iPhone is an attractive target to develop for from a business perspective (&lt;A href="http://gizmodo.com/5378390/the-app-store-effect-are-iphone-apps-headed-for-oblivion" mce_href="http://gizmodo.com/5378390/the-app-store-effect-are-iphone-apps-headed-for-oblivion"&gt;maybe&lt;/A&gt;), but the SDK doesn’t appear to be the reason people are flocking to it.&amp;nbsp; One highlight at the end was when Rory showed Novell’s &lt;A href="http://monotouch.net/" mce_href="http://monotouch.net/"&gt;MonoTouch&lt;/A&gt; which allows for C# development targeting the iPhone.&amp;nbsp; This looks like a slick environment even if it is a little pricey.&lt;/P&gt;
&lt;P&gt;Following Rory came Joel again with a sales pitch for FogBugs 7.&amp;nbsp; I have to say I was impressed with the empirical scheduling.&amp;nbsp; There is a new plugin called Kiln for code reviews which looks alright, but I think I prefer the UI from &lt;A href="http://www.codeplex.com/Malevich" mce_href="http://www.codeplex.com/Malevich"&gt;Malevich&lt;/A&gt; better.&amp;nbsp; For instance, the comments didn’t appear inline with the text when they were being made.&amp;nbsp; They did later when the submitter saw them though so perhaps I just missed something as Joel blazed through the UI.&amp;nbsp; If I were a startup, I would definitely consider using FogBugz to handle my planning and bug tracking needs.&lt;/P&gt;
&lt;P&gt;Lunch was catered by Wolfgang Puck and was reasonably good consider it was a conference and the whole thing only cost $99.&amp;nbsp; They divided up the tables into discussion topics (great idea!).&amp;nbsp; I went to a table about programming languages, but others included agile methods, startups, and a few I forgot.&lt;/P&gt;
&lt;P&gt;The first speaker after lunch was &lt;A href="http://codylindley.com/" mce_href="http://codylindley.com/"&gt;Cody Lindley&lt;/A&gt; from Ning who was talking about jQuery.&amp;nbsp; jQuery has been on my list of topics to learn about, but never made it to the top of said list.&amp;nbsp; It’s fascinating technology, especially considering I just read Crockford’s &lt;A href="http://oreilly.com/catalog/9780596517748/" mce_href="http://oreilly.com/catalog/9780596517748/"&gt;&lt;EM&gt;Javascript:&amp;nbsp; The Good Parts&lt;/EM&gt;&lt;/A&gt; recently and got a feel for the language as it was meant to be used.&amp;nbsp; For those that don’t know, jQuery is the most popular Javascript framework right now.&amp;nbsp; It runs on 35% of all Javascript pages on the web and 21% of all web pages of any kind.&amp;nbsp; It’s primary use is to make manipulating the DOM (the page structure) much easier.&amp;nbsp; Boiled down it lets a programmer easily select some portion of the page and apply an effect to it.&amp;nbsp; In implementation, it appears to be a Javascript function that wraps up a collection of page elements into a class which then provides methods for manipulating the set.&amp;nbsp; Cody used &lt;A href="http://jsbin.com/" mce_href="http://jsbin.com/"&gt;jsbin.com&lt;/A&gt; for his demo which appears to be an online javascript testing and debugging tool.&amp;nbsp; It looks very nice.&lt;/P&gt;
&lt;P&gt;Daniel Racha from Nokia was next up to talk about &lt;A href="http://qt.nokia.com/" mce_href="http://qt.nokia.com/"&gt;Qt&lt;/A&gt;&amp;nbsp;(pronounced "cute" not "Q-T").&amp;nbsp; This is a cross-platform UI toolkit and development platform recently purchased by Nokia.&amp;nbsp; It is also the basis of the K Desktop Environment (KDE) for Linux and is where Webkit originated.&amp;nbsp; Webkit is the rendering engine that powers Safari and Chrome.&amp;nbsp; Nokia’s plan is to use Qt as the basis for its phone app development story.&amp;nbsp; The technology and the tools are both mature and highly capable.&amp;nbsp; Daniel did a good job selling the merits of Nokia’s tool chain.&amp;nbsp; Considering the toolkit supports 6 platforms right now (Windows, Mac, Linux, plus several phone OS’s), I can see how this might be the way for cross-phone applications to be written.&amp;nbsp; Daniel also mentioned the Nokia N900 which apparently is completely open source to the point where end users could upload their own OS.&amp;nbsp; I can foresee 3rd party variants like those created for the Linksys routers.&amp;nbsp; This could be an interesting challenge to Apple’s iPhone strategy.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://twitter.com/twleung" mce_href="http://twitter.com/twleung"&gt;Ted Leung&lt;/A&gt; from Sun came to talk about Python.&amp;nbsp; This is another language I haven’t had time to learn yet.&amp;nbsp; His slides were terribly hard to read (purple on black—seriously?), but the content was good.&amp;nbsp; He gave a quick overview of the language basics and then talked about more advanced features like destructuring, generators (simple continuations), decorators, and extensions.&amp;nbsp; Python has definitely taken a lot from the world of functional programming.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.dansanderson.com/" mce_href="http://www.dansanderson.com/"&gt;Dan Sanderson&lt;/A&gt; was next up and gave an introduction to the Google App Engine.&amp;nbsp; It looks like an interesting way to build out scalable web sites.&amp;nbsp; This is the competitor to Amazon’s S3 and Microsoft’s Azure.&amp;nbsp; It supports the Python and Java virtual machines and so sites can be implemented in Python, Java, or any language that targets the JVM (Clojure, Scala, JRuby, etc.).&amp;nbsp; With that kind of support it would seem an app programmed to it would be capable of being moved, but that would not be the case.&amp;nbsp; The app engine is a very different sandbox to play in.&amp;nbsp; The database is non-relational and doesn’t support SQL (or at least fully SQL), the filesystem is different, there is no direct network access.&amp;nbsp; In short, once an app is written to the App Engine, it won’t easily run anywhere else.&amp;nbsp; The environment looks intriguing, but you are putting your company’s fate into Google’s hands.&lt;/P&gt;
&lt;P&gt;The day ended with &lt;A href="http://www.cs.washington.edu/homes/seitz/" mce_href="http://www.cs.washington.edu/homes/seitz/"&gt;Steve Seitz&lt;/A&gt; from the University of Washington talking about some of the advances in 3D image extrapolation.&amp;nbsp; Steve is behind much of the technology that became &lt;A href="http://photosynth.net/" mce_href="http://photosynth.net/"&gt;PhotoSynth&lt;/A&gt;.&amp;nbsp; Steve’s talk was light on programming content but high on “Wow!” factor.&amp;nbsp; This was a great way to end the day.&amp;nbsp; I’m not sure my mind could have taken another heavy talk.&amp;nbsp; The stuff Steve showed us was mind blowing.&amp;nbsp; They are able to take regular photographs, process them, and recreate the 3D scene.&amp;nbsp; Not only that, but newer technology allows for a walkthrough of the site and even &lt;A href="http://grail.cs.washington.edu/rome/dense.html" mce_href="http://grail.cs.washington.edu/rome/dense.html"&gt;full texturing&lt;/A&gt;.&amp;nbsp; You can see it &lt;A href="http://grail.cs.washington.edu/rome/" mce_href="http://grail.cs.washington.edu/rome/"&gt;here&lt;/A&gt;.&amp;nbsp; The best is this one:&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; PADDING-LEFT: 0px; WIDTH: 425px; PADDING-RIGHT: 0px; DISPLAY: block; FLOAT: none; MARGIN-LEFT: auto; MARGIN-RIGHT: auto; PADDING-TOP: 0px" id=scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:ede5f0a3-ab39-4c03-8dfe-db87b6aa14d1 class=wlWriterEditableSmartContent&gt;
&lt;DIV style="PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-TOP: 0px" id=30d78192-7c55-4985-a7ab-e8bfab8cd937&gt;
&lt;DIV&gt;&lt;A href="http://www.youtube.com/watch?v=sQegEro5Bfo&amp;amp;rel=0&amp;amp;color1=0xb1b1b1&amp;amp;color2=0xcfcfcf&amp;amp;hl=en&amp;amp;feature=player_embedded&amp;amp;fs=1" target=_new mce_href="http://www.youtube.com/watch?v=sQegEro5Bfo&amp;amp;rel=0&amp;amp;color1=0xb1b1b1&amp;amp;color2=0xcfcfcf&amp;amp;hl=en&amp;amp;feature=player_embedded&amp;amp;fs=1"&gt;&lt;IMG style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; BORDER-TOP-STYLE: none; BORDER-LEFT-STYLE: none" alt="" src="http://blogs.msdn.com/blogfiles/steverowe/WindowsLiveWriter/StackOverflowDevDays_14916/video5953daf864bf.jpg" onload="var downlevelDiv = document.getElementById('30d78192-7c55-4985-a7ab-e8bfab8cd937'); downlevelDiv.innerHTML = &amp;quot;&lt;div&gt;&lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&gt;&lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/sQegEro5Bfo&amp;amp;rel=0&amp;amp;color1=0xb1b1b1&amp;amp;color2=0xcfcfcf&amp;amp;hl=en&amp;amp;feature=player_embedded&amp;amp;fs=1&amp;amp;hl=en\&amp;quot;&gt;&lt;\/param&gt;&lt;embed src=\&amp;quot;http://www.youtube.com/v/sQegEro5Bfo&amp;amp;rel=0&amp;amp;color1=0xb1b1b1&amp;amp;color2=0xcfcfcf&amp;amp;hl=en&amp;amp;feature=player_embedded&amp;amp;fs=1&amp;amp;hl=en\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;355\&amp;quot;&gt;&lt;\/embed&gt;&lt;\/object&gt;&lt;\/div&gt;&amp;quot;;" galleryimg="no" mce_src="http://blogs.msdn.com/blogfiles/steverowe/WindowsLiveWriter/StackOverflowDevDays_14916/video5953daf864bf.jpg"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Overall the day was well spent.&amp;nbsp; I got to learn about a lot of cool new technologies and renew my excitement for programming.&amp;nbsp; Now I just have to pick one and find the time to learn it.&amp;nbsp; If the event takes place again next year, I definitely intend on going.&amp;nbsp; Thanks to Joel Spolsky and the folks at Carsonified for putting on such a great conference.&lt;/P&gt;
&lt;P&gt;For more, find other reviews on &lt;A href="http://meta.stackoverflow.com/questions/26873/devdays-reviews-seattle" mce_href="http://meta.stackoverflow.com/questions/26873/devdays-reviews-seattle"&gt;Meta.Stackoverflow&lt;/A&gt; or watch the &lt;A href="http://twitter.com/search?q=+%23devdays#search?q=%20%23devdays" mce_href="http://twitter.com/search?q=+%23devdays#search?q=%20%23devdays"&gt;Twitter stream&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;A title=http://www.seattlesymphony.org/benaroya/ href="http://www.seattlesymphony.org/benaroya/" mce_href="http://www.seattlesymphony.org/benaroya/"&gt;&lt;/A&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9911170" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Programming" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Programming/" /></entry><entry><title>Forging a Team Identity</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/09/30/forging-a-team-identity.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/09/30/forging-a-team-identity.aspx</id><published>2009-09-30T19:25:53Z</published><updated>2009-09-30T19:25:53Z</updated><content type="html">&lt;p&gt;For a group of coworkers to have a chance of becoming a team, they must share a common sense of purpose or identity.&amp;#160; Dave Logan in Tribal Leadership calls this a “Noble Cause.”&amp;#160; On small teams this often comes naturally.&amp;#160; Everyone is working on the same project or related set of features.&amp;#160; As teams become larger, their goals become more dissimilar and team identity becomes harder to forge.&amp;#160; It is up to the leader to forge this team identity.&lt;/p&gt;  &lt;p&gt;Having a unifying cause (whether noble or not) is important to get the most out of a team.&amp;#160; If people are all working toward a common goal, they will make the right compromises to do what is best for the team as a whole.&amp;#160; If there is no unifying cause, people will be working to optimize locally which is usually at odds with global optimization.&amp;#160; Each person will be trying their hardest, but if they are pulling is different directions, some of their effort will cancel out the effort of others.&amp;#160; Having a unifying cause does not guarantee that people work in concert, but it is certainly a prerequisite.&lt;/p&gt;  &lt;p&gt;How does one go about finding a unifying cause?&amp;#160; First look at the obvious candidates.&amp;#160; If the whole team is working on a particular product or feature area, just use that.&amp;#160; In my past I have unified teams around the concept of working on audio in Windows or on being the video team.&amp;#160; Sometimes there is no single feature to focus on.&amp;#160; In my last position I had 3 teams working for me.&amp;#160; Each had a distinct area to work on.&amp;#160; We were all part of the Windows organization, but we were such a small part that we couldn’t take that as our identity.&amp;#160; Each team even had its own identity, but as a group of leads, we didn’t.&amp;#160; What Joe was working on didn’t relate much to what Jane was working on.&amp;#160; I was convicted by &lt;a href="http://www.amazon.com/Tribal-Leadership-Leveraging-Thriving-Organization/dp/0061251305"&gt;Tribal Leadership&lt;/a&gt; and &lt;a href="http://www.amazon.com/Good-Great-Companies-Leap-Others/dp/0066620996"&gt;Good to Great&lt;/a&gt; that we needed a point of unification, but there wasn’t a product we has in common.&amp;#160; It was time to forge an identity rather than find one.&lt;/p&gt;  &lt;p&gt;The unifying principal I chose was becoming better managers together.&amp;#160; This is something we all had in common, being managers, and something we could help each other with.&amp;#160; Even if the technologies we were working on didn’t form a conceptual whole, our positions did.&amp;#160; Toward this end we made sure to have a lot of discussions about managing people.&amp;#160; We would discuss situations and how to handle them.&amp;#160; We started a weekly “book club” where we would read a chapter of a book each week and discuss it in our leads meeting (more on this in a future post).&amp;#160; It worked well.&amp;#160; The team began to gel work work together.&amp;#160; People began forming triad relationships rather than being dyadic.&amp;#160; That is, they started helping each other rather than merely reporting everything to me.&lt;/p&gt;  &lt;p&gt;It is important that a team, whether it be a team of ICs all working on the same feature or a group of leads reporting to a manager, have some common identity.&amp;#160; This in turns requires a goal or a unifying principal.&amp;#160; If there are no obvious candidates to be found, identity should be forged from something less obvious.&amp;#160; In the second case, it is easy to operate without a unifying goal, but things will run less smoothly.&amp;#160; Be &lt;a href="http://blogs.msdn.com/steverowe/archive/2009/07/01/be-intentional.aspx"&gt;intentional&lt;/a&gt; about ensuring each team has a common identity.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9901380" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Management" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Management/" /></entry><entry><title>Own the Feedback</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/08/04/own-the-feedback.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/08/04/own-the-feedback.aspx</id><published>2009-08-04T19:19:00Z</published><updated>2009-08-04T19:19:00Z</updated><content type="html">&lt;p&gt;Some time ago I was at a management training course. The group was divided into those who were managers of managers known in this course as M2s and those who were what I have been calling leads–that is managers of individual contributors–which they called M1s. I was part of the M2 group. The M1s were divided into groups of 10 or so and an M2 was assigned to each group as the Manager and another as merely an individual contributor. A couple of the M2s–myself included–formed the executive committee and were not involved in the working groups at all the first day. On the second day we changed things up and I wound up as an IC on a team. I knew I could not come into this group that didn't know me and act as the leader. It wasn't my role and it wouldn't be accepted. I tried really hard to play the supporting role. &lt;/p&gt;  &lt;p&gt;When I arrived, the group was in some trouble. They were in the middle of wordsmithing their mission statement (this on day 2!!). To make it worse, all 10 members were involved in this and it was becoming a marathon session. In an effort to help out, I made several suggestions and tried to ask questions to point them in the right direction. I didn't tell them how to act. They could freely take or leave my suggestions. At least, that is how I perceived it. &lt;/p&gt;  &lt;p&gt;At the end of the 2nd day there was a feedback session. Many of the members said something to the effect “I felt you were trying to take over the team.” My initial reaction was to challenge the validity of these statements. Not out loud of course, but internally. I had no intent in taking over. In fact I had been trying hard to avoid taking over. I carefully crafted my suggestions in such a way that they were not instructions, but just offerings of opinion that carried no weight of authority. If I had been actively avoiding taking over, these people must be in error in their judgement. &lt;/p&gt;  &lt;p&gt;When the M2s gathered I shared this experience with someone who had become a mentor to me. His sage advice was, “You have to own the feedback.” What he meant was that there had to be truth in there. Even if the feedback wasn't an accurate representation of reality–I was *not* trying to take over–it was an accurate representation of their perception of reality. Something about the situation and my actions had caused this perception. I could either accept that and look for the cause or I could reject that and learn nothing. &lt;/p&gt;  &lt;p&gt;I chose to accept the criticism and looked for the root cause of their perception. I was totally new to the situation. These people did not know me. Even though my suggestions were not intended as instructions, they were perceived that way because I was perceived as the new guy and new guys shouldn't act with authority so fast. In their minds I was the new hire and didn't understand the situation. I had built up no relationships, no human capital with them and thus had no implicity trust. I thus talked with more authority than someone in my position should have. It wasn't so much me but the position I held. I needed to act more in line with their expectations. I needed to build the relationship before giving advice. &lt;/p&gt;  &lt;p&gt;This analysis was born out later as people gave me the feedback that I had done less to try to take over as the session wore on. In reality, I had initially been rejecting their feedback and so hadn't changed. My actions were the same late on day 2 as they were early that day. The actions hadn't changed, but the perception had. I had built up some human capital and so my actions were being perceived differently. The specific takeaway is to know your perceived position and to act within it. Perception matters. It is important to build relationships before trying to affect change. &lt;/p&gt;  &lt;p&gt;The more general takeaway is to always own the feedback. When people say they perceive you in a particular way, that cannot be argued. The fact is, whether you intended it or not, you were perceived in that manner. The only two options are to accept the feedback and act on it or to ignore it and burn the relationship. The world is too small to go around cavalierly burning relationships. Owning the feedback means accepting that you did something to create the perception. It could be reality. It could have been that I really was trying to take over the group. Or it could be merely perceptual. I had acted in such a way so as to appear to want to take control even though I didn't. It is important to discern which of these is true because the solution is different in each case. &lt;/p&gt;  &lt;p&gt;This is advice I end up giving often at review time. Someone gets a tough message and wants to challenge it. “But I didn't do …” or “But that's not how it really happened.” These responses are not taking responsibility for the event. They are not examples of owning the feedback. The person proffering these responses will not fix the problem because they are externalizing blame for it. The true problem lies with someone else and so they have no responsibility or even ability to fix it. My response to this is consistent. The reality is that this is the perception. If they didn't do what they are accused of, then they did something to cause someone to think that they did. Whatever that was, they need to look for a way to address it. If not, they'll be getting the same review next year and at that point it will become a trend. &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9856792" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Management" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Management/" /></entry><entry><title>How to Interact with Your Team as a Manager</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/07/27/how-to-interact-with-your-team-as-a-manager.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/07/27/how-to-interact-with-your-team-as-a-manager.aspx</id><published>2009-07-27T17:49:09Z</published><updated>2009-07-27T17:49:09Z</updated><content type="html">&lt;p&gt;As one moves from being a lead (manager whose reports are individual contributors) to a manager (manager whose reports are leads), there is an important decision to be made about how to interact with your skip-level reports. That is, how should a manager handle his interactions with the individual contributors reporting to his leads. There are two ends of this spectrum and managers often gravitate to one end or the other. The first option is to bypass the leads and go directly to those on the front lines. The second is to route most interactions through the leads. Both have their advantages and disadvantages. Where to position yourself between these two ends of the spectrum is not an easy decision to make. &lt;/p&gt;  &lt;p&gt;If a manager decides to bypass her reports and go directly to the individual contributors (ICs), she has direct knowledge of how things are progressing. She develops a direct relationship with the ICs. Things are more likely to be done the way she wants. However, there are some significant downsides to this behavior as well. &lt;/p&gt;  &lt;p&gt;First, it is hard to scale to this level. The fact that the organization chose to have leads should indicate that the work is too big for one person to manage. If the manager can handle all of the ICs directly, the lead position is extraneous and harmful. The reality is that this manager is unlikely to have enough time to closely monitor the work all of the time. Her interaction with the team will then tend toward drive-by management. She will swoop in and give direction on a particular part of a project but then lose focus before the results of the direction become evident. This can lead to poor decisions being implemented and frustration among the individuals carrying out the instructions. &lt;/p&gt;  &lt;p&gt;Second, it can lead to discontent among the leads. They will have particular ways they want work done and a priority order for what they want done. Having their manager go directly to their reports means these instructions will be contradicted. This causes confusion among the ICs who will have conflicting priorities and goals. The lead will also feel his role being undermined by his manager. When she goes to his reports and gives them instructions, he is out of the loop and will begin to feel unnecessary or even frustrated. This can cause the lead to stop performing the duties of a lead and allowing the manager to do that work. As the manager is unable to give the same amount of attention, this often leads to a situation where no one is paying attention. &lt;/p&gt;  &lt;p&gt;What about the alternative? Routing work through the leads. When a manager wants her team to do something, rather than going to Fred the IC with instructions, she asks the lead to ask Fred to do the work. This allows for the lead to always be in the loop. It allows the lead to ensure that there is a clear message (see blog past on providing clarity) so that the IC only has one set of priorities. It also allows the manager to scale. Rather than having to check in on Fred's progress, she can just ask her lead in their 1:1 how things are going. The details of the work can be left to the lead and the manager need only bother with the end goals. This may sound good, but there are downsides as well. &lt;/p&gt;  &lt;p&gt;First, going through another person in communication always risks the message getting distorted. As anyone who played telephone in elementary school can attest, the more people that retransmit a message, the more it will change. In the elementary school game children are asked to sit in a line. The first child is given a message and asked to tell the next child in line. Each child in turn is to repeat what they heard to the next child. The final child will announce to the group the message he received. With rare exception, the final message is not even related to the initial one. &lt;/p&gt;  &lt;p&gt;Second, going through another person can limit the amount of feedback received. If Jane the manager tells her lead Marcus to have his team make the iWidget program interface with the new build process, there is some chance that Jane will not learn that this is more difficult than initially conceived. If Marcus does his job poorly, he may not relay the message to Jane. This leads to frustration on all fronts. Jane is upset because the project is taking too long. Fred the IC is upset because he is being asked to do the impossible. Marcus may even be frustrated because both his manager and his report are frustrated. &lt;/p&gt;  &lt;p&gt;The third and perhaps most insidious downside of this management approach is the lack of relationship that gets built. People will subconsciously distrust those who they do not have a relationship with. Their natural tendency is to distrust until they have reason to trust. The reason doesn't have to be large. It could just be seeing that the manager treats others fairly or having casual conversations which convey the sense that the manager is a “real person.” The result of this psychological phenomenon is that until a manager has built up social capital via relationships, she will not get the benefit of the doubt from her team. Subtly, the team will interpret ambiguous actions in a negative light. Asking for a code review will not be seen as a way to strengthen the team's coding skills but rather as a way to check up on people and “get them” if they aren't doing well enough. Mail sent asking about the status of a bug will be viewed as accusatory rather than merely inquisitive. The most insidious part is that the manager will probably never realize this is happening because she doesn't have the relationships that would provide the necessary feedback channel. &lt;/p&gt;  &lt;p&gt;In the past year I made the transition to manager and faced this exact quandary. My decision was to route most interaction through my reports. When I needed work done, I would ask the manager to have the work done instead of going directly to the report. I knew the downsides of not letting leads do their job and wasn't going to make that mistake. Instead, I made the mistake of being too distant. I built up relationships with my direct reports, but not as much with the teams reporting to them. Based on this experience, I will be trying a more mixed approach in the future. &lt;/p&gt;  &lt;p&gt;I still believe it is important not to bypass the leads when giving work instructions.&amp;#160; Yes, this has the telephone problem, but the consequences of avoiding that are too great.&amp;#160; At the same time, it is important to build a relationship with the individual contributors.&amp;#160; This means ensuring direct contact.&amp;#160; At the lower edge contact should be made at the individual level by wandering the halls and by skip-level 1:1s.&amp;#160; At the higher edge, contact should be made by sending out broad mails laying out high-level vision, by all-team meetings even if there is no business demand for them, and by occasionally attending your team leads' meetings.&amp;#160; The middle (direct business communication) should be left to the leads.&amp;#160; In initiating contact at the individual level for personal contact and at the vision level for business, you should generate enough “human capital” that the team will come to trust you and give you the benefit of the doubt.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9850049" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Management" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Management/" /></entry><entry><title>Be Intentional</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/07/01/be-intentional.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/07/01/be-intentional.aspx</id><published>2009-07-01T20:33:50Z</published><updated>2009-07-01T20:33:50Z</updated><content type="html">&lt;p&gt;My old manager used to always say, “Be intentional.”&amp;#160; It took me a long time to comprehend exactly what he meant by this, but eventually I did and have come to appreciate the advice.&amp;#160; What he meant was to always make active, conscious decisions rather than just letting things happen.&amp;#160; It also means to verify things rather than assuming they are a certain way.&amp;#160; For example, if you don’t have enough time to do everything on your plate, think carefully about which items will not get done rather than just working on items in no particular order.&amp;#160; It should be your intent which specific items go undone.&lt;/p&gt;  &lt;p&gt;This is a good principle to act by.&amp;#160; All too often people think about what they *are* doing but don’t consider what they *are not* doing.&amp;#160; It is just as important to be conscious about what you are not doing as it is to be aware of what you are.&amp;#160; If you don’t actively choose that which is not done, it is likely that the wrong things will drop off your plate.&amp;#160; It is easy to be busy working on something that is important to the detriment of something that is really important.&amp;#160; It is best to make all decisions, both positive and negative, conscious ones.&amp;#160; I’ll often ask my team when something goes undone whether that was intentional or not.&amp;#160; If there is only time to do 3 items and there are 4 that should be done, I’m fine with the 4th being dropped.&amp;#160; It is a poor manager who is upset when the impossible isn’t accomplished.&amp;#160; I do, however, hold my team accountable for that 4th item being something they intend to not get done rather than whatever just happened to be left at the end of the day.&lt;/p&gt;  &lt;p&gt;I’ve seen this come up in testing features.&amp;#160; I recall a time when a report of mine was testing a particular feature with two aspects to it.&amp;#160; For good reasons he started working on the first part, a complex parser for device attributes.&amp;#160; Being complex, this took a long time to thoroughly test.&amp;#160; In fact, it was taking long enough that he was not going to be able to get to the second aspect of the feature at all.&amp;#160; I inquired whether this was really the right approach.&amp;#160; Did he think it was better to thoroughly test the parser and test the other part none or would it be better to test the parser to some level, then test the other aspect, and finally return (in the future) to cover the less important parts of the parser.&amp;#160; Upon reflection he decided it was a better idea to cover both to some extent than one fully and the other none.&amp;#160; The trouble here is that he wasn’t acting intentionally.&amp;#160; The test plan called for testing both aspects thoroughly.&amp;#160; The plan didn’t call for ignoring the second part.&amp;#160; It was just because of the unexpected difficulty of testing the parser that the second was going to be missed.&amp;#160; He needed to step back, re-evaluate, and decide intentionally rather than just letting events dictate what was going to be dropped.&lt;/p&gt;  &lt;p&gt;This principle is also good to apply when dealing with other people.&amp;#160; Instead of just assuming that the other party will do the right thing, being intentional means specifically outlining expectations of them.&amp;#160; It is easy to think you’ve told someone what to do without them realizing that you did.&amp;#160; Being intentional means verifying that your assumptions were communicated and following up later.&amp;#160; It means being explicit when handing work to another person.&amp;#160; Make sure they understand that it is your expectation that they now have the action item before you clear it from your to-do list.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9811509" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Other" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Other/" /></entry><entry><title>Five Books To Read If You Want My Job</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/05/27/five-books-to-read-if-you-want-my-job.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/05/27/five-books-to-read-if-you-want-my-job.aspx</id><published>2009-05-28T03:03:52Z</published><updated>2009-05-28T03:03:52Z</updated><content type="html">&lt;p&gt;This came out of a conversation I had today with a few other test leads.&amp;#160; the question was, “What are the top 5 books you should read if you want my job?”&amp;#160; My job in this case being that of a test development lead.&amp;#160; At Microsoft that means I lead a team (or teams) of people whose job it is to write software which automatically tests the product.&amp;#160; &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.amazon.com/Behind-Closed-Doors-Management-Programmers/dp/0976694026"&gt;Behind Closed Doors&lt;/a&gt; by Johanna Rothman – One of the best books on practical management that I’ve run across.&amp;#160; 1:1’s, managing by walking around, etc.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/Practice-Programming-Addison-Wesley-Professional-Computing/dp/020161586X"&gt;The Practice of Programming&lt;/a&gt; by Kernighan and Pike– Similar to &lt;a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670"&gt;Code Complete&lt;/a&gt; but a lot more succinct.&amp;#160; How to be a good developer.&amp;#160; Even if you don’t develop, you have to help your team do so.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612"&gt;Design Patterns&lt;/a&gt; by Gamma et al – Understand how to construct well factored software.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/How-Break-Software-Practical-Testing/dp/0201796198"&gt;How to Break Software&lt;/a&gt; by James Whittaker – The best practical guide to software testing.&amp;#160; No egg headed notions here.&amp;#160; Only ideas that work.&amp;#160; I’ve heard that &lt;a href="http://www.amazon.com/How-We-Test-Software-Microsoft/dp/0735624259"&gt;How We Test Software at Microsoft&lt;/a&gt; is a good alternative but I haven’t read it yet.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/Smart-Gets-Things-Done-Technical/dp/1590598385"&gt;Smart, and Gets Things Done&lt;/a&gt; by Joel Spolsky – How great developers think and how to recruit them.&amp;#160; Get and retain a great team.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This is not an exhaustive list.&amp;#160; There is a lot more to learn than what is represented in these books, but these will touch on the essentials.&amp;#160; If you have additional suggestions, please leave them in the comments.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9645166" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Testing" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Testing/" /><category term="Programming" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Programming/" /><category term="Management" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Management/" /><category term="Books" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Books/" /><category term="Software Process" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Software+Process/" /></entry><entry><title>Some Programming Languages to Consider Learning</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/05/12/some-programming-languages-to-consider-learning.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/05/12/some-programming-languages-to-consider-learning.aspx</id><published>2009-05-12T18:21:00Z</published><updated>2009-05-12T18:21:00Z</updated><content type="html">&lt;P&gt;Learning a new programming language can affect the way you think.&amp;nbsp; While most modern languages are &lt;A href="http://en.wikipedia.org/wiki/Turing-complete" mce_href="http://en.wikipedia.org/wiki/Turing-complete"&gt;Turing Complete&lt;/A&gt; and can theoretically all accomplish the same things, that’s not practically true.&amp;nbsp; Each language has its own strengths of expressiveness.&amp;nbsp; For instance, trying to write dynamically typed code in C++ is possible, but a pain in the neck.&amp;nbsp; You would have to implement your own type system to do so.&amp;nbsp; Each language makes certain things easy and other things hard.&amp;nbsp; Learning different languages then exposes you to different approaches.&amp;nbsp; Each approach provides a different way of thinking and a set of tools supporting that way of thinking.&amp;nbsp; What follows are some of the languages I’ve learned and what I think they provide.&amp;nbsp; This list is limited to languages I’ve studied in at least a little depth.&amp;nbsp; There are many more languages out there that may be useful.&amp;nbsp; If you have additional suggestions, please make them in the comments.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://cm.bell-labs.com/cm/cs/cbook/" mce_href="http://cm.bell-labs.com/cm/cs/cbook/"&gt;C&lt;/A&gt; – This is coding very close to the metal.&amp;nbsp; Learning it promotes an understanding of memory, pointers, etc.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://www.sbcl.org/" mce_href="http://www.sbcl.org/"&gt;Lisp&lt;/A&gt;/&lt;A href="http://www.plt-scheme.org/" mce_href="http://www.plt-scheme.org/"&gt;Scheme&lt;/A&gt; – Once you get past your parenthesis-phobia, it’s a very elegant language.&amp;nbsp; The big learnings here are treating code as data, &lt;A href="http://en.wikipedia.org/wiki/Metaprogramming" mce_href="http://en.wikipedia.org/wiki/Metaprogramming"&gt;metaprogramming&lt;/A&gt; (writing programs that themselves write programs), and recursion.&amp;nbsp; Lisp is also a dynamically-typed language.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://clojure.org/" mce_href="http://clojure.org/"&gt;Clojure&lt;/A&gt; – A variant of Lisp that runs on the JVM.&amp;nbsp; In addition to what you can learn from Lisp, it adds &lt;A href="http://en.wikipedia.org/wiki/Persistent_data_structure" mce_href="http://en.wikipedia.org/wiki/Persistent_data_structure"&gt;persistent data structures&lt;/A&gt; and &lt;A href="http://en.wikipedia.org/wiki/Software_transactional_memory" mce_href="http://en.wikipedia.org/wiki/Software_transactional_memory"&gt;transactional memory&lt;/A&gt;.&amp;nbsp; Persistent data structures are ones that *never* change.&amp;nbsp; Once you have a “pointer” to one, it will never change underneath you.&amp;nbsp; This makes parallel programming much simpler.&amp;nbsp; Clojure also is more of a functional language than Lisp/Scheme.&amp;nbsp; It is not purely functional, but allows for the functional style to be followed more easily.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://www.squeak.org/" mce_href="http://www.squeak.org/"&gt;Smalltalk&lt;/A&gt; – Much of modern programming originated in this language.&amp;nbsp; Modern GUIs are based on the Xerox Parc Smalltalk systems.&amp;nbsp; Object Oriented programming was first popularized in Smalltalk.&amp;nbsp; Extreme Programming, Agile, and Design patterns all found their initial formulations in Smalltalk.&amp;nbsp; In addition to learning about OO programming, Smalltalk is great to understand &lt;A href="http://www.smalltalk-resources.com/Smalltalk-Getting-the-Message.html" mce_href="http://www.smalltalk-resources.com/Smalltalk-Getting-the-Message.html"&gt;message passing&lt;/A&gt;.&amp;nbsp; This gives object-oriented code a different feel than the function call semantics of C++/Java/C#.&amp;nbsp; Smalltalk is also a dynamic language.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://www.perl.com/" mce_href="http://www.perl.com/"&gt;Perl&lt;/A&gt; – Perl was once known as the duct tape of the internet.&amp;nbsp; It ran everything.&amp;nbsp; It has since been surpassed (at least in blogosphere popularity) by other scripting languages like Ruby and Python.&amp;nbsp; The biggest thing to learn from Perl is regular expressions.&amp;nbsp; They are built into the core of the language.&amp;nbsp; Other languages support them but often as a library.&amp;nbsp; Even those that do support them in the syntax do not usually utilize them so pervasively.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx" mce_href="http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx"&gt;C#&lt;/A&gt;/&lt;A href="http://java.sun.com/" mce_href="http://java.sun.com/"&gt;Java&lt;/A&gt; – These languages both solve the same problems in almost the same ways.&amp;nbsp; They are a great place to learn object-oriented programming.&amp;nbsp; It is built in from the ground up.&amp;nbsp; The OO style is one of function calls and strong interfaces (which distinguishes it from Smalltalk).&amp;nbsp; These languages also have the largest accompanying libraries.&lt;/LI&gt;&lt;/UL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9605228" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Programming" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Programming/" /><category term="Learning to Code" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Learning+to+Code/" /></entry><entry><title>Inbox Zero, Take Two</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/b/steverowe/archive/2009/04/30/inbox-zero-take-two.aspx" /><id>http://blogs.msdn.com/b/steverowe/archive/2009/04/30/inbox-zero-take-two.aspx</id><published>2009-04-30T20:04:41Z</published><updated>2009-04-30T20:04:41Z</updated><content type="html">&lt;p&gt;A year and a half ago I tried to get to “&lt;a href="http://blogs.msdn.com/steverowe/archive/2007/11/29/inbox-zero.aspx"&gt;Inbox Zero&lt;/a&gt;” and failed.&amp;#160; This is the idea that you get your inbox down to zero mails every day.&amp;#160; I’m making another run at it and this time have been a little more successful.&amp;#160; I’m not perfect, but I haven’t fallen off the horse yet either.&amp;#160; Here’s what I have found to work.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Let all interesting mail fall directly into the inbox.&amp;#160; Don’t use separate folders for stuff from your boss or an alias/list that is important.&lt;/li&gt;    &lt;li&gt;Move non-interesting mail into a separate folder by a rule.&amp;#160; I have rules to shunt off aliases I find merely interesting but not important into their own folders automatically.&lt;/li&gt;    &lt;li&gt;Read or skim every mail that is in your inbox.&amp;#160; For each, make one of the following decisions:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Respond.&amp;#160; Read it and take the appropriate action.&amp;#160; If you can do this in a minute or two, just do it.&lt;/li&gt;      &lt;li&gt;Delete it.&amp;#160; You have the information or it wasn’t interesting.&amp;#160; Either way, you don’t need to keep it around.&lt;/li&gt;      &lt;li&gt;Archive it.&amp;#160; You may need to refer back to it later, but you don’t need to take any action on it.&lt;/li&gt;      &lt;li&gt;Mark it for further reading.&amp;#160; It’s not critical to act on it, but too long to read now.&amp;#160; Put it in a folder to read later.&lt;/li&gt;      &lt;li&gt;Mark it for further action.&amp;#160; It will take longer than you have to respond, but a response is necessary.&amp;#160; Put it in a folder for later response.&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;Following these rules makes my inbox look something like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Inbox&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Action Required&lt;/li&gt;      &lt;li&gt;Archive&lt;/li&gt;      &lt;li&gt;Read Later&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Interests&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Various subfolders for the non-critical aliases I am part of.&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;I also have a rule to move all mail sent to: or cc: me directly to my inbox.&amp;#160; This way mail intended for my eyes won’t get filtered into an “interests” folder.&lt;/p&gt;  &lt;p&gt;I have found this system simple enough to keep up with it.&amp;#160; It also means I no longer miss mails which got filtered into some folder I haven’t yet read for today.&amp;#160; I now see every interesting mail and am at least aware of it.&amp;#160; It also helps me keep track of the mails I really need to go back and respond to.&amp;#160; My old system was just to leave them unread, but this got unwieldy very quickly and I never made it back to most of them.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9580777" width="1" height="1"&gt;</content><author><name>SteveRowe</name><uri>http://blogs.msdn.com/SteveRowe/ProfileUrlRedirect.ashx</uri></author><category term="Other" scheme="http://blogs.msdn.com/b/steverowe/archive/tags/Other/" /></entry></feed>
