<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Antipatter &#187; programming</title>
	<atom:link href="http://antipatter.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://antipatter.com</link>
	<description>The Web, The Business, The Smoke and Mirrors</description>
	<lastBuildDate>Tue, 15 Nov 2011 15:34:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Fixing Personalization: A Conversational Architecture Approach</title>
		<link>http://antipatter.com/2011/05/fixing-personalization/</link>
		<comments>http://antipatter.com/2011/05/fixing-personalization/#comments</comments>
		<pubDate>Mon, 16 May 2011 11:00:12 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[conversational architecture]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tech strategy]]></category>
		<category><![CDATA[conarch]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[personalization]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=418</guid>
		<description><![CDATA[
Once upon a time there was personalization.  Of course no one called it that.  It was just that when you walked into the general store in your one-horse town, the guy behind the counter already knew who you were.  &#8221;Hi &#60;your-name&#62;, how are you doing?  How are those &#60;things-I-sold-you-last-week&#62; working out for you?&#8221;.  You were [...]
]]></description>
			<content:encoded><![CDATA[<p>Once upon a time there was personalization.  Of course no one called it that.  It was just that when you walked into the general store in your one-horse town, the guy behind the counter already knew who you were.  &#8221;Hi &lt;your-name&gt;, how are you doing?  How are those &lt;things-I-sold-you-last-week&gt; working out for you?&#8221;.  You were experiencing personalized service, just like the other 30 people in your little hamlet.</p>
<p>Come the industrial revolution however, there was suddenly an issue of <em>scale</em> introduced into the equation.  Suddenly instead of a handful of customers, an enterprise might have hundreds, thousands or, in the modern world, millions and billions.  One of the first and most fundamental actions of the industrial revolution was to cut personalization out at its heart.  That&#8217;s because personalization didn&#8217;t scale.  The factory needed to get thousands of units manufactured on their assembly lines, and couldn&#8217;t stop to deal with pesky user requests like &#8220;colors-other-than-black&#8221; on their Model Ts.</p>
<p>Then cometh the Internet.  With its oh-so-seductive lack of physicality and supposed promise of infinite supply (and the associated supposed-zero-incremental-customization cost) there was suddenly a burst of activity around creating customized experiences for individuals on the web.  Personalization was back.  All sales leads would convert and prosper.</p>
<p>Wait a second, though.  Go look for some books on personalization.  You might notice something interesting, as I did when I went looking.  Nothing has really been published about personalization since about 2002 or so.  That&#8217;s kind of funny.  Wonder why that is?  Almost like&#8230;something went wrong&#8230;</p>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/scale-balencing.png"><img class="size-full wp-image-429 alignleft" title="scale balancing" src="http://antipatter.com/wp-content/uploads/2011/05/scale-balencing.png" alt="" width="272" height="286" /></a></p>
<h2>Black Boxes</h2>
<p>New technology always debuts as a black box that promises to solve all of our problems.  Generally speaking, the people signing the checks don&#8217;t care to understand how it works, only that it&#8217;s going to bequeath competitive advantage on them (in the case of early adopters) or because all of their peers are signing on to it (in the case of the majority).  Also, sadly, the role of technology has been treated in a very arms-length manner within much of the business world.  That&#8217;s too bad, because it has some of the greatest impact on business.</p>
<p>In the case of personalization, engagements typically went like this: you fed all of your data into it (products, articles etc) and let it perform some sort of proprietary analysis on that data.  Then you dropped some recommendation widgets onto your site, clicked your heels together three times, and suddenly you were looking at theoretically relevant content and/or personalized product recommendations.</p>
<p>Over time, however there have been concerns by people who have deployed such systems.  In a nutshell those concerns are:</p>
<ul>
<li>How do we know our recommendations are working?</li>
<li>How do make sure the black box personalization system doesn&#8217;t do something weird or inappropriate?</li>
<li>How can we use personalization to distinguish ourselves from our competition?</li>
</ul>
<p>In the world of black box personalization, there haven&#8217;t really been good answers to these questions, because you&#8217;re dealing with a <em>black box</em>.  You don&#8217;t know how the system is really working, there aren&#8217;t any controls or visible workings that you can have mastery over and it&#8217;s difficult to gain insight on how things work, and how your business strategy could be incorporated into the personalization system&#8217;s execution.</p>
<p>I believe these combined factors took a lot of the sheen off of the face of personalization.  Business operators, unable to really get any idea about how these systems worked, decided they weren&#8217;t that happy about delegating such a fundamental aspect of their marketing to an automated system that provided no means of understanding its workings.  From there the only practical choice was to go back to manual curation.  And that, as we know, doesn&#8217;t scale.</p>
<p>This problem is, I believe, at the heart of why I&#8217;ve had trouble finding any writing about personalization that has been published within the last 5 years.  I have a hard time believing that the technology behind personalization has come to a halt, but the business application of it seems to have hit a brick wall.</p>
<h2>Splitting the Dilemna</h2>
<p>So faced between a choice between the scaling problems of manual curation, and the unpredictability and the unknown factor that comes with black box personalization, business hasn&#8217;t been left with a great choice.  Generally speaking, it seems like businesses have mostly come down on the side of manual curation, and have put personalization into a ghetto on their website (a recommendations sidebar or such).  Again, that&#8217;s too bad, because there&#8217;s so much being left on the table that personalization could address, but without more control and insight into the process, business are unable to trust it.</p>
<p>What would be nice is a mechanism for businesses to be able to define the principles, or rules, under which they want to extend personalized service, and then from those rules deploy automation to execute that service.  A kind of  &#8221;white box&#8221; personalization, if you will.  This is where <a title="Conversational Architecture" href="http://antipatter.com/2011/04/conversational-architecture/">Conversational Architecture</a> comes in.</p>
<p>I propose that we treat personalization a little differently than we have in the past.  Using Conversational Architectural terms, business can define how their personalization system should respond to particular cases that are important to the business, in the way the business prefers.  Because the business is essentially defining <em>rules</em>, however, and not individual cases, the system can scale through automation.</p>
<h2>Tuning the Content Mix</h2>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/content-mix.png"><img class="alignright size-full wp-image-433" title="content mix" src="http://antipatter.com/wp-content/uploads/2011/05/content-mix.png" alt="" width="180" height="180" /></a>Conversational Architecture thinks of product recommendations, or related or personalized content, as all part of the same problem.  We call these &#8220;<em><strong>content policy</strong></em>&#8221; objects, and treat them as components that can be included in various contexts.  A content policy object is a placeholder for a set of business rules that describes how a component should be populated with content (content meaning articles, products, profiles or whatever).  The point, however, is that the <em><strong>mix of content</strong></em> within these policy objects can be tuned by the website operator.</p>
<p>Here&#8217;s what kind of content you can get in a content policy object:</p>
<ul>
<li><strong>Personalized</strong>:  Based on the user&#8217;s expressed affinities, personalized content tends to be related (via metadata) to content that the user has endorsed in some way.  For example, if we&#8217;re talking about products, then personalized products would be related, (via metadata, tagging or collaborative filtering style aggregation), to products in which the user has expressed an interest in some way, such as by buying them, adding them to a wishlist or so forth.</li>
<li><strong>Related</strong>:  Related content is similar to personalized content, but instead of user affinities, the starting point is something on the page that serves as a base content.  In the case of e-commerce, the starting point could be the product featured on a product page, or perhaps a particular metadata or tag value represented by a product category page.</li>
<li><strong>Curated</strong>:  Sometimes you just want some specific content to show up in a particular place.  This is curation, meaning the individual content objects are specified directly.</li>
<li><strong>Random</strong>: With all this content targeting, it&#8217;s occasionally nice to dial in a little bit of noise.  Random content could be anything, and allows the policy editor to back off a little from complete content targeting, allowing for the possibility of serendipitous discovery by users.  You never know.</li>
</ul>
<h2>How Content is Related</h2>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/vector-of-relevancy.png"><img class="alignnone size-full wp-image-435" title="vector of relevancy" src="http://antipatter.com/wp-content/uploads/2011/05/vector-of-relevancy.png" alt="" width="492" height="120" /></a></p>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/vector-of-relevancy.png"></a>Another important idea with regards to personalized and related content is the idea of <strong><em>vectors of relevancy</em></strong>.   This has to do with the specific metadata that is used to relate content to each other, and the relative importance of similar values within that metadata.  Not all characteristics of content are equally important when tuning a content policy.</p>
<p>For example when we built Whiskey Engine (whiskey-engine.com), we consulted with an expert who explained to us the elements of the taste of whiskey.  He broke the taste of whiskey into elements like &#8220;herbs/spice&#8221;, &#8220;flowers&#8221; and &#8220;smoothness&#8221;.  Based on his tastings, we accumulated data about the taste profiles of each whiskey in his collection, with a value between 1 and 5 (1 meaning the least, 5 the most) for each taste characteristic.</p>
<p>However when we spoke with him further, it turned out that people tended to place a premium on the &#8220;smoothness&#8221; factor above all else.  In other words, once people decide how smooth they like their whiskey, they tend to follow that vector when looking for new whiskies.  People place far less concern on other whiskey taste values such as &#8220;herbs/spice&#8221;.</p>
<p>For a different example, think about music: if you like the artist who recorded one track, there are reasonably good odds that you&#8217;ll like another track by the same artist.  On the other hand, the record company that release the recording is much less significant.  People usually don&#8217;t care (and don&#8217;t know) which record company released a particular recording.</p>
<p>Buy carefully defining the metadata for content as well as specifying its importance as a vector of relevancy, recommendations and related content can be improved within policy objects.</p>
<h2>Gaining Confidence: Measuring Content Policy Performance</h2>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/Confidence.png"><img class="alignnone size-full wp-image-437" title="Confidence" src="http://antipatter.com/wp-content/uploads/2011/05/Confidence.png" alt="" width="466" height="111" /></a></p>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/Confidence.png"></a>So how can you know if your personalization strategy is working?  By treating the content policy object as the head end of a conversion funnel, and measuring how well it performs (we call this &#8220;<em><strong>Confidence</strong></em>&#8220;).  At its simplest, you should simply be able to see how well each content policy object is performing.  If you&#8217;re not satisfied with the results, then go tweak your content policy mix, or try altering the relevancy vectors of the content metadata to increase the quality of the personalized and related content in the policy.  Specific personalization deployments should never be treated as &#8220;set and forget&#8221;.  You need to work on them, adapting them to your specific audience.</p>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/conductivity1.png"><img class="alignnone size-full wp-image-441" title="conductivity" src="http://antipatter.com/wp-content/uploads/2011/05/conductivity1.png" alt="" width="466" height="323" /></a></p>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/conductivity1.png"></a>Of course the ultimate version of responding to confidence measurements would be for the content policy object to reconfigure dynamically based on performance.  Conversational architecture has a name for this too &#8211; we call it &#8220;<em><strong>conductivity</strong></em>&#8220;.  Essentially we measure the performance of recommendations and weight the effectiveness of the current vectors of relevancy.  Over time we&#8217;ll start to adjust the vectors (&#8220;oh look, it turns out that herbs/spice is a bigger deal than we thought&#8221;) to increase the performance of the content policy objects.</p>
<h2>What about Modality?</h2>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/social-sharer.png"><img class="alignnone size-full wp-image-451" title="social sharer" src="http://antipatter.com/wp-content/uploads/2011/05/social-sharer.png" alt="" width="460" height="183" /></a></p>
<p><a href="http://antipatter.com/wp-content/uploads/2011/05/social-sharer.png"></a>In the original <a href="http://antipatter.com/2011/04/conversational-architecture/">conversational architecture article</a> I talked a fair amount about modal websites.  How does modality apply to personalization then?  I think that first one should realize that while you don&#8217;t have to use modality to build a personalized website using conversational architecture concepts, modality <em>can</em> provide you with a way of describe some special features that could take your personalized website over the top.</p>
<p>The basic guideline is: when moving away from ideas that can be expressed easily in terms of content policy objects &#8211; modality can be very helpful.  For example, imagine an e-commerce website that provided discounts for people who frequently shared products from the site through social networking channels like Facebook and Twitter.  In Conversational Architecture terms, you could identify this kind of person as a Persona (call them &#8220;social sharer&#8221; or something) and trigger a mode from that persona that caused a discount to appear in their shopping cart.  This is an easily expressed business rule that could then be implemented through automation on the site.</p>
<h2>Wrap Up</h2>
<p>So we introduced five new concepts that Conversational Architecture provides that allow businesses to more clearly articulate what they want from personalization: <strong>content policy objects</strong> that provide customized mixes of content, products etc., <strong>vectors of relevancy</strong> that determine the relative importance of content metadata when calculating recommendations, <strong>confidence</strong> which expresses the performance of content policy objects in terms of conversion, <strong>conductivity</strong> which expresses the evolution of vectors of relevancy over time, and finally how <strong>modality</strong> can be applied to a personalization problem.</p>
<p>This is obviously a lot of new ideas, however it&#8217;s entirely possible to just try them out one at a time and look for incremental improvement in your personalization implementation.  By using these concepts, you have acquired a language in which to discuss personalization, which will allow businesses to more closely align personalization with their specific approaches to operating their business.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2011/05/fixing-personalization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modeling Risk (Part 4) &#8211; Putting It All Together</title>
		<link>http://antipatter.com/2009/08/modeling-risk-part-4-putting-it-all-together/</link>
		<comments>http://antipatter.com/2009/08/modeling-risk-part-4-putting-it-all-together/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 01:28:28 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web agency]]></category>
		<category><![CDATA[risk]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=282</guid>
		<description><![CDATA[
In this, the final installment of the Modeling Risk series, we going to put together everything we covered in the previous installments into a unified risk model. In part one we learned about Client Risk: risk that clients bring when they walk through the door.  Based on attributes such as the ability to make decisions, [...]
]]></description>
			<content:encoded><![CDATA[<p>In this, the final installment of the Modeling Risk series, we going to put together everything we covered in the previous installments into a unified risk model.</p>
<p style="text-align: center;"><img class="size-medium wp-image-284 aligncenter" title="risk" src="http://antipatter.com/wp-content/uploads/2009/08/risk-300x233.png" alt="risk" width="300" height="233" /></p>
<p>In <a href="http://antipatter.com/2009/07/modeling-risk/">part one</a> we learned about Client Risk: risk that clients bring when they walk through the door.  Based on attributes such as the ability to make decisions, relative insensitivity to price and technology agnosticism, clients can either be part of the problem or part of the solution when it comes to managing risk.</p>
<p>In <a href="http://antipatter.com/2009/08/modeling-risk-part-2/">part two</a> we learned about Structural Risk: risk that is derived from how the team is structured &#8211; whether they are familiar with each other, a common process, the tech or the client.  In some ways this type of risk is learning curve risk, because it models how many learning curves are piled onto the project.</p>
<p>Finally, in <a href="http://antipatter.com/2009/08/modeling-risk-part-3-quality/">part three</a> we learned about Qualitative Risk: risk that is driven from the quality of the team, the technology and the support for the team.  The better these things are, the more curve balls they can handle, and the more they can cope with risk from the other vectors.</p>
<p>From each of these three aspects of risk we derived an overall letter grade: from A to F.</p>
<h2>Putting it All Together</h2>
<p>Here&#8217;s how the letter grades combine:</p>
<h3>Low Risk: All A&#8217;s and B&#8217;s</h3>
<p>This is a good to great project with minimal risk.  In this range you can count on projects staying on track, and arriving where they are supposed to within budget, on schedule and at a level of quality that will satisfy everyone.</p>
<h3>Medium Risk: One or Two C&#8217;s</h3>
<p>This is a project that has a combination of a relatively problematic client, an immature team, or mediocre quality issues.  It is possible to succeed in this space, but it requires a close watch and quick action to mitigate the problems that inevitably will come up.  The success of the project depends on at least on of the three areas being better than the &#8220;C&#8221; level &#8211; the strength that can hold up the project.</p>
<h3>High Risk: Three C&#8217;s or One or Two D&#8217;s</h3>
<p>This is a project that, from its onset, has a good chance of going bad.  Either there is no strong area that pulls the project up to the medium risk level, or there is one or more areas with real problems: a truly high risk client, an immature team or poor quality from the team, the technology or the team&#8217;s support system.</p>
<p>Despite the best risk-mitigating activity from management, there is still a good chance that this project will go wrong.  It would be  a sound decision to walk away from such a project, but if taking it on is necessary, then it should be approached extremely defensively, as there will inevitably be serious crises as the project progresses.</p>
<h3>Lead Balloon: One or more F&#8217;s, or 3 D&#8217;s</h3>
<p>This is either a project with an impossible client, a disastrous team, or a catastrophic quality issue; or it is a project that is merely poor in all three areas.</p>
<p>Generally speaking, it is not possible to be successful with such a project.  The presence of the F will sink the project on its own, or the general malaise of the 3 D&#8217;s will accumulate into a disaster.</p>
<p>A project at this level needs a fundamental reset: generally either the client or the team has to go, depending on the source of the problems.  Risk mitigation at this level will be overwhelmed.</p>
<h2>Conclusion</h2>
<p>So there you go &#8211; my general theory of project risk.  I hope that you find it helpful, and through it gain a greater understanding of why projects succeed and fail, and when to plunge ahead, and when to run the other way.  Good luck!</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2009/08/modeling-risk-part-4-putting-it-all-together/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modeling Risk (Part 3): Quality</title>
		<link>http://antipatter.com/2009/08/modeling-risk-part-3-quality/</link>
		<comments>http://antipatter.com/2009/08/modeling-risk-part-3-quality/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 05:09:35 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[web agency]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=267</guid>
		<description><![CDATA[
The plot so far:  there are specific things that cause project&#8217;s to fail, beyond the abilities of seemingly competent people to control.  These forces aren&#8217;t random, they are specific patterns and antipatterns that create accumulating risk that bears down on projects like debt. In Part 1 we discussed client driven risk &#8211; the problems that [...]
]]></description>
			<content:encoded><![CDATA[<p>The plot so far:  there are specific things that cause project&#8217;s to fail, beyond the abilities of seemingly competent people to control.  These forces aren&#8217;t random, they are specific patterns and antipatterns that create accumulating risk that bears down on projects like debt.</p>
<p>In <a href="http://antipatter.com/2009/07/modeling-risk/">Part 1</a> we discussed client driven risk &#8211; the problems that clients bring to the table and how they affect the project.  In <a href="http://antipatter.com/2009/08/modeling-risk-part-2/">Part 2</a> we discussed structural risk &#8211; risk that originates with the composition of the team working on the project.</p>
<p>The third and list type of risk I call <strong>Qualitative Risk</strong>.  This is a kind of risk that is affected by the quality of the tools and people executing the project.  Everything counts, everything matters.  Quality affects the project.</p>
<p>There is a school of thought in business that would dearly like to factor quality out of the equation.  Businesses that trade in commoditized markets, competing on price, basically operate on the supposition that there is a standard level of quality and that it is not a distinguishing characteristic.  The movement towards off-shoring software development included an attempt to factor out quality.  Command-and-control programming languages like Java and .NET are attempts to engineer developer quality out of the equation &#8211; at least partially.</p>
<p>Quality, however, matters.  The web development framework you choose will affect the project, positively or negatively.  The skills of the developers you hire will affect the project.  It is not just subjective, some of these things are actually better than others.</p>
<p>I break Quality factors down into 3 main pillars: <em>Team</em>, <em>Tech</em> and <em>Support</em>.</p>
<p><strong>Team:</strong> How strong is the team?  My feeling is there should be at least 1 really good senior developer for every 3 medium or junior developers on staff.  In addition, it is good to have at least a couple of honest-to-goodness rock stars around &#8211; the people who can be thrown against any technical challenge and still land on their feet.  The bar should be set at a level where the team can be counted on to astonish you on at least a semi-regular basis.</p>
<p><strong>Tech:</strong> How good is the tech on which you&#8217;re building this thing?  Does it provide features that you need?  Does it provide a means of accelerating custom development, in case you need to go outside those features?  How often is time spent using the technology solving actual business problems, as opposed to just servicing the demanded ceremonies of the technology?  When is the technology enabling you, and when are you fighting it?</p>
<p><strong>Support:</strong> The infrastructure: managerial, administrative, legal, HR etc., that surrounds the team &#8211; how much is it helping?  Is HR effective in finding new talent?  How about support from IT?  Is it straightforward to get ticket systems, continuous integration servers, new virtual servers etc. set up?  Or does every request take forever, with the development team resorting to circumventing the company infrastructure?  Does management back and support the development team, or are they selling them up the river?</p>
<p>Each of these pillars is deep and complicated, so grading them is a little abstract.  However if you set an aggregate grade for each pillar and take the average you&#8217;ll get a sense of the qualitative risk associated with the project.  Again, starting about the C grade and intensifying as you drop below that, you can easily get to a level of unacceptable risk.</p>
<p><strong>In the next and final installment of this series &#8211; we&#8217;ll look at putting all the various risk factors, client-driven, structural and qualitative, into an overall risk profile.</strong></p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2009/08/modeling-risk-part-3-quality/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modeling Risk (Part 2)</title>
		<link>http://antipatter.com/2009/08/modeling-risk-part-2/</link>
		<comments>http://antipatter.com/2009/08/modeling-risk-part-2/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 22:32:49 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web agency]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[teams]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=254</guid>
		<description><![CDATA[
In part one we had a look at risk that comes to the project from the client, before it even starts.  This time we&#8217;ll look at risk that comes from the composition of the project and the project team. I like to call this second category Structural Risk, because it has to do with how [...]
]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://antipatter.com/2009/07/modeling-risk/">part one</a> we had a look at risk that comes to the project from the client, before it even starts.  This time we&#8217;ll look at risk that comes from the composition of the project and the project team.</p>
<p>I like to call this second category <strong>Structural Risk</strong>, because it has to do with how a project is structured: the parts that make it up.  Again, to take the positive angle &#8211; each point below is listed in its non-risk-adding, positive side:</p>
<ul>
<li><strong>The team has worked together before.</strong> The team itself is a known quantity, with the individual talents and personalities of each team member known to the group.  This knowledge allows team members to guide the project to leverage the various strengths and avoid the weaknesses of the individuals on the team, working together to achieve the highest level of productivity.  Also hopefully people like and respect each other.</li>
<li><strong>The team knows the technology.</strong> It is a technology that the team has worked with before &#8211; they know how to work with it rather than wind up fighting it.  They are unlikely to be surprised by strange quirks of the tech stack that creep up at the most inopportune times.</li>
<li><strong>The team knows the client.</strong> The team has worked with this client before, and therefore knows the business problems that intersect their space.  This way they will be less likely to make poor assumptions about how things are supposed to work.  Functional specs are great, but they don&#8217;t take the place of actual domain knowledge on the part of the team.</li>
<li><strong>The team has a methodology for staying on track.</strong> Without getting into the comparative merits of individual development methodologies, the main point is that the team has a way to prioritize, track progress, and correct problems early on.  A team that can&#8217;t tell that it&#8217;s off-course can&#8217;t correct.</li>
<li><strong>The team can effectively communicate to management, and vice-versa.</strong> The cliche is that management understands different levels of priority for requirements, but sees all cost of implementation as equal.  Developers see different costs of implementation, but imagine all requirements to be equally important.  Neither is true, of course, and there needs to be an effective channel for technical and business stakeholders to properly communicate with each other.  A Tech Lead can be an effective method here.</li>
</ul>
<p>Note that none of this discusses the individual experience or quality of the members of the team.  This is structural.  Process and management &#8211; all about getting people to speak with each other, and work well together.</p>
<p>Again 1 point for each &#8220;yes&#8221; answer for your team, just like in part one.</p>
<p style="padding-left: 30px;"><strong>5 points: A.</strong> Your team knows each other, the client and the means to success like the back of their hand.  You&#8217;ve probably already made the mistakes you are going to make, so you can count on solid execution from people.</p>
<p style="padding-left: 30px;"><strong>4 points: B.</strong> Still solid.  B is as good as a team can get with a new client (and at least in agency work new clients are frequent).  B is structurally still a good risk, but can occasionally throw up a surprise or two.</p>
<p style="padding-left: 30px;"><strong>3 points: C.</strong> Medium risk.  At this level there is at least some degree of immaturity in the team &#8211; it may reflect new hires, or the creation of a new team where there wasn&#8217;t one before.  The team is still working out the kinks in their process.</p>
<p style="padding-left: 30px;"><strong>2 points: D.</strong> This is an immature team.  There are enough unknowns going on at this level that the team can easily trip over itself, adding significant risk to a project.  Watch out.</p>
<p style="padding-left: 30px;"><strong>1 and below: F.</strong> The team is not ready for this project.  The structural problems will create a significant negative impact on the project, probably leading to some level of failure.</p>
<p><em><strong>To be concluded in part 3, where we&#8217;ll look at qualitative risk, and how to combine all the risk factors together into a single model.</strong></em></p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2009/08/modeling-risk-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modeling Risk</title>
		<link>http://antipatter.com/2009/07/modeling-risk/</link>
		<comments>http://antipatter.com/2009/07/modeling-risk/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 20:50:23 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web agency]]></category>
		<category><![CDATA[clients]]></category>
		<category><![CDATA[projects]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=241</guid>
		<description><![CDATA[
Why do some software / web projects run off the rails so badly?  Are we just incompetent?  Is it that the very practice of programming is so incredibly difficult that it defies any attempt to manage it?  Perhaps software development is just an inherently terrible idea, and we should leave it up to Microsoft to [...]
]]></description>
			<content:encoded><![CDATA[<p>Why do some software / web projects run off the rails so badly?  Are we just incompetent?  Is it that the very practice of programming is so incredibly difficult that it defies any attempt to manage it?  Perhaps software development is just an inherently terrible idea, and we should leave it up to Microsoft to handle, and focus on other things, such as selecting the best clip-art for our PowerPoint slides.</p>
<p>Okay, no one buys that exactly, but there is a certain amount of seeming randomness in software or web development that makes developers and managers both very, very nervous when entering new endeavors.  Everyone knows from past experience that even with the best of intentions, things seem to occasionally go terribly wrong.</p>
<p>I&#8217;d like to suggest that things happen for a reason, however.  In the case of software development projects, there are specific patterns and phenomena that drive projects towards success or failure, and that learning to recognize those patterns can lead one to manage them much better.</p>
<p>In fact I would take that one step further, and say that these patterns can actually be modeled, and together form a bit of a magic 8-ball on what&#8217;s likely to happen with the project.</p>
<h3>Clients</h3>
<p>Many software development projects have clients involved, and for many of them the problems start right there.  Clients present an extremely powerful influence over projects, because if they are not happy, there is no business.  Clients do not always act in their own best interests however, or the best interests for the project.  Therein lies the rub.</p>
<p>I&#8217;ve identified a specific set of criteria that identifies good clients.  Clients with these attributes are good, those without them are bad.  Howe much risk a client brings to a project depends on how many items on this list they rate.</p>
<ul>
<li><strong>Strong decision maker:</strong> Is there someone (much preferably an individual person) who can make decisions in the client organization?  Or is there a distributed set of stakeholders, all with different agendas, values and visions about what the product should be?</li>
<li><strong>Reasonably Insensitive to Price:</strong> Does the client appreciate the value of what they&#8217;re getting?  Or do they just want to slash, slash, slash prices and get the cheapest possible version of their site?  Do they argue over every last nickle and dime?</li>
<li><strong>Technology Agnostic:</strong> Tech matters.  Anyone who says differently is ignorant or lying.  The choices of hosting, frameworks, platforms, products etc all compound and add or remove risk from the project.  Good clients are ones that allow and encourage the best tools for the jobs to be used.  Bad clients come in the door with corporate technology mandates that have nothing to do with the specific interests of the project.</li>
<li><strong>On a Reasonable Deadline, but Flexible on Scope:</strong> Projects need schedules in order to happen, but the uncertainty baked into programming demands that something in the classic project management triangle flex, and the best thing to flex is scope.  When there is a clearly prioritized set of features on the table, the upcoming release may or may not have certain features, or they may be implemented at a number of different levels of complexity.  Hard features of limited business or user value should be jettisoned.</li>
<li><strong>Savvy:</strong> Good clients know their own business, the Internet and so forth.  Clients that require teaching on every last point that intersects the project slows things down, and opens the door for them to make bad decisions.  A client that is reasonably well educated on their space and how it relates to the project will be much less off than others.</li>
</ul>
<h5>Grading</h5>
<p>For your client, award 1 point for each of the above criteria.</p>
<p style="padding-left: 30px;"><strong>5 points: A.</strong> Run, don&#8217;t walk and get this client&#8217;s business.  They are extremely rare and can be the basis of an excellent partnership in which you can do great things.</p>
<p style="padding-left: 30px;"><strong>4 points: B.</strong> A good, run of the mill client.  Will occasionally do something bothersome, but well within the parameters of something that can be managed for success.</p>
<p style="padding-left: 30px;"><strong>3 points: C.</strong> Fair.  This is starting to get into the range where client risk can adversely affect the project.  If it is combined from risk from other factors, failure can occur.  Nonetheless it is possible to succeed with a C client.</p>
<p style="padding-left: 30px;"><strong>2 points: D.</strong> Not good.  This is a high-risk client, and this kind of work should only be taken on if painstaking steps are taken to protect the team from bad influences and decisions made by the client.  A large amount of time will be spent on keeping this client under control, and preventing them from damaging the project.  It better be worth it.</p>
<p style="padding-left: 30px;"><strong>1 and below: F.</strong> This client brings disaster with them.  It is almost impossible to succeed with this kind of client, and it usually isn&#8217;t worth it.  They will be a never-ending source of problems, and will compel bad decisions that will most likely derail the project.  Avoid.</p>
<p><em><strong>Continued in part 2, when we&#8217;ll look at some of the other risk factors that bear on a project.</strong></em></p>
<p>UPDATE: Okay, so I <a href="http://antipatter.com/2008/08/how-to-work-with-web-agencies/">covered some of this before,</a> but this is part of the model, so its sort of from the opposite tack.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2009/07/modeling-risk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problems, Salesmen and Engineers</title>
		<link>http://antipatter.com/2008/09/problems-salesmen-and-engineers/</link>
		<comments>http://antipatter.com/2008/09/problems-salesmen-and-engineers/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 02:14:31 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web agency]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[psychology]]></category>
		<category><![CDATA[sales]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=207</guid>
		<description><![CDATA[
Remember this old joke? A mathematician sits on a park bench next to a pretty girl.  He wants to move closer but is struck by the helplessness of the situation: he&#8217;ll move half the distance, then half of the remaining distance, then half of that, and so on and so on &#8211; but will never [...]
]]></description>
			<content:encoded><![CDATA[<p>Remember this old joke?</p>
<blockquote><p>A mathematician sits on a park bench next to a pretty girl.  He wants to move closer but is struck by the helplessness of the situation: he&#8217;ll move half the distance, then half of the remaining distance, then half of that, and so on and so on &#8211; but will never actually reach the girl because the remaining distance can always be halved.</p>
<p>Later an engineer finds themselves in the same position.  Like the mathematician, he knows its impossible to actually reach the girl, but he realizes he can get close enough for all practical purposes.</p></blockquote>
<p>(Okay, it is, and has always been, a dumb joke.  But it&#8217;s about how engineers think, and that&#8217;s what I want to talk about.)</p>
<p>Engineers solve problems.  In order to solve problems, they need to identify them.  They need to get down in the detailed muck of whatever it is at hand so they can see how things work and find a solution.  This is called &#8220;getting your hands dirty&#8221;.</p>
<p>Most people are afraid of problems.  Problems make them feel like victims &#8211; helpless to control their fate.  They&#8217;re used to problems making life worse for them, without any available solutions.</p>
<p>Engineers, on the other hand, relish the thought of new problems.  After all, they&#8217;re used to having problems fall before their mental prowess &#8211; sliced into bits by <a href="http://en.wikipedia.org/wiki/Occam's_Razor "> Occam&#8217;s Razor</a>.  The existence of problems is enjoyable to an engineer: it gives them something to do.  To most, however, the existence of problems is upsetting.</p>
<p>And that brings us to salespeople.  Salespeople identify problems that upset people, and they sell solutions to those problems.  (And since this is a web agency post, by &#8220;solutions&#8221; I mean &#8220;websites&#8221;).  In theory, people will feel better because their problems have now been solved. The salesperson also feels better because they now have money.</p>
<p>Now what salespeople <strong>don&#8217;t</strong> want to do is dwell on the problem..  They want to talk about the solution.  No problems should escape the solution.  The solution leads to the sale.  Focus on the solution.  Always Be Closing.  Dwelling on problems creates doubt in the mind of non-engineers, and doubt screws up closing the deal.</p>
<p>So, ultimately, the salesperson wants to play down any problems that are not solved by signing the deal, whereas the engineer wants to dwell on them in detail.  Disconnect.</p>
<p>Weird things can start to happen when you bring an engineer into a sales situation; something that is occasionally necessary.  In the web agency world, the art of deal making is that<strong> the sale is made long before it&#8217;s clear what is being sold</strong>.  For <em>n</em> dollars, <em>something</em> will be built that will do something on the lines of solving these business problems.  Sort of.  Give or take.</p>
<p>This is totally backwards to the engineer, who, in their problem solving mindset, wants to be given a problem to solve.  A set of metrics for success.  A clearly defined goal.  But that&#8217;s not the way agencies work.  First you pay, later you find out what you get.</p>
<p>In order to close the deal, the salesperson needs to keep out of the details, and basically imply that the website will do everything that the client wants, but without <em>actually</em> promising anything specific.  The danger to the salesperson is that the engineer, being detail conscious, will screw this up.</p>
<p>The danger for the engineer is that the salesperson might sell something that simply can&#8217;t be delivered for the specified budget.  Or perhaps commits the engineering team to a ridiculous technical constraint that adds so much risk to the project, or is so onerous, that what started as a simple project becomes a nightmare.</p>
<p>When an agency works well, there&#8217;s a kind of dance between sales and engineering, where sales gets deals done without being drawn down into the muck of engineering, but doesn&#8217;t create any deals too stupid for engineering to be able to deliver.</p>
<p>When sales and engineering don&#8217;t sufficiently trust or respect each other the dance breaks down.  Then sales closes deals that are impossible, and engineering bogs sales negotiations down in details that simply shouldn&#8217;t see the light of day until the ink dries on the contract.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2008/09/problems-salesmen-and-engineers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Everybody Disco</title>
		<link>http://antipatter.com/2008/09/everybody-disco/</link>
		<comments>http://antipatter.com/2008/09/everybody-disco/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 02:13:04 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[concurrent]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=181</guid>
		<description><![CDATA[
I&#8217;m looking at a new project called Disco.  It was developed by Nokia as an implementation of MapReduce, the Google-spawned algorithm for sharding a large computing task into pieces that can be crunched by multiple cores or servers.  Word has it that MapReduce is used extensively at Google, probably to build that big index, I&#8217;m [...]
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m looking at a new project called <a title="Disco" href="http://www.discoproject.org" target="_blank">Disco</a>.  It was developed by Nokia as an implementation of <a title="MapReduce" href="http://labs.google.com/papers/mapreduce.html" target="_blank">MapReduce</a>, the Google-spawned algorithm for sharding a large computing task into pieces that can be crunched by multiple cores or servers.  Word has it that MapReduce is used extensively at Google, probably to build that big index, I&#8217;m guessing.</p>
<p>The core of Disco is implemented in <a title="Erlang" href="http://www.erlang.org/" target="_blank">Erlang</a>, the concurrent, fault-tolerant, multicore-ready distributed computing platform developed some time ago at Ericsson.  Erlang is brilliant, though <a title="Thinking in Concurrency" href="http://antipatter.com/2008/07/thinking-in-concurrency/" target="_blank">kind of weird</a>, and represents a big educational hurdle for the existing programming population.  It&#8217;s just too different from the existing major programming paradigms.</p>
<p>Disco takes a stab at solving that problem, by allowing programmers to write their jobs in <a title="Python" href="http://python.org/" target="_blank">Python</a>.  The jobs are executed by the Erlang core, buying all that distributed, fault-tolerant goodness that Erlang provides, but keeping it safely sealed away from application developers who can work in the relatively friendlier world of Python.</p>
<p>Here (lifted directly from the Disco documentation) is a Disco job:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">from</span> disco.<span style="color: black;">core</span> <span style="color: #ff7700;font-weight:bold;">import</span> Disco, result_iterator
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> fun_map<span style="color: black;">&#40;</span>e, params<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>w, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> w <span style="color: #ff7700;font-weight:bold;">in</span> e.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> fun_reduce<span style="color: black;">&#40;</span><span style="color: #008000;">iter</span>, out, params<span style="color: black;">&#41;</span>:
    s = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> w, f <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">iter</span>:
        s<span style="color: black;">&#91;</span>w<span style="color: black;">&#93;</span> = s.<span style="color: black;">get</span><span style="color: black;">&#40;</span>w, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> + <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> w, f <span style="color: #ff7700;font-weight:bold;">in</span> s.<span style="color: black;">iteritems</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        out.<span style="color: black;">add</span><span style="color: black;">&#40;</span>w, f<span style="color: black;">&#41;</span>
&nbsp;
results = Disco<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;disco://localhost&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">new_job</span><span style="color: black;">&#40;</span>
		name = <span style="color: #483d8b;">&quot;wordcount&quot;</span>,
                <span style="color: #008000;">input</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;http://discoproject.org/chekhov.txt&quot;</span><span style="color: black;">&#93;</span>,
                <span style="color: #008000;">map</span> = fun_map,
		<span style="color: #008000;">reduce</span> = fun_reduce<span style="color: black;">&#41;</span>.<span style="color: black;">wait</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> word, frequency <span style="color: #ff7700;font-weight:bold;">in</span> result_iterator<span style="color: black;">&#40;</span>results<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">print</span> word, frequency</pre></div></div>

<p>So this code snip is about creating a word count of some text.  MapReduce always consists of two functions &#8211; the Map function, which is used to split up a big job into a bunch of smaller jobs, and the Reduce function which assembles it back together into a single result.  (This is the essence of MapReduce, and isn&#8217;t tied to a particular technology).</p>
<p>The code above has two fun_* functions.  &#8220;Fun&#8221; is a Erlang-ism that creates an anonymous function, not unlike a lambda in Python.  The functions themselves are passed into the Disco instance which then spits out the results, once all the reduce functions exit no doubt.</p>
<p>So in the above code example, it looks like each word gets its own job, zipping through the text and getting a frequency count.  The job split is initially established by fun_map.  Then fun_reduce runs, concurrently, once per unique word in the text and counts up the frequency of that word, adding its results to the &#8220;out&#8221; accumulator.  Disco ties it all together and returns it as the &#8220;results&#8221;.</p>
<p>Wait, this gets better.  Disco comes with tools that allow it to be deployed on <a title="Amazon EC2" href="http://www.amazon.com/gp/browse.html?node=201590011" target="_blank">Amazon&#8217;s EC2</a> computing cloud.  (Hm, Python.  <em>Django-Disco</em> anyone?) Imagine dynamic, linear capacity scaling, on rented compute cycles, with easily written Python jobs.  I think I might be salivating a bit.</p>
<p>I&#8217;m a huge fan of anything that can deliver concurrent programming power in a form that&#8217;s paletable to programmers that haven&#8217;t grown up with it.  I&#8217;m going to eagerly watch the Disco project to see how it does.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2008/09/everybody-disco/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn or Die</title>
		<link>http://antipatter.com/2008/09/learn-or-die/</link>
		<comments>http://antipatter.com/2008/09/learn-or-die/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 13:16:50 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[crybaby]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=169</guid>
		<description><![CDATA[
I could never get my employers to pay for training.  Back in the beginning of my career, when I was dirt poor, even computer books were really expensive for me.  However, I somehow scraped together what was (for me) an enormous amount of cash to buy the books that I needed to learn (actually paying [...]
]]></description>
			<content:encoded><![CDATA[<p>I could never get my employers to pay for training.  Back in the beginning of my career, when I was dirt poor, even computer books were really expensive for me.  However, I somehow scraped together what was (for me) an enormous amount of cash to buy the books that I needed to learn (actually paying for classes wasn&#8217;t even on the table).  I had heard of the concept of employers paying for training, but the tiny start-ups where I worked could never afford that kind of thing.</p>
<p>That&#8217;s why I&#8217;m absolutely confounded by people who, when being presented with the opportunity to learn something new on their employer&#8217;s dime, refuse or drag their feet.  These people have someone who is willing to pay them to become even more marketable than they are now.  They can earn while they learn.  And yet, their answer is &#8220;no thanks&#8221;.</p>
<p>What drives this kind of thinking?  Why would someone decline to learn something new?  I can think of a couple of things:</p>
<p>First, I think that people legitimately realize that learning new things can potentially change your worldview, making you re-evaluate the truth of things that you supposedly knew before.  However, this becomes the &#8220;path to the dark side&#8221; when people reject the idea of learning new things <em>because</em> they&#8217;d rather maintain their existing worldview rather than having a greater comprehension of the truth.  It&#8217;s willful ignorance.  To avoid learning things for this reason is to choose to be stupid.</p>
<p>Secondly, (and I&#8217;m a bit more sympathetic to this reason) some people have been taught that a particular technology as a solution to everything.  Java (where I spent a good decade of my time) has been sold as the development environment for everything from an embedded, to a desktop apps, to web apps, to mainframe computing.  The message was that Java is the tool of choice for <em>everything</em>.  So why would one learn anything else?  What&#8217;s the point?  (Okay, so this actually sounds a bit like laziness to me, but such is the human condition &#8211; I accept that.)</p>
<p>Finally, a somewhat plausible reason I&#8217;ve heard is that people only want to learn things that have a direct impact on their capacity to make money.  Java developers are statistically paid the most of any developers &#8211; so again &#8211; why learn something else?  What is sad about that is that the best of the development community (and the source of much technology) comes from people who actually love technology.  People who are only in it for the money tend to also be mediocre programmers.</p>
<p>So here&#8217;s my plea to those who would choose not to learn new technology (or new things in general), whether out of fear, laziness or avarice: your brain is dying.  Save it.</p>
<p>Learning is a habit that keeps you sharp.  The more you learn, the more capable you are of learning.  This is a virtuous cycle that can get you 1) a robust and well-informed (albeit still disrupt-able) worldview, 2) a deep toolkit of knowledge to take on different problem domains and 3) awesome market value, allowing you to rake in the cash.  In other words &#8211; all of the stuff you care about can be accomplished to a much higher degree by learning new things.  There&#8217;s work involved, sure, but if you stay ignorant you&#8217;ll only be working hard anyway: putting out fires in your career because you don&#8217;t have the knowledge to take control of the situation.</p>
<p>Taking every chance I&#8217;ve had to learn new things has been the engine that&#8217;s driven my career.  So, please, if someone offers you a chance to learn something new, on their dime, <em>take it</em>.  On both a personal and professional level, its keeping you alive.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2008/09/learn-or-die/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stack &#8216;em Up</title>
		<link>http://antipatter.com/2008/08/stack-em-up/</link>
		<comments>http://antipatter.com/2008/08/stack-em-up/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 02:23:19 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tech strategy]]></category>
		<category><![CDATA[web agency]]></category>
		<category><![CDATA[monoculture]]></category>
		<category><![CDATA[tech stack]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=133</guid>
		<description><![CDATA[
It&#8217;s been a bit longer than I wanted between posts &#8211; side effect of coming off of a vacation and going directly into a new job.  Sorry.  I&#8217;ll try to be more consistent, moving forward. The idea of maintaining a single technology stack in a development shop is quite appealing.  If everyone knows the same [...]
]]></description>
			<content:encoded><![CDATA[<p><em>It&#8217;s been a bit longer than I wanted between posts &#8211; side effect of coming off of a vacation and going directly into a new job.  Sorry.  I&#8217;ll try to be more consistent, moving forward.</em></p>
<p>The idea of maintaining a single technology stack in a development shop is quite appealing.  If everyone knows the same programming language (the thinking goes), the same web framework, the same RDBMS and so forth, then life would be better.  Business really likes this kind of thinking.  It promises efficiencies of scale, reduced training costs, and easily replaceable employees.  This kind of &#8220;one true technology&#8221; approach is the foundational philosophy of corporate darlings Java and .NET.    Once you have the organization standardized on the tech, it is promised, then every part will play nicely with every other part, critical dependencies (such as employees) will be reduced, and the whole &#8220;what are we doing about technology&#8221; question just goes away.</p>
<p>Now, of course I support operational efficiencies, reducing training costs (well, to an extent: I view training as an investment), and so forth, but I think that the idea of &#8220;one true stack&#8221;, especially in service-oriented tech shops like web agencies, is a pipe dream.  The advantages of standardizing an entire company on a single tech stack are outweighed by the disadvantages.</p>
<p>Before I get into that, however, I want to introduce the idea of a &#8220;jealous&#8221; technology.  A jealous technology tries to take over as many aspects of the stack as possible; mandating a specific component at each level.  Some technologies are more &#8220;jealous&#8221; than others.  Microsoft is notoriously jealous:  the Microsoft web framework, ASP.NET, really wants to be deployed on the Microsoft web server: IIS, on the Microsoft operating system: Windows, backed by the Microsoft RDBMS: SQL Server.  Other combinations (yes, I know about <a href="http://www.mono-project.com/Main_Page" target="_blank">Mono</a>) simply don&#8217;t work as well.  And, on the other hand, Windows is something of a second-class deployment platform for most other web technologies (ever try to deploy Rails on Windows&#8230;with IIS?  Yuck&#8230;)</p>
<p>Speaking of Ruby on Rails, they&#8217;ve become a bit of a jealous technology themselves.  Rails projects now prefer a particular JavaScript framework (Prototype), version control system (Git), editor (TextMate), build system (Capistrano) and development operating system (OS X).  (As well as, obviously, programming language: Ruby). While it&#8217;s certainly not as bad as the Microsoft scenario,  I do have to ask the question as to why the web framework has <em>any</em> influence over what version control system I use.  Do you have to use all the technologies that I&#8217;ve listed above with Rails?  No, of course not.  But they are <em>preferred</em>.  Things go better with <span style="text-decoration: line-through;">Coke</span> Capistrano.</p>
<p>The point is that some technologies are better suited towards certain problems than others, and <strong>a blanket organizational standardization on a single tech stack leads to a tremendous amount of wasted energy spent on driving square pegs into round holes</strong>.  Ruby is not a great foundation for an enterprise-class messaging framework.  Java is not a good choice for a lightweight CMS.  And anything other than .NET is a bad choice for an app destined to be maintained by a bunch of MSDN types.</p>
<p>In fact, I&#8217;d argue that <strong>the cost of operation efficiencies lost by maintaining multiple tech stacks is exceeded by the cost of jamming technologies into inappropriate use cases</strong>.  So, as messy as it sounds, any technical organization that is project or service based (as opposed to being exclusively product based) should maintain a strategic &#8220;quiver&#8221; of different technologies, so it can deploy the best choice when faced with a business problem.  Otherwise a fragile <a href="http://en.wikipedia.org/wiki/Monoculture_(computer_science) "> monoculture</a> is created, wasting a tremendous amount of developer effort, and adding artificial risk and expense to projects.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2008/08/stack-em-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Thinking in Concurrency</title>
		<link>http://antipatter.com/2008/07/thinking-in-concurrency/</link>
		<comments>http://antipatter.com/2008/07/thinking-in-concurrency/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 15:58:20 +0000</pubDate>
		<dc:creator>loren</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rampant speculation]]></category>
		<category><![CDATA[concurrent]]></category>
		<category><![CDATA[erlang]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[reia]]></category>

		<guid isPermaLink="false">http://antipatter.com/?p=27</guid>
		<description><![CDATA[
A few weeks ago, Anwar Ghuloum at the Research@Intel blog advised developers that they should start thinking about &#8220;tens, hundreds and thousands of cores&#8221;.  In essence, the people that control processor development are telling us that the future of programming is going to move out rather than up.  To get an idea of the time [...]
]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, Anwar Ghuloum at the Research@Intel blog advised developers that they should start thinking about <a href="http://blogs.intel.com/research/2008/06/unwelcome_advice.php" target="_blank">&#8220;tens, hundreds and thousands of cores&#8221;</a>.  In essence, the people that control processor development are telling us that the future of programming is going to move out rather than up.  To get an idea of the time line, Intel&#8217;s CEO tells us to expect <a href="http://techfreep.com/intel-80-cores-by-2011.htm" target="_blank">80 cores by 2011</a>.  We can probably assume the number of cores on a processor is going to increase geometrically in the years that follow.</p>
<p><strong>The catch is that we don&#8217;t really know how to program for this.</strong></p>
<p>To take advantage of massively multicore architectures, we really need to take our computing problems and decompose them into smaller bits that can be farmed out to various worker processes.  This idea is what Google&#8217;s <a href="http://labs.google.com/papers/mapreduce.html" target="_blank">MapReduce</a> is all about, and is an approach that has worked well with certain categories of problems, such as bioinformatic data analysis, or 3D rendering.</p>
<h2>Programming Crisis</h2>
<p>I am seeing a pending programmer educational crisis coming.  Most programmers just are not trained to think about this kind of decomposition.  They&#8217;ve learned functional and object-oriented languages, and tend to think in a linear fashion.  Furthermore, the nature of the programming languages and platforms they&#8217;ve  worked on has ingrained the concept into them that multi-threaded programming is extremely tricky.  And with mainstream platforms, it is.</p>
<p>A lot of the existing difficulty with well-known languages, such as Java, is managing shared state, or memory between different threads.  Java has various synchronization mechanisms, but using them in heavily multithreaded environments can be challenging.  I&#8217;ve seen unit tests randomly pass or fail, swinging on race conditions &#8211; which thread ended first &#8211; that determine the success or failure of the test.</p>
<p>In the web world we&#8217;ve become rather fond of very high level languages such as Python and Ruby.  However the runtime story gets even worse &#8211; most scripting language runtimes can&#8217;t acknowledge more than one processor at a time &#8211; meaning that the only way to parallelize work is to instantiate multiple instances of the runtime.  Besides this being a hack, it makes communication between processes awkward (usually relying on expensive data serialization), and creates the kind of issues that we&#8217;ve been trying to get away from with high-level languages: the developer has to deal with boilerplate computer science problems, rather than being allowed to exclusively concentrate on their business problems.</p>
<h2>Concurrent Languages</h2>
<p>One answer seems to be tech stacks that are designed for concurrency from the ground up.  Enter <a href="http://www.erlang.org/" target="_blank">Erlang</a>, a language developed for telephony applications by Ericsson.  Erlang handles concurrency very, very well.  For example, it circumvents the shared state problem by <em>not having any shared state</em>.  However, from the perspective of someone with a Java or Python background (e.g. me) it&#8217;s frickin&#8217; weird.  Some serious adjustments in the way problems are approached have to be made.</p>
<p>Here&#8217;s a real simple code snip, that generates the squares of a list of numbers.  First a naive implementation in Python:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> squares<span style="color: black;">&#40;</span>num_list<span style="color: black;">&#41;</span>:
    square_list = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> n <span style="color: #ff7700;font-weight:bold;">in</span> num_list:
        square_list.<span style="color: black;">append</span><span style="color: black;">&#40;</span>n <span style="color: #66cc66;">*</span> n<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> square_list</pre></div></div>

<p>A more compact version in Python, using a list comprehension:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> squares<span style="color: black;">&#40;</span>num_list<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#91;</span>n<span style="color: #66cc66;">*</span>n <span style="color: #ff7700;font-weight:bold;">for</span> n <span style="color: #ff7700;font-weight:bold;">in</span> num_list<span style="color: black;">&#93;</span></pre></div></div>

<p>Here&#8217;s the same code in Erlang:</p>
<pre>square([H|T]) -&gt; H*H | square(T);
square([]) -&gt; [].</pre>
<p>Assuming you don&#8217;t know Erlang, can you even tell what&#8217;s going on?  You&#8217;re looking at a completely different paradigm.  The left side of the functions (to the left of the &#8220;-&gt;&#8221; marker) relies on pattern matching (sort of like regular expressions).  To the right side, the function implementation is <a title="Tail Recursion" href="http://en.wikipedia.org/wiki/Tail_recursion" target="_blank">tail recursion</a> at work.  Needless to say, this is a bit of a departure for many developers.  I shudder to think of trying to take a department of developers who cut their teeth on Java and PHP, and train them up in Erlang.</p>
<p>This is why I&#8217;m so interested in projects like <a title="Reia" href="http://wiki.reia-lang.org/wiki/Main_Page" target="_blank">Reia</a>.  In an attempt to fix the &#8220;impedance mismatch&#8221; between the coming massively multicore future, and today&#8217;s programming skills, their goal is to make a high-level Python/Ruby like language that compiles onto bytecode that will run on the Erlang VM.  It&#8217;s in a very early stage, and I&#8217;m not sure if it will ever gain critical mass, but this is a problem that needs solving, and I&#8217;m intererested in any attempts.</p>
<div class="acc_license"></div><!---->]]></content:encoded>
			<wfw:commentRss>http://antipatter.com/2008/07/thinking-in-concurrency/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

