<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Interoperability Happens - Reading</title>
    <link>http://blogs.tedneward.com/</link>
    <description>Ted's takes on the enterprise Java, .NET and Web services communities and technologies</description>
    <copyright>Ted Neward</copyright>
    <lastBuildDate>Thu, 09 Sep 2010 03:53:01 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.7067.0</generator>
    <managingEditor>tneward@tedneward.com</managingEditor>
    <webMaster>tneward@tedneward.com</webMaster>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=bd7339e6-fdd5-4f2a-b711-de9a38f6c743</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,bd7339e6-fdd5-4f2a-b711-de9a38f6c743.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,bd7339e6-fdd5-4f2a-b711-de9a38f6c743.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=bd7339e6-fdd5-4f2a-b711-de9a38f6c743</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Hey, anybody who’s got significant VMWare mojo, help out a bro?
</p>
        <p>
I’ve got a Win7 VM (one of many) that appears to be exhibiting weird disk behavior—the
vmdk, a growable single-file VMDK, is almost precisely twice the used space. It’s
a 120GB growable disk, and the Win7 guest reports about 35GB used, but the VMDK takes
about 70GB on host disk. CHKDSK inside Windows says everything’s good, and the VMWare
“Disk Cleanup” doesn’t change anything, either. It doesn’t seem to be a Windows7 thing,
because I’ve got a half-dozen other Win7 VMs that operate… well, normally (by which
I mean, 30GB used in the VMDK means 30GB used on disk). It’s a VMWare Fusion host,
if that makes any difference. Any other details that might be relevant, let me know
and I’ll post.
</p>
        <p>
Anybody got any ideas what the heck is going on inside this disk?
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=bd7339e6-fdd5-4f2a-b711-de9a38f6c743" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>VMWare help</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,bd7339e6-fdd5-4f2a-b711-de9a38f6c743.aspx</guid>
      <link>http://blogs.tedneward.com/2010/09/09/VMWare+Help.aspx</link>
      <pubDate>Thu, 09 Sep 2010 03:53:01 GMT</pubDate>
      <description>&lt;p&gt;
Hey, anybody who’s got significant VMWare mojo, help out a bro?
&lt;/p&gt;
&lt;p&gt;
I’ve got a Win7 VM (one of many) that appears to be exhibiting weird disk behavior—the
vmdk, a growable single-file VMDK, is almost precisely twice the used space. It’s
a 120GB growable disk, and the Win7 guest reports about 35GB used, but the VMDK takes
about 70GB on host disk. CHKDSK inside Windows says everything’s good, and the VMWare
“Disk Cleanup” doesn’t change anything, either. It doesn’t seem to be a Windows7 thing,
because I’ve got a half-dozen other Win7 VMs that operate… well, normally (by which
I mean, 30GB used in the VMDK means 30GB used on disk). It’s a VMWare Fusion host,
if that makes any difference. Any other details that might be relevant, let me know
and I’ll post.
&lt;/p&gt;
&lt;p&gt;
Anybody got any ideas what the heck is going on inside this disk?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=bd7339e6-fdd5-4f2a-b711-de9a38f6c743" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,bd7339e6-fdd5-4f2a-b711-de9a38f6c743.aspx</comments>
      <category>.NET</category>
      <category>Android</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Industry</category>
      <category>iPhone</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Objective-C</category>
      <category>Parrot</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Security</category>
      <category>Social</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>VMWare</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
      <category>XNA</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=a2b21a39-22ae-4ba7-88a4-1bcb10e8429b</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,a2b21a39-22ae-4ba7-88a4-1bcb10e8429b.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,a2b21a39-22ae-4ba7-88a4-1bcb10e8429b.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=a2b21a39-22ae-4ba7-88a4-1bcb10e8429b</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As a part of my program to learn how to use the Mac OS more effectively (mostly to
counteract my lack of Mac-command-line kung fu, but partly to get Neal Ford off my
back ;-) ), I set the home page in Firefox to point to the <a href="http://osxdaily.com/" target="_blank">OSX
Daily</a> website. This morning, <a href="http://osxdaily.com/2010/05/13/print-screen-mac/" target="_blank">this
particular page</a> popped up as the "tip of the day", and a particular
thing about it struck my fancy. Go ahead and glance at it before you continue on.
</p>
        <p>
On its own merits, there's nothing particularly interesting about it—it's a tip about
how to do a screen-capture in OS X, which is hardly a breakthrough feature. But something
about the tenor struck me: "You’ve probably noticed there is no ‘Print Screen’
button on a Mac keyboard, this is to both simplify the keyboard and also because it’s
unnecessary. Instead of hitting a “Print Screen” button, you’ll hit one of several
keyboard combination shortcuts, depending on the exact screen capture action you want
taken. ... Command+Shift+3 takes a screenshot of the full screen ... Command+Shift+4
brings up a selection box .... Command+Shift+4, then spacebar, then click a window
takes a screenshot of the window...."
</p>
        <p>
Wait a second. This is <em>simpler</em>?
</p>
        <p>
If "you're a PC", you're probably rolling on the floor with laughter at
this moment, determined to go find a Mac fanboi and Lord it over him that it requires
the use of no less than three keystrokes to take a friggin' screenshot.
</p>
        <p>
If, on the other hand, you love the Mac, you're probably chuckling at the idiocy of
PC manufacturers who continue to keep a key on the keyboard dating back from the terminal
days (right next to "Scroll Lock") that rarely, if ever, gets used.
</p>
        <p>
Who's right? Who's the idiot?
</p>
        <p>
You both are.
</p>
        <p>
See, the fact is, your perceptions of a particular element of the different platforms
(the menubar at the top of the screen vs. in the main window of the app, the one-button
vs. two-button mouse, and so on) colors your response. If you have emotionally committed
to the Mac, then anything it does is naturally right and obvious; if you've emotionally
committed to Windows, then ditto. This is a natural psychological response—it happens
to everybody, to some degree or another. We need, at a subconscious level, to know
that our decisions were the right ones to have made, so we look for those facts which
confirm the decision, and avoid the facts that question it. (It's this same psychological
drive that causes battered wives to defend their battering husbands to the police
and intervening friends/family, and for people who've already committed to one political
party or the other to see huge gaping holes in logic in the opponents' debate responses,
but to gloss over their own candidates'.)
</p>
        <p>
Why bring it up? Because this also is what drives developers to justify the decisions
they've made in developing software—when a user or another developer questions a particular
decision, the temptation is to defend it to the dying breath, because it was a decision
we made. We start looking for justifications to back it, we start aggressively questioning
the challenger's competency or right to question the decision, you name it. It's a
hard thing, to admit we might have been wrong, and even harder to admit that even
though we might have been right, we were for the wrong reasons, or the decision still
was the wrong one, or—perhaps hardest of all—the users simply like it the other way,
even though this way is vastly more efficient and sane.
</p>
        <p>
Have you admitted you were wrong lately?
</p>
        <p>
(Check out <em><a href="http://www.amazon.com/Predictably-Irrational-Hidden-Forces-Decisions/dp/006135323X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1273833371&amp;sr=8-1" target="_blank">Predictably
Irrational</a></em>, <em><a href="http://www.amazon.com/How-We-Decide-Jonah-Lehrer/dp/0547247990/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1273833400&amp;sr=8-1" target="_blank">How
We Decide</a></em>, and <em><a href="http://www.amazon.com/Why-We-Make-Mistakes-Without/dp/0767928067/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1273833436&amp;sr=8-1" target="_blank">Why
We Make Mistakes</a></em> for more details on the psychology of decision-making.)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=a2b21a39-22ae-4ba7-88a4-1bcb10e8429b" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Emotional commitment colors everything</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,a2b21a39-22ae-4ba7-88a4-1bcb10e8429b.aspx</guid>
      <link>http://blogs.tedneward.com/2010/05/14/Emotional+Commitment+Colors+Everything.aspx</link>
      <pubDate>Fri, 14 May 2010 10:40:33 GMT</pubDate>
      <description>&lt;p&gt;
As a part of my program to learn how to use the Mac OS more effectively (mostly to
counteract my lack of Mac-command-line kung fu, but partly to get Neal Ford off my
back ;-) ), I set the home page in Firefox to point to the &lt;a href="http://osxdaily.com/" target="_blank"&gt;OSX
Daily&lt;/a&gt; website. This morning, &lt;a href="http://osxdaily.com/2010/05/13/print-screen-mac/" target="_blank"&gt;this
particular page&lt;/a&gt; popped up as the &amp;quot;tip of the day&amp;quot;, and a particular
thing about it struck my fancy. Go ahead and glance at it before you continue on.
&lt;/p&gt;
&lt;p&gt;
On its own merits, there's nothing particularly interesting about it—it's a tip about
how to do a screen-capture in OS X, which is hardly a breakthrough feature. But something
about the tenor struck me: &amp;quot;You’ve probably noticed there is no ‘Print Screen’
button on a Mac keyboard, this is to both simplify the keyboard and also because it’s
unnecessary. Instead of hitting a “Print Screen” button, you’ll hit one of several
keyboard combination shortcuts, depending on the exact screen capture action you want
taken. ... Command+Shift+3 takes a screenshot of the full screen ... Command+Shift+4
brings up a selection box .... Command+Shift+4, then spacebar, then click a window
takes a screenshot of the window....&amp;quot;
&lt;/p&gt;
&lt;p&gt;
Wait a second. This is &lt;em&gt;simpler&lt;/em&gt;?
&lt;/p&gt;
&lt;p&gt;
If &amp;quot;you're a PC&amp;quot;, you're probably rolling on the floor with laughter at
this moment, determined to go find a Mac fanboi and Lord it over him that it requires
the use of no less than three keystrokes to take a friggin' screenshot.
&lt;/p&gt;
&lt;p&gt;
If, on the other hand, you love the Mac, you're probably chuckling at the idiocy of
PC manufacturers who continue to keep a key on the keyboard dating back from the terminal
days (right next to &amp;quot;Scroll Lock&amp;quot;) that rarely, if ever, gets used.
&lt;/p&gt;
&lt;p&gt;
Who's right? Who's the idiot?
&lt;/p&gt;
&lt;p&gt;
You both are.
&lt;/p&gt;
&lt;p&gt;
See, the fact is, your perceptions of a particular element of the different platforms
(the menubar at the top of the screen vs. in the main window of the app, the one-button
vs. two-button mouse, and so on) colors your response. If you have emotionally committed
to the Mac, then anything it does is naturally right and obvious; if you've emotionally
committed to Windows, then ditto. This is a natural psychological response—it happens
to everybody, to some degree or another. We need, at a subconscious level, to know
that our decisions were the right ones to have made, so we look for those facts which
confirm the decision, and avoid the facts that question it. (It's this same psychological
drive that causes battered wives to defend their battering husbands to the police
and intervening friends/family, and for people who've already committed to one political
party or the other to see huge gaping holes in logic in the opponents' debate responses,
but to gloss over their own candidates'.)
&lt;/p&gt;
&lt;p&gt;
Why bring it up? Because this also is what drives developers to justify the decisions
they've made in developing software—when a user or another developer questions a particular
decision, the temptation is to defend it to the dying breath, because it was a decision
we made. We start looking for justifications to back it, we start aggressively questioning
the challenger's competency or right to question the decision, you name it. It's a
hard thing, to admit we might have been wrong, and even harder to admit that even
though we might have been right, we were for the wrong reasons, or the decision still
was the wrong one, or—perhaps hardest of all—the users simply like it the other way,
even though this way is vastly more efficient and sane.
&lt;/p&gt;
&lt;p&gt;
Have you admitted you were wrong lately?
&lt;/p&gt;
&lt;p&gt;
(Check out &lt;em&gt;&lt;a href="http://www.amazon.com/Predictably-Irrational-Hidden-Forces-Decisions/dp/006135323X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1273833371&amp;amp;sr=8-1" target="_blank"&gt;Predictably
Irrational&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href="http://www.amazon.com/How-We-Decide-Jonah-Lehrer/dp/0547247990/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1273833400&amp;amp;sr=8-1" target="_blank"&gt;How
We Decide&lt;/a&gt;&lt;/em&gt;, and &lt;em&gt;&lt;a href="http://www.amazon.com/Why-We-Make-Mistakes-Without/dp/0767928067/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1273833436&amp;amp;sr=8-1" target="_blank"&gt;Why
We Make Mistakes&lt;/a&gt;&lt;/em&gt; for more details on the psychology of decision-making.)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=a2b21a39-22ae-4ba7-88a4-1bcb10e8429b" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,a2b21a39-22ae-4ba7-88a4-1bcb10e8429b.aspx</comments>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Industry</category>
      <category>Mac OS</category>
      <category>Reading</category>
      <category>Solaris</category>
      <category>Windows</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=39927a30-8b67-4c6d-8656-c855f1ba008c</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,39927a30-8b67-4c6d-8656-c855f1ba008c.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,39927a30-8b67-4c6d-8656-c855f1ba008c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=39927a30-8b67-4c6d-8656-c855f1ba008c</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://tirania.org/blog/archive/2010/Mar-25.html" target="_blank">Miguel
de Icaza wrote up a good response</a> to the <a href="http://74.125.93.132/search?q=cache:LPFDjfqGMRMJ:www.sdtimes.com/link/34203+Does+Windows+cost+Microsoft+opportunities&amp;cd=1&amp;hl=en&amp;ct=clnk&amp;gl=us" target="_blank">SDTimes
article</a> in which both of us were quoted, and I thought it might serve to flesh
out the discussion a bit more to chime in with my part in the piece.
</p>
        <p>
First and foremost, Miguel notes:
</p>
        <blockquote>
          <p>
David quotes Ted Neward (a speaker on the .NET and Java circuits, but not an open
source guy by any stretch of the imagination). 
</p>
        </blockquote>
        <p>
Amen to that—I have never tried to promote myself as an open source guy, and certainly
not somebody that can go toe-to-toe on open-source issues like Miguel can. David contacted
me specifically to comment on some of Miguel's points, and that's what I tried to
do.
</p>
        <blockquote>
          <p>
Ted tried to refute my point about Java and innovation but seemed to have missed the
point. 
</p>
        </blockquote>
        <p>
Again, I don't think I can argue with that. Your point becomes more clear in your
blog entry, Miguel, and as you'll see in a second, I disagree with only part of the
point, and perhaps it's a semantic discussion that isn't one you (or anybody else)
wants to have, but seems important to note, at least in my mind. :-)
</p>
        <blockquote>
          <p>
The article attributed this to Ted: <i>"Microsoft has made an open-source CLI
implementation codenamed 'Rotor' freely available, but it has had little or no uptake".</i></p>
          <p>
There is a very simple reason for that. Rotor was not open source and it was doomed
to failure the moment it came out. When Microsoft released Rotor in 2002 or 2003 they
had no idea what they were doing and basically botched the whole effort by using a
proprietary license for Rotor. 
</p>
        </blockquote>
        <p>
And there we have it: "Rotor was not open source". This is the entire point
on which the disagreement (or lack thereof) hinges.
</p>
        <p>
Some time ago, on a panel, I mentioned that there are three kinds of common usage
when people use the term "open source". (I'm not arguing the 'proper' definition
here—I'm arguing the common lay usage, which may or may not actually be correct according
to those who define such things.) Those three definitions are:
</p>
        <ol>
          <li>
Free. ("I didn't have to pay for it!")</li>
          <li>
Source-available. ("I can build it!")</li>
          <li>
Accepting community contributions, and as a result, forkable. ("I can submit
patches!" or "I don't like the direction you're taking it, so I'm taking
the source and forking it and going in a different direction!")</li>
        </ol>
        <p>
Rotor fit the definitions of the first 2, though #1 usually implies an ability to
use it in a production environment, something the Shared Source license (the license
applying to Rotor at the time of its release) didn't permit in any way shape or form.
</p>
        <p>
And Miguel's exactly right—according to the #3 definition of the above, or <a href="http://www.opensource.org/docs/definition.php" target="_blank">the
linked definition he cites</a>, Rotor does not fit that. Period.
</p>
        <p>
Alas, it is to the detriment of our industry that people don't use terms according
to their actual definitions, but a looser, less precise, usage model. Not being an
"open-source guy", I fall into the trap of using the looser definition,
and that's what I was using when I read Miguel's point and made my counterpoint.
</p>
        <p>
As to the rest of Miguel's point, that Microsoft "botched" the release of
Rotor, I'm not sure that's the case—what I think was happening was a difference of
intent versus interpretation of that intent. I don't want to put words in Miguel's
mouth, so forgive me if I'm (again) not reading it right, but contrary to what Miguel
seems to believe, Microsoft never really intended Rotor as an "open source"
implementation in the sense that Mono was.
</p>
        <p>
Instead, Microsoft intended Rotor to be an implementation that universities and research
groups could use to hack on the CLR or build languages for the CLR, in an effort to
promote .NET and its usage among researchers and universities. Based on the discussions
I had with David Stutz during the <em>Shared Source CLI Essentials</em> writing, Microsoft
never really thought that Rotor would be all that interesting as an open-source "platform",
per se—hence the reason that the GC and JIT that appear in Rotor are "simplified"
and "not all that interesting" (David's words, as best I can remember them).
At the time, they felt that these (GC and JIT) would be areas that students and companies
would want to research around those areas, so a production-ready implementation of
either was really not necessary. 
</p>
        <p>
In other words, Microsoft saw Rotor as JikesRVM, not as Mono. And definitely not as
OpenJDK.
</p>
        <p>
Which gets us right back to Miguel's point, a spot-on analysis:
</p>
        <blockquote>
          <p>
Had Microsoft been an open company in 2001 and had embraced diversity we would live
in a different world. The awesome Mono team would probably be bigger, and the existing
team members would have longer vacations. 
</p>
        </blockquote>
        <p>
The Microsoft of 2001 was categorically and absolutely afraid of the open-source community.
In fact, I seem to recall David listing a litany of things he'd had to do to get Rotor
pushed out the door, even with the license it had. Had David not been as high up in
the organization as he was, we probably wouldn't have seen Rotor. And, I believe,
we wouldn't see Microsoft being where they are now...
</p>
        <blockquote>
          <p>
But for everyone that missed the point, luckily, Microsoft has new management, new
employees that know open source, fresh new ideas, is becoming more open and is working
actively on interoperability with third parties. They even launched the CodePlex Foundation. 
</p>
        </blockquote>
        <p>
... without it, because Rotor made it clear to the powers-that-be that even if they
turn loose the "keys to the kingdom" (as the CLR was thought to be, in some
quarters) out to the world, Microsoft doesn't go bankrupt. A steady yet slowly-emerging
"new Microsoft" is coming, one which is figuring out how to interact with
open source in ways that the "old Microsoft" could never consider. (Remember,
this is not IBM, a company that makes more money on services than on software sales—this
is a firm that makes its money principally from commercial software sales. Anybody
who thinks they've got that part of the open source market figured out should probably
run out and start a company, because that's a hell of a trick.)
</p>
        <p>
And lest it seem like I'm harshing a bit too much on Microsoft, let's take one of
Miguel's points and turn it over for a second:
</p>
        <blockquote>
          <p>
But my point about the ecosystem goes beyond the JVM, it is about the Java ecosystem
in general vs the .NET ecosystem. Java was able to capitalize on having implementations
on Linux and Unix, which accounts for more than half the web today. The Apache Foundation
is a big hub for Java-based development and it grew organically.
</p>
        </blockquote>
        <p>
All of which was good for <em>Java</em>.... but not necessarily for <em>Sun</em>,
who as most of you know, just recently got acquired by one of their former competitors.
We can moan and groan and complain about the slow pace Microsoft has been taking to
come to open source, particularly when compared to Sun's approach, but in the end,
one of these companies is still in business and listed on the NYSE, and the other
isn't.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=39927a30-8b67-4c6d-8656-c855f1ba008c" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Comments on the SDTimes article</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,39927a30-8b67-4c6d-8656-c855f1ba008c.aspx</guid>
      <link>http://blogs.tedneward.com/2010/03/27/Comments+On+The+SDTimes+Article.aspx</link>
      <pubDate>Sat, 27 Mar 2010 00:03:14 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://tirania.org/blog/archive/2010/Mar-25.html" target="_blank"&gt;Miguel
de Icaza wrote up a good response&lt;/a&gt; to the &lt;a href="http://74.125.93.132/search?q=cache:LPFDjfqGMRMJ:www.sdtimes.com/link/34203+Does+Windows+cost+Microsoft+opportunities&amp;amp;cd=1&amp;amp;hl=en&amp;amp;ct=clnk&amp;amp;gl=us" target="_blank"&gt;SDTimes
article&lt;/a&gt; in which both of us were quoted, and I thought it might serve to flesh
out the discussion a bit more to chime in with my part in the piece.
&lt;/p&gt;
&lt;p&gt;
First and foremost, Miguel notes:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
David quotes Ted Neward (a speaker on the .NET and Java circuits, but not an open
source guy by any stretch of the imagination). 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Amen to that—I have never tried to promote myself as an open source guy, and certainly
not somebody that can go toe-to-toe on open-source issues like Miguel can. David contacted
me specifically to comment on some of Miguel's points, and that's what I tried to
do.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Ted tried to refute my point about Java and innovation but seemed to have missed the
point. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Again, I don't think I can argue with that. Your point becomes more clear in your
blog entry, Miguel, and as you'll see in a second, I disagree with only part of the
point, and perhaps it's a semantic discussion that isn't one you (or anybody else)
wants to have, but seems important to note, at least in my mind. :-)
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
The article attributed this to Ted: &lt;i&gt;&amp;quot;Microsoft has made an open-source CLI
implementation codenamed 'Rotor' freely available, but it has had little or no uptake&amp;quot;.&lt;/i&gt;
&lt;/p&gt;
&lt;p&gt;
There is a very simple reason for that. Rotor was not open source and it was doomed
to failure the moment it came out. When Microsoft released Rotor in 2002 or 2003 they
had no idea what they were doing and basically botched the whole effort by using a
proprietary license for Rotor. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
And there we have it: &amp;quot;Rotor was not open source&amp;quot;. This is the entire point
on which the disagreement (or lack thereof) hinges.
&lt;/p&gt;
&lt;p&gt;
Some time ago, on a panel, I mentioned that there are three kinds of common usage
when people use the term &amp;quot;open source&amp;quot;. (I'm not arguing the 'proper' definition
here—I'm arguing the common lay usage, which may or may not actually be correct according
to those who define such things.) Those three definitions are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Free. (&amp;quot;I didn't have to pay for it!&amp;quot;)&lt;/li&gt;
&lt;li&gt;
Source-available. (&amp;quot;I can build it!&amp;quot;)&lt;/li&gt;
&lt;li&gt;
Accepting community contributions, and as a result, forkable. (&amp;quot;I can submit
patches!&amp;quot; or &amp;quot;I don't like the direction you're taking it, so I'm taking
the source and forking it and going in a different direction!&amp;quot;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Rotor fit the definitions of the first 2, though #1 usually implies an ability to
use it in a production environment, something the Shared Source license (the license
applying to Rotor at the time of its release) didn't permit in any way shape or form.
&lt;/p&gt;
&lt;p&gt;
And Miguel's exactly right—according to the #3 definition of the above, or &lt;a href="http://www.opensource.org/docs/definition.php" target="_blank"&gt;the
linked definition he cites&lt;/a&gt;, Rotor does not fit that. Period.
&lt;/p&gt;
&lt;p&gt;
Alas, it is to the detriment of our industry that people don't use terms according
to their actual definitions, but a looser, less precise, usage model. Not being an
&amp;quot;open-source guy&amp;quot;, I fall into the trap of using the looser definition,
and that's what I was using when I read Miguel's point and made my counterpoint.
&lt;/p&gt;
&lt;p&gt;
As to the rest of Miguel's point, that Microsoft &amp;quot;botched&amp;quot; the release of
Rotor, I'm not sure that's the case—what I think was happening was a difference of
intent versus interpretation of that intent. I don't want to put words in Miguel's
mouth, so forgive me if I'm (again) not reading it right, but contrary to what Miguel
seems to believe, Microsoft never really intended Rotor as an &amp;quot;open source&amp;quot;
implementation in the sense that Mono was.
&lt;/p&gt;
&lt;p&gt;
Instead, Microsoft intended Rotor to be an implementation that universities and research
groups could use to hack on the CLR or build languages for the CLR, in an effort to
promote .NET and its usage among researchers and universities. Based on the discussions
I had with David Stutz during the &lt;em&gt;Shared Source CLI Essentials&lt;/em&gt; writing, Microsoft
never really thought that Rotor would be all that interesting as an open-source &amp;quot;platform&amp;quot;,
per se—hence the reason that the GC and JIT that appear in Rotor are &amp;quot;simplified&amp;quot;
and &amp;quot;not all that interesting&amp;quot; (David's words, as best I can remember them).
At the time, they felt that these (GC and JIT) would be areas that students and companies
would want to research around those areas, so a production-ready implementation of
either was really not necessary. 
&lt;/p&gt;
&lt;p&gt;
In other words, Microsoft saw Rotor as JikesRVM, not as Mono. And definitely not as
OpenJDK.
&lt;/p&gt;
&lt;p&gt;
Which gets us right back to Miguel's point, a spot-on analysis:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Had Microsoft been an open company in 2001 and had embraced diversity we would live
in a different world. The awesome Mono team would probably be bigger, and the existing
team members would have longer vacations. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The Microsoft of 2001 was categorically and absolutely afraid of the open-source community.
In fact, I seem to recall David listing a litany of things he'd had to do to get Rotor
pushed out the door, even with the license it had. Had David not been as high up in
the organization as he was, we probably wouldn't have seen Rotor. And, I believe,
we wouldn't see Microsoft being where they are now...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
But for everyone that missed the point, luckily, Microsoft has new management, new
employees that know open source, fresh new ideas, is becoming more open and is working
actively on interoperability with third parties. They even launched the CodePlex Foundation. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
... without it, because Rotor made it clear to the powers-that-be that even if they
turn loose the &amp;quot;keys to the kingdom&amp;quot; (as the CLR was thought to be, in some
quarters) out to the world, Microsoft doesn't go bankrupt. A steady yet slowly-emerging
&amp;quot;new Microsoft&amp;quot; is coming, one which is figuring out how to interact with
open source in ways that the &amp;quot;old Microsoft&amp;quot; could never consider. (Remember,
this is not IBM, a company that makes more money on services than on software sales—this
is a firm that makes its money principally from commercial software sales. Anybody
who thinks they've got that part of the open source market figured out should probably
run out and start a company, because that's a hell of a trick.)
&lt;/p&gt;
&lt;p&gt;
And lest it seem like I'm harshing a bit too much on Microsoft, let's take one of
Miguel's points and turn it over for a second:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
But my point about the ecosystem goes beyond the JVM, it is about the Java ecosystem
in general vs the .NET ecosystem. Java was able to capitalize on having implementations
on Linux and Unix, which accounts for more than half the web today. The Apache Foundation
is a big hub for Java-based development and it grew organically.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
All of which was good for &lt;em&gt;Java&lt;/em&gt;.... but not necessarily for &lt;em&gt;Sun&lt;/em&gt;,
who as most of you know, just recently got acquired by one of their former competitors.
We can moan and groan and complain about the slow pace Microsoft has been taking to
come to open source, particularly when compared to Sun's approach, but in the end,
one of these companies is still in business and listed on the NYSE, and the other
isn't.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=39927a30-8b67-4c6d-8656-c855f1ba008c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,39927a30-8b67-4c6d-8656-c855f1ba008c.aspx</comments>
      <category>.NET</category>
      <category>Android</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>F#</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Mac OS</category>
      <category>Reading</category>
      <category>Visual Basic</category>
      <category>WCF</category>
      <category>Windows</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=809393d8-2dea-4ae3-a2fa-9e6aace6d16e</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,809393d8-2dea-4ae3-a2fa-9e6aace6d16e.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,809393d8-2dea-4ae3-a2fa-9e6aace6d16e.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=809393d8-2dea-4ae3-a2fa-9e6aace6d16e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Let's see if <a href="http://www.practicalecommerce.com/articles/1575-Chart-of-the-Week-Google-s-Android-Mobile-OS-Will-Outpace-the-iPhone-Others" target="_blank">this
one</a> holds: Gartner says that by 2012, Android will have a larger percentage of
the worldwide mobile phone market than the iPhone, 14.5 % against 13.7%.
</p>
        <p>
Reasons to doubt this particular bit of prescience? Gartner also predicts that "Windows
Mobile" will have "12.8 percent" of the market. This despite the fact
that at MIX last week, Microsoft basically canned Windows Mobile in favor of a complete
reboot called "Windows Phone Series 7" based on ideas from Silverlight and
XNA.
</p>
        <p>
Huh.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=809393d8-2dea-4ae3-a2fa-9e6aace6d16e" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Another Gartner prediction...</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,809393d8-2dea-4ae3-a2fa-9e6aace6d16e.aspx</guid>
      <link>http://blogs.tedneward.com/2010/03/24/Another+Gartner+Prediction.aspx</link>
      <pubDate>Wed, 24 Mar 2010 07:15:23 GMT</pubDate>
      <description>&lt;p&gt;
Let's see if &lt;a href="http://www.practicalecommerce.com/articles/1575-Chart-of-the-Week-Google-s-Android-Mobile-OS-Will-Outpace-the-iPhone-Others" target="_blank"&gt;this
one&lt;/a&gt; holds: Gartner says that by 2012, Android will have a larger percentage of
the worldwide mobile phone market than the iPhone, 14.5 % against 13.7%.
&lt;/p&gt;
&lt;p&gt;
Reasons to doubt this particular bit of prescience? Gartner also predicts that &amp;quot;Windows
Mobile&amp;quot; will have &amp;quot;12.8 percent&amp;quot; of the market. This despite the fact
that at MIX last week, Microsoft basically canned Windows Mobile in favor of a complete
reboot called &amp;quot;Windows Phone Series 7&amp;quot; based on ideas from Silverlight and
XNA.
&lt;/p&gt;
&lt;p&gt;
Huh.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=809393d8-2dea-4ae3-a2fa-9e6aace6d16e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,809393d8-2dea-4ae3-a2fa-9e6aace6d16e.aspx</comments>
      <category>.NET</category>
      <category>Android</category>
      <category>C#</category>
      <category>Industry</category>
      <category>iPhone</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Windows</category>
      <category>XNA</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=4b2137dd-11cc-4ad5-8771-5906f2759273</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,4b2137dd-11cc-4ad5-8771-5906f2759273.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,4b2137dd-11cc-4ad5-8771-5906f2759273.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=4b2137dd-11cc-4ad5-8771-5906f2759273</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Cruising the Web late last night, I ran across <a href="http://blogs.techrepublic.com.com/10things/?p=1297" target="_blank">"10
things you can do to advance your career as a developer"</a>, summarized below:
</p>
        <ol>
          <li>
Build a PC 
</li>
          <li>
Participate in an online forum and help others 
</li>
          <li>
Man the help desk 
</li>
          <li>
Perform field service 
</li>
          <li>
Perform DBA functions 
</li>
          <li>
Perform all phases of the project lifecycle 
</li>
          <li>
Recognize and learn the latest technologies 
</li>
          <li>
Be an independent contractor 
</li>
          <li>
Lead a project, supervise, or manage 
</li>
          <li>
Seek additional education 
</li>
        </ol>
        <p>
I agreed with some of them, I disagreed with others, and in general felt like they
were a little too high-level to be of real use. For example, "Seek additional
education" seems entirely too vague: In what? How much? How often? And "Recognize
and learn the latest technologies" is something like offering advice to the Olympic
fencing silver medalist and saying, "You should have tried harder".
</p>
        <p>
So, in the great spirit of "Not Invented Here", I present my own list; as
usual, I welcome comment and argument. And, also as usual, caveats apply, since not
everybody will be in precisely the same place and be looking for the same things.
In general, though, whether you're looking to kick-start your career or just "kick
it up a notch", I believe this list will help, because these ideas have been
of help to me at some point or another in my own career.
</p>
        <h3>
          <strong>
            <em>10: Build a PC.</em>
          </strong>
        </h3>
        <p>
Yes, even developers have to know about hardware. More importantly, a developer at
a small organization or team will find himself in a position where he has to take
on some system administrator roles, and sometimes that means grabbing a screwdriver,
getting a little dusty and dirty, and swapping hardware around. Having said this,
though, once you've done it once or twice, leave it alone—the hardware game is an
ever-shifting and ever-changing game (much like software is, surprise surprise), and
it's been my experience that most of us only really have the time to pursue one or
the other.
</p>
        <p>
By the way, "PC" there is something of a generic term—build a Linux box,
build a Windows box, or "build" a Mac OS box (meaning, buy a Mac Pro and
trick it out a little—add more memory, add another hard drive, and so on), they all
get you comfortable with snapping parts together, and discovering just how ridiculously
simple the whole thing really is.
</p>
        <p>
And for the record, once you've done it, go ahead and go back to buying pre-built
systems or laptops—I've never found building a PC to be any cheaper than buying one
pre-built. Particularly for PC systems, I prefer to use smaller local vendors where
I can customize and trick out the box. If you're a Mac, that's not really an option
unless you're into the "Hackintosh" thing, which is quite possibly the logical
equivalent to "Build a PC". Having never done it myself, though, I can't
say how useful that is as an educational action.
</p>
        <h3>
        </h3>
        <h3>
        </h3>
        <h3>
        </h3>
        <h3>
          <strong>
            <em>9: Pick a destination</em>
          </strong>
        </h3>
        <p>
Do you want to run a team of your own? Become an independent contractor? Teach programming
classes? Speak at conferences? Move up into higher management and get out of the programming
game altogether? Everybody's got a different idea of what they consider to be the
"ideal" career, but it's amazing how many people don't really think about
what they want their career path to be.
</p>
        <p>
A wise man once said, "The journey of a thousand miles begins with a single step."
I disagree: The journey of a thousand miles begins with the damn map. You have to
know where you want to go, and a rough idea of how to get there, before you can really
start with that single step. Otherwise, you're just wandering, which in itself isn't
a bad thing, but isn't going to get you to a destination except by random chance.
(Sometimes that's not a bad result, but at least then you're openly admitting that
you're leaving your career in the hands of chance. If you're OK with that, skip to
the next item. If you're not, read on.)
</p>
        <p>
Lay out explicitly (as in, write it down someplace) what kind of job you're wanting
to grow into, and then lay out a couple of scenarios that move you closer towards
that goal. Can you grow within the company you're in? (Have others been able to?)
Do you need to quit and strike out on your own? Do you want to lead a team of your
own? (Are there new projects coming in to the company that you could put yourself
forward as a potential tech lead?) And so on.
</p>
        <p>
Once you've identified the destination, now you can start thinking about steps to
get there. 
</p>
        <p>
If you want to become a speaker, put your name forward to give some presentations
at the local technology user group, or volunteer to hold a "brown bag" session
at the company. Sign up with Toastmasters to hone your speaking technique. Watch other
speakers give technical talks, and see what they do that you don't, and vice versa. 
</p>
        <p>
If you want to be a tech lead, start by quietly assisting other members of the team
get their work done. Help them debug thorny problems. Answer questions they have.
Offer yourself up as a resource for dealing with hard problems.
</p>
        <p>
If you want to slowly move up the management chain, look to get into the project management
side of things. Offer to be a point of contact for the users. Learn the business better.
Sit down next to one of your users and watch their interaction with the existing software,
and try to see the system from their point of view.
</p>
        <p>
And so on.
</p>
        <h3>
          <strong>
            <em>8: Be a bell curve</em>
          </strong>
        </h3>
        <p>
Frequently, at conferences, attendees ask me how I got to know so much on so many
things. In some ways, I'm reminded of the story of a world-famous concert pianist
giving a concert at Carnegie Hall—when a gushing fan said, "I'd give my life
to be able to play like that", the pianist responded quietly, "I did".
But as much as I'd like to leave you with the impression that I've dedicated my entire
life to knowing everything I could about this industry, that would be something of
a lie. The truth is, I don't know anywhere near as much as I'd like, and I'm always
poking my head into new areas. Thank God for my ADD, that's all I can say on that
one.
</p>
        <p>
For the rest of you, though, that's not feasible, and not really practical, particularly
since I have an advantage that the "working" programmer doesn't—I have set
aside weeks or months in which to do nothing more than study a new technology or language.
</p>
        <p>
Back in the early days of my career, though, when I was holding down the 9-to-5, I
was a Windows/C++ programmer. I was working with the Borland C++ compiler and its
associated framework, the ObjectWindows Library (OWL), extending and maintaining applications
written in it. One contracting client wanted me to work with Microsoft MFC instead
of OWL. Another one was storing data into a relational database using ODBC. And so
on. Slowly, over time, I built up a "bell curve"-looking collection of skills
that sort of "hovered" around the central position of C++/Windows.
</p>
        <p>
Then, one day, a buddy of mine mentioned the team on which he was a project manager
was looking for new blood. They were doing web applications, something with which
I had zero experience—this was completely outside of my bell curve. HTML, HTTP, Cold
Fusion, NetDynamics (an early Java app server), this was way out of my range, though
at least NetDynamics was a <em>little</em> similar, since it was basically a server-side
application framework, and I had some experience with app frameworks from my C++ days.
So, resting on my C++ experience, I started flirting with Java, and so on.
</p>
        <p>
Before long, my "bell curve" had been readjusted to have Java more or less
at its center, and I found that experience in C++ still worked out here—what I knew
about ODBC turned out to be incredibly useful in understanding JDBC, what I knew about
DLLs from Windows turned out to be helpful in understanding Java's dynamic loading
model, and of course syntactically Java looked a lot like C++ even though it behaved
a little bit differently under the hood. (One article author suggested that Java was
closer to Smalltalk than C++, and that prompted me to briefly flirt with Smalltalk
before I concluded said author was out of his frakking mind.)
</p>
        <p>
All of this happened over roughly a three-year period, by the way.
</p>
        <p>
The point here is that you won't be able to assimilate the entire industry in a single
sitting, so pick something that's relatively close to what you already know, and use
your experience as a springboard to learn something that's new, yet possibly-if-not-probably
useful to your current job. You don't have to be a deep expert in it, and the further
away it is from what you do, the less you really need to know about it (hence the
bell curve metaphor), but you're still exposing yourself to new ideas and new concepts
and new tools/technologies that still could be applicable to what you do on a daily
basis. Over time the "center" of your bell curve may drift away from what
you've done to include new things, and that's OK.
</p>
        <h3>
          <strong>
            <em>7: Learn one new thing every year</em>
          </strong>
        </h3>
        <p>
In the last tip, I told you to branch out slowly from what you know. In this tip,
I'm telling you to go throw a dart at something entirely unfamiliar to you and learn
it. Yes, I realize this sounds contradictory. It's because those who stick to only
what they know end up missing the radical shifts of direction that the industry hits
every half-decade or so until it's mainstream and commonplace and "everybody's
doing it".
</p>
        <p>
In their amazing book "The Pragmatic Programmer", Dave Thomas and Andy Hunt
suggest that you learn one new programming language every year. I'm going to amend
that somewhat—not because there aren't enough languages in the world to keep you on
that pace for the rest of your life—far from it, if that's what you want, go learn
Ruby, F#, Scala, Groovy, Clojure, Icon, Io, Erlang, Haskell and Smalltalk, then come
back to me for the list for 2020—but because languages aren't the only thing that
we as developers need to explore. There's a lot of movement going on in areas beyond
languages, and you don't want to be the last kid on the block to know they're happening.
</p>
        <p>
Consider this list: object databases (<a href="http://www.db4o.com" target="_blank">db4o</a>)
and/or the "NoSQL" movement (<a href="http://www.mongodb.org/display/DOCS/Tutorial" target="_blank">MongoDB</a>).
Dependency injection and composable architectures (<a href="http://www.springframework.org" target="_blank">Spring</a>, <a href="http://mef.codeplex.com" target="_blank">MEF</a>).
A dynamic language (<a href="http://www.rubyforge.org" target="_blank">Ruby</a>, <a href="http://www.python.org" target="_blank">Python</a>, <a href="http://www.ecmascript.org" target="_blank">ECMAScript</a>).
A functional language (<a href="http://msdn.microsoft.com/en-us/fsharp/default.aspx" target="_blank">F#</a>, <a href="http://www.scala-lang.org" target="_blank">Scala</a>, <a href="http://www.haskell.org" target="_blank">Haskell</a>).
A Lisp (Common Lisp, <a href="http://clojure.org" target="_blank">Clojure</a>, Scheme,
Nu). A mobile platform (iPhone, Android). "Space"-based architecture (<a href="http://www.gigaspaces.com" target="_blank">Gigaspaces</a>,
Terracotta). Rich UI platforms (Flash/Flex, Silverlight). Browser enhancements (AJAX,
jQuery, HTML 5) and how they're different from the rich UI platforms. And this is
without adding any of the "obvious" stuff, like Cloud, to the list.
</p>
        <p>
(I'm not convinced Cloud is something worth learning this year, anyway.)
</p>
        <p>
You get through that list, you're operating outside of your comfort zone, and chances
are, your boss' comfort zone, which puts you into the enviable position of being somebody
who can advise him around those technologies. <em>DO NOT TAKE THIS TO MEAN YOU MUST
KNOW THEM DEEPLY.</em> Just having a passing familiarity with them can be enough. <em>DO
NOT TAKE THIS TO MEAN YOU SHOULD PROPOSE USING THEM ON THE NEXT PROJECT.</em> In fact,
sometimes the most compelling evidence that you really know where and when they should
be used is when you suggest stealing ideas from the thing, rather than trying to force-fit
the thing onto the project as a whole.
</p>
        <h3>
          <strong>
            <em>6: Practice, practice, practice</em>
          </strong>
        </h3>
        <p>
Speaking of the concert pianist, somebody once asked him how to get to Carnegie Hall.
HIs answer: "Practice, my boy, practice."
</p>
        <p>
The same is true here. You're not going to get to be a better developer without practice.
Volunteer some time—even if it's just an hour a week—on an open-source project, or
start one of your own. Heck, it doesn't even have to be an "open source"
project—just create some requirements of your own, solve a problem that a family member
is having, or rewrite the project you're on as an interesting side-project. Do the
Nike thing and "Just do it". Write some Scala code. Write some F# code.
Once you're past "hello world", write the Scala code to use db4o as a persistent
storage. Wire it up behind Tapestry. Or write straight servlets in Scala. And so on.
</p>
        <h3>
          <strong>
            <em>5: Turn off the TV</em>
          </strong>
        </h3>
        <p>
Speaking of marketing slogans, if you're like most Americans, surveys have shown that
you watch about four hours of TV a day, or 28 hours of TV a week. In that same amount
of time (28 hours over 1 week), you could read the entire set of poems by Maya Angelou,
one F. Scott Fitzgerald novel, all poems by T.S.Eliot, 2 plays by Thornton Wilder,
or all 150 Psalms of the Bible. An average reader, reading just one hour a day, can
finish an "average-sized" book (let's assume about the size of a novel)
in a week, which translates to 52 books a year.
</p>
        <p>
Let's assume a technical book is going to take slightly longer, since it's a bit deeper
in concept and requires you to spend some time experimenting and typing in code; let's
assume that reading and going through the exercises of an average technical book will
require 4 weeks (a month) instead of just one week. That's 12 new tools/languages/frameworks/ideas
you'd be learning per year.
</p>
        <p>
All because you stopped watching David Caruso turn to the camera, whip his sunglasses
off and say something stupid. (I guess it's not his fault; <em>CSI:Miami</em> is a
crap show. The other two are actually not bad, but <em>Miami</em> just makes me retch.) 
</p>
        <p>
After all, when's the last time that David Caruso or the rest of that show did anything
that was even remotely realistic from a computer perspective? (I always laugh out
loud every time they run a database search against some national database on a completely
non-indexable criteria—like a partial license plate number—and it comes back in seconds.
What the hell database are THEY using? I want it!) Soon as you hear The Who break
into that riff, flip off the TV (or set it to mute) and pick up the book on the nightstand
and boost your career. (And hopefully sink Caruso's.)
</p>
        <p>
Or, if you just can't give up your weekly dose of Caruso, then put the book in the
bathroom. Think about it—how much time do you spend in there a week?
</p>
        <p>
And this gets even better when you get a Kindle or other e-reader that accepts PDFs,
or the book you're interested in is natively supported in the e-readers' format. Now
you have it with you for lunch, waiting at dinner for your food to arrive, or while
you're sitting guard on your 10-year-old so he doesn't sneak out of his room after
his bedtime to play more XBox.
</p>
        <h3>
          <strong>
            <em>4: Have a life</em>
          </strong>
        </h3>
        <p>
Speaking of XBox, don't slave your life to work. Pursue other things. Scientists have
repeatedly discovered that exercise helps keep the mind in shape, so take a couple
of hours a week (buh-bye, <em>American Idol</em>) and go get some exercise. Pick up
a new sport you've never played before, or just go work out at the gym. (This year
I'm doing Hopkido and fencing.) Read some nontechnical books. (I recommend anything
by Malcolm Gladwell as a starting point.) Spend time with your family, if you have
one—mine spends at least six or seven hours a week playing "family games"
like <a href="http://www.realitycheckgames.com/Products/127-the-settlers-of-catan.aspx" target="_blank">Settlers
of Catan</a>, <a href="http://www.realitycheckgames.com/Products/113-dominion.aspx" target="_blank">Dominion</a>, <a href="http://www.realitycheckgames.com/Products/88-to-court-the-king.aspx" target="_blank">To
Court The King</a>, <a href="http://www.realitycheckgames.com/Products/98-munchkin.aspx" target="_blank">Munchkin</a>,
and other non-traditional games, usually over lunch or dinner. I also belong to an
informal "Game Night club" in Redmond consisting of several Microsoft employees
and their families, as well as outsiders. And so on. Heck, go to a local bar and watch
the game, and you'll meet some really interesting people. And some boring people,
too, but you don't have to talk to them during the next game if you don't want.
</p>
        <p>
This isn't just about maintaining a healthy work-life balance—it's also about having
interests that other people can latch on to, qualities that will make you more "human"
and more interesting as a person, and make you more attractive and "connectable"
and stand out better in their mind when they hear that somebody they know is looking
for a software developer. This will also help you connect better with your users,
because like it or not, they do <em>not</em> get your puns involving Klingon. (Besides,
the geek stereotype is SO 90's, and it's time we let the world know that.)
</p>
        <p>
Besides, you never know when having some depth in other areas—philosophy, music, art,
physics, sports, whatever—will help you create an analogy that will explain some thorny
computer science concept to a non-technical person and get past a communication roadblock.
</p>
        <h3>
          <strong>
            <em>3: Practice on a cadaver</em>
          </strong>
        </h3>
        <p>
Long before they scrub up for their first surgery on a human, medical students practice
on dead bodies. It's grisly, it's not something we really want to think about, but
when you're the one going under the general anesthesia, would you rather see the surgeon
flipping through the "How-To" manual, "just to refresh himself"?
</p>
        <p>
Diagnosing and debugging a software system can be a hugely puzzling trial, largely
because there are so many possible "moving parts" that are creating the
problem. Compound that with certain bugs that only appear when multiple users are
interacting at the same time, and you've got a recipe for disaster when a production
bug suddenly threatens to jeopardize the company's online revenue stream. Do you really
want to be sitting in the production center, flipping through "How-To"'s
and FAQs online while your boss looks on and your CEO is counting every minute by
the thousands of dollars?
</p>
        <p>
Take a tip from the med student: long before the thing goes into production, introduce
a bug, deploy the code into a virtual machine, then hand it over to a buddy and let
him try to track it down. Have him do the same for you. Or if you can't find a buddy
to help you, do it to yourself (but try not to cheat or let your knowledge of where
the bug is color your reactions). How do you know the bug is there? Once you know
it's there, how do you determine what kind of bug it is? Where do you start looking
for it? How would you track it down without attaching a debugger or otherwise disrupting
the system's operations? (Remember, we can't always just attach an IDE and step through
the code on a production server.) How do you patch the running system? And so on.
</p>
        <p>
Remember, you can either learn these things under controlled circumstances, learn
them while you're in the "hot seat", so to speak, or not learn them at all
and see how long the company keeps you around.
</p>
        <h3>
          <strong>
            <em>2: Administer the system</em>
          </strong>
        </h3>
        <p>
Take off your developer hat for a while—a week, a month, a quarter, whatever—and be
one of those thankless folks who have to keep the system running. Wear the pager that
goes off at 3AM when a server goes down. Stay all night doing one of those "server
upgrades" that have to be done in the middle of the night because the system
can't be upgraded while users are using it. Answer the phones or chat requests of
those hapless users who can't figure out why they can't find the record they just
entered into the system, and after a half-hour of thinking it must be a bug, ask them
if they remembered to check the "Save this record" checkbox on the UI (which
had to be there because the developers were told it had to be there) before submitting
the form. Try adding a user. Try removing a user. Try changing the user's password.
Learn what a real joy having seven different properties/XML/configuration files scattered
all over the system really is.
</p>
        <p>
Once you've done that, particularly on a system that you built and tossed over the
fence into production and thought that was the end of it, you'll understand just why
it's so important to keep the system administrators in mind when you're building a
system for production. And why it's critical to be able to have a system that tells
you when it's down, instead of having to go hunting up the answer when a VP tells
you it is (usually because he's just gotten an outage message from a customer or client).
</p>
        <h3>
          <strong>
            <em>1: Cultivate a peer group</em>
          </strong>
        </h3>
        <p>
Yes, you can join an online forum, ask questions, answer questions, and learn that
way, but that's a poor substitute for physical human contact once in a while. Like
it or not, various sociological and psychological studies confirm that a "connection"
is really still best made when eyeballs meet flesh. (The "disassociative"
nature of email is what makes it so easy to be rude or flamboyant or downright violent
in email when we would never say such things in person.) Go to conferences, join a
user group, even start one of your own if you can't find one. Yes, the online avenues
are still open to you—read blogs, join mailing lists or newsgroups—but don't lose
sight of human-to-human contact.
</p>
        <p>
While we're at it, don't create a peer group of people that all look to you for answers—as
flattering as that feels, and as much as we do learn by providing answers, frequently
we rise (or fall) to the level of our peers—have at least one peer group that's overwhelmingly
smarter than you, and as scary as it might be, venture to offer an answer or two to
that group when a question comes up. You don't have to be right—in fact, it's often
vastly more educational to be wrong. Just maintain an attitude that says "I have
no ego wrapped up in being right or wrong", and take the entire experience as
a learning opportunity.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=4b2137dd-11cc-4ad5-8771-5906f2759273" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>10 Things To Improve Your Development Career</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,4b2137dd-11cc-4ad5-8771-5906f2759273.aspx</guid>
      <link>http://blogs.tedneward.com/2010/01/19/10+Things+To+Improve+Your+Development+Career.aspx</link>
      <pubDate>Tue, 19 Jan 2010 10:02:01 GMT</pubDate>
      <description>&lt;p&gt;
Cruising the Web late last night, I ran across &lt;a href="http://blogs.techrepublic.com.com/10things/?p=1297" target="_blank"&gt;&amp;quot;10
things you can do to advance your career as a developer&amp;quot;&lt;/a&gt;, summarized below:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Build a PC 
&lt;/li&gt;
&lt;li&gt;
Participate in an online forum and help others 
&lt;/li&gt;
&lt;li&gt;
Man the help desk 
&lt;/li&gt;
&lt;li&gt;
Perform field service 
&lt;/li&gt;
&lt;li&gt;
Perform DBA functions 
&lt;/li&gt;
&lt;li&gt;
Perform all phases of the project lifecycle 
&lt;/li&gt;
&lt;li&gt;
Recognize and learn the latest technologies 
&lt;/li&gt;
&lt;li&gt;
Be an independent contractor 
&lt;/li&gt;
&lt;li&gt;
Lead a project, supervise, or manage 
&lt;/li&gt;
&lt;li&gt;
Seek additional education 
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
I agreed with some of them, I disagreed with others, and in general felt like they
were a little too high-level to be of real use. For example, &amp;quot;Seek additional
education&amp;quot; seems entirely too vague: In what? How much? How often? And &amp;quot;Recognize
and learn the latest technologies&amp;quot; is something like offering advice to the Olympic
fencing silver medalist and saying, &amp;quot;You should have tried harder&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
So, in the great spirit of &amp;quot;Not Invented Here&amp;quot;, I present my own list; as
usual, I welcome comment and argument. And, also as usual, caveats apply, since not
everybody will be in precisely the same place and be looking for the same things.
In general, though, whether you're looking to kick-start your career or just &amp;quot;kick
it up a notch&amp;quot;, I believe this list will help, because these ideas have been
of help to me at some point or another in my own career.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;10: Build a PC.&lt;/em&gt;&lt;/strong&gt; 
&lt;/h3&gt;
&lt;p&gt;
Yes, even developers have to know about hardware. More importantly, a developer at
a small organization or team will find himself in a position where he has to take
on some system administrator roles, and sometimes that means grabbing a screwdriver,
getting a little dusty and dirty, and swapping hardware around. Having said this,
though, once you've done it once or twice, leave it alone—the hardware game is an
ever-shifting and ever-changing game (much like software is, surprise surprise), and
it's been my experience that most of us only really have the time to pursue one or
the other.
&lt;/p&gt;
&lt;p&gt;
By the way, &amp;quot;PC&amp;quot; there is something of a generic term—build a Linux box,
build a Windows box, or &amp;quot;build&amp;quot; a Mac OS box (meaning, buy a Mac Pro and
trick it out a little—add more memory, add another hard drive, and so on), they all
get you comfortable with snapping parts together, and discovering just how ridiculously
simple the whole thing really is.
&lt;/p&gt;
&lt;p&gt;
And for the record, once you've done it, go ahead and go back to buying pre-built
systems or laptops—I've never found building a PC to be any cheaper than buying one
pre-built. Particularly for PC systems, I prefer to use smaller local vendors where
I can customize and trick out the box. If you're a Mac, that's not really an option
unless you're into the &amp;quot;Hackintosh&amp;quot; thing, which is quite possibly the logical
equivalent to &amp;quot;Build a PC&amp;quot;. Having never done it myself, though, I can't
say how useful that is as an educational action.
&lt;/p&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;9: Pick a destination&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Do you want to run a team of your own? Become an independent contractor? Teach programming
classes? Speak at conferences? Move up into higher management and get out of the programming
game altogether? Everybody's got a different idea of what they consider to be the
&amp;quot;ideal&amp;quot; career, but it's amazing how many people don't really think about
what they want their career path to be.
&lt;/p&gt;
&lt;p&gt;
A wise man once said, &amp;quot;The journey of a thousand miles begins with a single step.&amp;quot;
I disagree: The journey of a thousand miles begins with the damn map. You have to
know where you want to go, and a rough idea of how to get there, before you can really
start with that single step. Otherwise, you're just wandering, which in itself isn't
a bad thing, but isn't going to get you to a destination except by random chance.
(Sometimes that's not a bad result, but at least then you're openly admitting that
you're leaving your career in the hands of chance. If you're OK with that, skip to
the next item. If you're not, read on.)
&lt;/p&gt;
&lt;p&gt;
Lay out explicitly (as in, write it down someplace) what kind of job you're wanting
to grow into, and then lay out a couple of scenarios that move you closer towards
that goal. Can you grow within the company you're in? (Have others been able to?)
Do you need to quit and strike out on your own? Do you want to lead a team of your
own? (Are there new projects coming in to the company that you could put yourself
forward as a potential tech lead?) And so on.
&lt;/p&gt;
&lt;p&gt;
Once you've identified the destination, now you can start thinking about steps to
get there. 
&lt;/p&gt;
&lt;p&gt;
If you want to become a speaker, put your name forward to give some presentations
at the local technology user group, or volunteer to hold a &amp;quot;brown bag&amp;quot; session
at the company. Sign up with Toastmasters to hone your speaking technique. Watch other
speakers give technical talks, and see what they do that you don't, and vice versa. 
&lt;/p&gt;
&lt;p&gt;
If you want to be a tech lead, start by quietly assisting other members of the team
get their work done. Help them debug thorny problems. Answer questions they have.
Offer yourself up as a resource for dealing with hard problems.
&lt;/p&gt;
&lt;p&gt;
If you want to slowly move up the management chain, look to get into the project management
side of things. Offer to be a point of contact for the users. Learn the business better.
Sit down next to one of your users and watch their interaction with the existing software,
and try to see the system from their point of view.
&lt;/p&gt;
&lt;p&gt;
And so on.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;8: Be a bell curve&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Frequently, at conferences, attendees ask me how I got to know so much on so many
things. In some ways, I'm reminded of the story of a world-famous concert pianist
giving a concert at Carnegie Hall—when a gushing fan said, &amp;quot;I'd give my life
to be able to play like that&amp;quot;, the pianist responded quietly, &amp;quot;I did&amp;quot;.
But as much as I'd like to leave you with the impression that I've dedicated my entire
life to knowing everything I could about this industry, that would be something of
a lie. The truth is, I don't know anywhere near as much as I'd like, and I'm always
poking my head into new areas. Thank God for my ADD, that's all I can say on that
one.
&lt;/p&gt;
&lt;p&gt;
For the rest of you, though, that's not feasible, and not really practical, particularly
since I have an advantage that the &amp;quot;working&amp;quot; programmer doesn't—I have set
aside weeks or months in which to do nothing more than study a new technology or language.
&lt;/p&gt;
&lt;p&gt;
Back in the early days of my career, though, when I was holding down the 9-to-5, I
was a Windows/C++ programmer. I was working with the Borland C++ compiler and its
associated framework, the ObjectWindows Library (OWL), extending and maintaining applications
written in it. One contracting client wanted me to work with Microsoft MFC instead
of OWL. Another one was storing data into a relational database using ODBC. And so
on. Slowly, over time, I built up a &amp;quot;bell curve&amp;quot;-looking collection of skills
that sort of &amp;quot;hovered&amp;quot; around the central position of C++/Windows.
&lt;/p&gt;
&lt;p&gt;
Then, one day, a buddy of mine mentioned the team on which he was a project manager
was looking for new blood. They were doing web applications, something with which
I had zero experience—this was completely outside of my bell curve. HTML, HTTP, Cold
Fusion, NetDynamics (an early Java app server), this was way out of my range, though
at least NetDynamics was a &lt;em&gt;little&lt;/em&gt; similar, since it was basically a server-side
application framework, and I had some experience with app frameworks from my C++ days.
So, resting on my C++ experience, I started flirting with Java, and so on.
&lt;/p&gt;
&lt;p&gt;
Before long, my &amp;quot;bell curve&amp;quot; had been readjusted to have Java more or less
at its center, and I found that experience in C++ still worked out here—what I knew
about ODBC turned out to be incredibly useful in understanding JDBC, what I knew about
DLLs from Windows turned out to be helpful in understanding Java's dynamic loading
model, and of course syntactically Java looked a lot like C++ even though it behaved
a little bit differently under the hood. (One article author suggested that Java was
closer to Smalltalk than C++, and that prompted me to briefly flirt with Smalltalk
before I concluded said author was out of his frakking mind.)
&lt;/p&gt;
&lt;p&gt;
All of this happened over roughly a three-year period, by the way.
&lt;/p&gt;
&lt;p&gt;
The point here is that you won't be able to assimilate the entire industry in a single
sitting, so pick something that's relatively close to what you already know, and use
your experience as a springboard to learn something that's new, yet possibly-if-not-probably
useful to your current job. You don't have to be a deep expert in it, and the further
away it is from what you do, the less you really need to know about it (hence the
bell curve metaphor), but you're still exposing yourself to new ideas and new concepts
and new tools/technologies that still could be applicable to what you do on a daily
basis. Over time the &amp;quot;center&amp;quot; of your bell curve may drift away from what
you've done to include new things, and that's OK.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;7: Learn one new thing every year&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
In the last tip, I told you to branch out slowly from what you know. In this tip,
I'm telling you to go throw a dart at something entirely unfamiliar to you and learn
it. Yes, I realize this sounds contradictory. It's because those who stick to only
what they know end up missing the radical shifts of direction that the industry hits
every half-decade or so until it's mainstream and commonplace and &amp;quot;everybody's
doing it&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
In their amazing book &amp;quot;The Pragmatic Programmer&amp;quot;, Dave Thomas and Andy Hunt
suggest that you learn one new programming language every year. I'm going to amend
that somewhat—not because there aren't enough languages in the world to keep you on
that pace for the rest of your life—far from it, if that's what you want, go learn
Ruby, F#, Scala, Groovy, Clojure, Icon, Io, Erlang, Haskell and Smalltalk, then come
back to me for the list for 2020—but because languages aren't the only thing that
we as developers need to explore. There's a lot of movement going on in areas beyond
languages, and you don't want to be the last kid on the block to know they're happening.
&lt;/p&gt;
&lt;p&gt;
Consider this list: object databases (&lt;a href="http://www.db4o.com" target="_blank"&gt;db4o&lt;/a&gt;)
and/or the &amp;quot;NoSQL&amp;quot; movement (&lt;a href="http://www.mongodb.org/display/DOCS/Tutorial" target="_blank"&gt;MongoDB&lt;/a&gt;).
Dependency injection and composable architectures (&lt;a href="http://www.springframework.org" target="_blank"&gt;Spring&lt;/a&gt;, &lt;a href="http://mef.codeplex.com" target="_blank"&gt;MEF&lt;/a&gt;).
A dynamic language (&lt;a href="http://www.rubyforge.org" target="_blank"&gt;Ruby&lt;/a&gt;, &lt;a href="http://www.python.org" target="_blank"&gt;Python&lt;/a&gt;, &lt;a href="http://www.ecmascript.org" target="_blank"&gt;ECMAScript&lt;/a&gt;).
A functional language (&lt;a href="http://msdn.microsoft.com/en-us/fsharp/default.aspx" target="_blank"&gt;F#&lt;/a&gt;, &lt;a href="http://www.scala-lang.org" target="_blank"&gt;Scala&lt;/a&gt;, &lt;a href="http://www.haskell.org" target="_blank"&gt;Haskell&lt;/a&gt;).
A Lisp (Common Lisp, &lt;a href="http://clojure.org" target="_blank"&gt;Clojure&lt;/a&gt;, Scheme,
Nu). A mobile platform (iPhone, Android). &amp;quot;Space&amp;quot;-based architecture (&lt;a href="http://www.gigaspaces.com" target="_blank"&gt;Gigaspaces&lt;/a&gt;,
Terracotta). Rich UI platforms (Flash/Flex, Silverlight). Browser enhancements (AJAX,
jQuery, HTML 5) and how they're different from the rich UI platforms. And this is
without adding any of the &amp;quot;obvious&amp;quot; stuff, like Cloud, to the list.
&lt;/p&gt;
&lt;p&gt;
(I'm not convinced Cloud is something worth learning this year, anyway.)
&lt;/p&gt;
&lt;p&gt;
You get through that list, you're operating outside of your comfort zone, and chances
are, your boss' comfort zone, which puts you into the enviable position of being somebody
who can advise him around those technologies. &lt;em&gt;DO NOT TAKE THIS TO MEAN YOU MUST
KNOW THEM DEEPLY.&lt;/em&gt; Just having a passing familiarity with them can be enough. &lt;em&gt;DO
NOT TAKE THIS TO MEAN YOU SHOULD PROPOSE USING THEM ON THE NEXT PROJECT.&lt;/em&gt; In fact,
sometimes the most compelling evidence that you really know where and when they should
be used is when you suggest stealing ideas from the thing, rather than trying to force-fit
the thing onto the project as a whole.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;6: Practice, practice, practice&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Speaking of the concert pianist, somebody once asked him how to get to Carnegie Hall.
HIs answer: &amp;quot;Practice, my boy, practice.&amp;quot;
&lt;/p&gt;
&lt;p&gt;
The same is true here. You're not going to get to be a better developer without practice.
Volunteer some time—even if it's just an hour a week—on an open-source project, or
start one of your own. Heck, it doesn't even have to be an &amp;quot;open source&amp;quot;
project—just create some requirements of your own, solve a problem that a family member
is having, or rewrite the project you're on as an interesting side-project. Do the
Nike thing and &amp;quot;Just do it&amp;quot;. Write some Scala code. Write some F# code.
Once you're past &amp;quot;hello world&amp;quot;, write the Scala code to use db4o as a persistent
storage. Wire it up behind Tapestry. Or write straight servlets in Scala. And so on.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;5: Turn off the TV&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Speaking of marketing slogans, if you're like most Americans, surveys have shown that
you watch about four hours of TV a day, or 28 hours of TV a week. In that same amount
of time (28 hours over 1 week), you could read the entire set of poems by Maya Angelou,
one F. Scott Fitzgerald novel, all poems by T.S.Eliot, 2 plays by Thornton Wilder,
or all 150 Psalms of the Bible. An average reader, reading just one hour a day, can
finish an &amp;quot;average-sized&amp;quot; book (let's assume about the size of a novel)
in a week, which translates to 52 books a year.
&lt;/p&gt;
&lt;p&gt;
Let's assume a technical book is going to take slightly longer, since it's a bit deeper
in concept and requires you to spend some time experimenting and typing in code; let's
assume that reading and going through the exercises of an average technical book will
require 4 weeks (a month) instead of just one week. That's 12 new tools/languages/frameworks/ideas
you'd be learning per year.
&lt;/p&gt;
&lt;p&gt;
All because you stopped watching David Caruso turn to the camera, whip his sunglasses
off and say something stupid. (I guess it's not his fault; &lt;em&gt;CSI:Miami&lt;/em&gt; is a
crap show. The other two are actually not bad, but &lt;em&gt;Miami&lt;/em&gt; just makes me retch.) 
&lt;/p&gt;
&lt;p&gt;
After all, when's the last time that David Caruso or the rest of that show did anything
that was even remotely realistic from a computer perspective? (I always laugh out
loud every time they run a database search against some national database on a completely
non-indexable criteria—like a partial license plate number—and it comes back in seconds.
What the hell database are THEY using? I want it!) Soon as you hear The Who break
into that riff, flip off the TV (or set it to mute) and pick up the book on the nightstand
and boost your career. (And hopefully sink Caruso's.)
&lt;/p&gt;
&lt;p&gt;
Or, if you just can't give up your weekly dose of Caruso, then put the book in the
bathroom. Think about it—how much time do you spend in there a week?
&lt;/p&gt;
&lt;p&gt;
And this gets even better when you get a Kindle or other e-reader that accepts PDFs,
or the book you're interested in is natively supported in the e-readers' format. Now
you have it with you for lunch, waiting at dinner for your food to arrive, or while
you're sitting guard on your 10-year-old so he doesn't sneak out of his room after
his bedtime to play more XBox.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;4: Have a life&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Speaking of XBox, don't slave your life to work. Pursue other things. Scientists have
repeatedly discovered that exercise helps keep the mind in shape, so take a couple
of hours a week (buh-bye, &lt;em&gt;American Idol&lt;/em&gt;) and go get some exercise. Pick up
a new sport you've never played before, or just go work out at the gym. (This year
I'm doing Hopkido and fencing.) Read some nontechnical books. (I recommend anything
by Malcolm Gladwell as a starting point.) Spend time with your family, if you have
one—mine spends at least six or seven hours a week playing &amp;quot;family games&amp;quot;
like &lt;a href="http://www.realitycheckgames.com/Products/127-the-settlers-of-catan.aspx" target="_blank"&gt;Settlers
of Catan&lt;/a&gt;, &lt;a href="http://www.realitycheckgames.com/Products/113-dominion.aspx" target="_blank"&gt;Dominion&lt;/a&gt;, &lt;a href="http://www.realitycheckgames.com/Products/88-to-court-the-king.aspx" target="_blank"&gt;To
Court The King&lt;/a&gt;, &lt;a href="http://www.realitycheckgames.com/Products/98-munchkin.aspx" target="_blank"&gt;Munchkin&lt;/a&gt;,
and other non-traditional games, usually over lunch or dinner. I also belong to an
informal &amp;quot;Game Night club&amp;quot; in Redmond consisting of several Microsoft employees
and their families, as well as outsiders. And so on. Heck, go to a local bar and watch
the game, and you'll meet some really interesting people. And some boring people,
too, but you don't have to talk to them during the next game if you don't want.
&lt;/p&gt;
&lt;p&gt;
This isn't just about maintaining a healthy work-life balance—it's also about having
interests that other people can latch on to, qualities that will make you more &amp;quot;human&amp;quot;
and more interesting as a person, and make you more attractive and &amp;quot;connectable&amp;quot;
and stand out better in their mind when they hear that somebody they know is looking
for a software developer. This will also help you connect better with your users,
because like it or not, they do &lt;em&gt;not&lt;/em&gt; get your puns involving Klingon. (Besides,
the geek stereotype is SO 90's, and it's time we let the world know that.)
&lt;/p&gt;
&lt;p&gt;
Besides, you never know when having some depth in other areas—philosophy, music, art,
physics, sports, whatever—will help you create an analogy that will explain some thorny
computer science concept to a non-technical person and get past a communication roadblock.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;3: Practice on a cadaver&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Long before they scrub up for their first surgery on a human, medical students practice
on dead bodies. It's grisly, it's not something we really want to think about, but
when you're the one going under the general anesthesia, would you rather see the surgeon
flipping through the &amp;quot;How-To&amp;quot; manual, &amp;quot;just to refresh himself&amp;quot;?
&lt;/p&gt;
&lt;p&gt;
Diagnosing and debugging a software system can be a hugely puzzling trial, largely
because there are so many possible &amp;quot;moving parts&amp;quot; that are creating the
problem. Compound that with certain bugs that only appear when multiple users are
interacting at the same time, and you've got a recipe for disaster when a production
bug suddenly threatens to jeopardize the company's online revenue stream. Do you really
want to be sitting in the production center, flipping through &amp;quot;How-To&amp;quot;'s
and FAQs online while your boss looks on and your CEO is counting every minute by
the thousands of dollars?
&lt;/p&gt;
&lt;p&gt;
Take a tip from the med student: long before the thing goes into production, introduce
a bug, deploy the code into a virtual machine, then hand it over to a buddy and let
him try to track it down. Have him do the same for you. Or if you can't find a buddy
to help you, do it to yourself (but try not to cheat or let your knowledge of where
the bug is color your reactions). How do you know the bug is there? Once you know
it's there, how do you determine what kind of bug it is? Where do you start looking
for it? How would you track it down without attaching a debugger or otherwise disrupting
the system's operations? (Remember, we can't always just attach an IDE and step through
the code on a production server.) How do you patch the running system? And so on.
&lt;/p&gt;
&lt;p&gt;
Remember, you can either learn these things under controlled circumstances, learn
them while you're in the &amp;quot;hot seat&amp;quot;, so to speak, or not learn them at all
and see how long the company keeps you around.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;2: Administer the system&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Take off your developer hat for a while—a week, a month, a quarter, whatever—and be
one of those thankless folks who have to keep the system running. Wear the pager that
goes off at 3AM when a server goes down. Stay all night doing one of those &amp;quot;server
upgrades&amp;quot; that have to be done in the middle of the night because the system
can't be upgraded while users are using it. Answer the phones or chat requests of
those hapless users who can't figure out why they can't find the record they just
entered into the system, and after a half-hour of thinking it must be a bug, ask them
if they remembered to check the &amp;quot;Save this record&amp;quot; checkbox on the UI (which
had to be there because the developers were told it had to be there) before submitting
the form. Try adding a user. Try removing a user. Try changing the user's password.
Learn what a real joy having seven different properties/XML/configuration files scattered
all over the system really is.
&lt;/p&gt;
&lt;p&gt;
Once you've done that, particularly on a system that you built and tossed over the
fence into production and thought that was the end of it, you'll understand just why
it's so important to keep the system administrators in mind when you're building a
system for production. And why it's critical to be able to have a system that tells
you when it's down, instead of having to go hunting up the answer when a VP tells
you it is (usually because he's just gotten an outage message from a customer or client).
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;&lt;em&gt;1: Cultivate a peer group&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Yes, you can join an online forum, ask questions, answer questions, and learn that
way, but that's a poor substitute for physical human contact once in a while. Like
it or not, various sociological and psychological studies confirm that a &amp;quot;connection&amp;quot;
is really still best made when eyeballs meet flesh. (The &amp;quot;disassociative&amp;quot;
nature of email is what makes it so easy to be rude or flamboyant or downright violent
in email when we would never say such things in person.) Go to conferences, join a
user group, even start one of your own if you can't find one. Yes, the online avenues
are still open to you—read blogs, join mailing lists or newsgroups—but don't lose
sight of human-to-human contact.
&lt;/p&gt;
&lt;p&gt;
While we're at it, don't create a peer group of people that all look to you for answers—as
flattering as that feels, and as much as we do learn by providing answers, frequently
we rise (or fall) to the level of our peers—have at least one peer group that's overwhelmingly
smarter than you, and as scary as it might be, venture to offer an answer or two to
that group when a question comes up. You don't have to be right—in fact, it's often
vastly more educational to be wrong. Just maintain an attitude that says &amp;quot;I have
no ego wrapped up in being right or wrong&amp;quot;, and take the entire experience as
a learning opportunity.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=4b2137dd-11cc-4ad5-8771-5906f2759273" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,4b2137dd-11cc-4ad5-8771-5906f2759273.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Security</category>
      <category>Social</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>VMWare</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=c95a7acd-a467-4c8e-a72a-2b8d3acee495</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,c95a7acd-a467-4c8e-a72a-2b8d3acee495.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,c95a7acd-a467-4c8e-a72a-2b8d3acee495.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c95a7acd-a467-4c8e-a72a-2b8d3acee495</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm excited to say that TechEd has accepted my pre-conference proposal, <em>Multiparadigmatic
C#</em>, where the abstract reads:
</p>
        <blockquote>
          <p>
C# has grown from “just” an object-oriented language into a language that is capable
of expressing several different paradigms of software development: object-oriented,
functional, and dynamic. In this session, developers will learn how to approach programming
in C# to use each of these approaches, and when.
</p>
        </blockquote>
        <p>
If you're interested in seeing C# used in a variety of different ways, come on out.
</p>
        <p>
And if you're not going to <a href="http://northamerica.msteched.com/?CR_CC=100280254&amp;WT.srch=1&amp;CR_SCC=100280254&amp;fbid=xvt_cg-ExsG" target="_blank">TechEd</a>....
why not? It's in New Orleans, folks!
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=c95a7acd-a467-4c8e-a72a-2b8d3acee495" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>2010 TechEd PreCon: Multiparadigmatic C#</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,c95a7acd-a467-4c8e-a72a-2b8d3acee495.aspx</guid>
      <link>http://blogs.tedneward.com/2010/01/15/2010+TechEd+PreCon+Multiparadigmatic+C.aspx</link>
      <pubDate>Fri, 15 Jan 2010 07:49:53 GMT</pubDate>
      <description>&lt;p&gt;
I'm excited to say that TechEd has accepted my pre-conference proposal, &lt;em&gt;Multiparadigmatic
C#&lt;/em&gt;, where the abstract reads:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
C# has grown from “just” an object-oriented language into a language that is capable
of expressing several different paradigms of software development: object-oriented,
functional, and dynamic. In this session, developers will learn how to approach programming
in C# to use each of these approaches, and when.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
If you're interested in seeing C# used in a variety of different ways, come on out.
&lt;/p&gt;
&lt;p&gt;
And if you're not going to &lt;a href="http://northamerica.msteched.com/?CR_CC=100280254&amp;amp;WT.srch=1&amp;amp;CR_SCC=100280254&amp;amp;fbid=xvt_cg-ExsG" target="_blank"&gt;TechEd&lt;/a&gt;....
why not? It's in New Orleans, folks!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=c95a7acd-a467-4c8e-a72a-2b8d3acee495" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,c95a7acd-a467-4c8e-a72a-2b8d3acee495.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>F#</category>
      <category>Industry</category>
      <category>Languages</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Visual Basic</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=680b8296-ba07-4230-b067-edceaf04e84b</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,680b8296-ba07-4230-b067-edceaf04e84b.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,680b8296-ba07-4230-b067-edceaf04e84b.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=680b8296-ba07-4230-b067-edceaf04e84b</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here we go again—another year, another set of predictions revisited and offered up
for the next 12 months. And maybe, if I'm feeling really ambitious, I'll take that
shot I thought about last year and try predicting for the decade. Without further
ado, I'll go back and revisit, unedited, my predictions for 2009 ("<strong>THEN</strong>"),
and pontificate on those subjects for 2010 before adding any new material/topics.
Just for convenience, <a href="http://blogs.tedneward.com/2009/01/01/2009+Predictions+2008+Predictions+Revisited.aspx" target="_blank">here's
a link back to last years' predictions</a>.
</p>
        <p>
Last year's predictions went something like this (complete with basketball-scoring):
</p>
        <ul>
          <li>
            <strong>THEN: </strong>"Cloud" will become the next "ESB" or "SOA",
in that it will be something that everybody will talk about, but few will understand
and even fewer will do anything with. (Considering the widespread disparity in the
definition of the term, this seems like a no-brainer.) <strong>NOW:</strong> Oh, yeah.
Straight up. I get two points for this one. Does <em>anyone</em> have a working definition
of "cloud" that applies to all of the major vendors' implementations? <em>Ted,
2; Wrongness, 0</em>.</li>
          <li>
            <strong>THEN: </strong>Interest in Scala will continue to rise, as will the number
of detractors who point out that Scala is too hard to learn. <strong>NOW:</strong> Two
points for this one, too. Not a hard one, mind you, but one of those "pass-and-shoot"
jumpers from twelve feet out. James Strachan even tweeted about this earlier today,
pointing out this comparison. As more Java developers who think of themselves as smart
people try to pick up Scala and fail, the numbers of sour grapes responses like "Scala's
too complex, and who needs that functional stuff anyway?" will continue to rise
in 2010. <em>Ted, 4; Wrongness, 0</em>.</li>
          <li>
            <strong>THEN</strong>: Interest in F# will continue to rise, as will the number of
detractors who point out that F# is too hard to learn. (Hey, the two really are cousins,
and the fortunes of one will serve as a pretty good indication of the fortunes of
the other, and both really seem to be on the same arc right now.) <strong>NOW:</strong> Interestingly
enough, I haven't heard as many F# detractors as Scala detractors, possibly because
I think F# hasn't really reached the masses of .NET developers the way that Scala
has managed to find its way in front of Java developers. I think that'll change mighty
quickly in 2010, though, once VS 2010 hits the streets. <em>Ted, 4; Wrongness 2</em>.</li>
          <li>
            <strong>THEN</strong>
            <em>:</em> Interest in all kinds of functional languages will
continue to rise, and more than one person will take a hint from Bob "crazybob"
Lee and liken functional programming to AOP, for good and for ill. People who took
classes on Haskell in college will find themselves reaching for their old college
textbooks again. <strong>NOW:</strong> Yep, I'm claiming two points on this one, if
only because a bunch of Haskell books shipped this year, and they'll be the last to
do so for about five years after this. (By the way, does anybody still remember aspects?)
But I'm going the opposite way with this one now; yes, there's Haskell, and yes, there's
Erlang, and yes, there's a lot of other functional languages out there, but who cares?
They're hard to learn, they don't always translate well to other languages, and developers
want languages that work on the platform they use on a daily basis, and that means
F# and Scala or Clojure, or its simply not an option. <em>Ted 6; Wrongness 2</em>.</li>
          <li>
            <strong>THEN</strong>
            <em>:</em> The iPhone is going to be hailed as "the enterprise
development platform of the future", and companies will be rolling out apps to
it. Look for Quicken iPhone edition, PowerPoint and/or Keynote iPhone edition, along
with connectors to hook the iPhone up to a presentation device, and (I'll bet) a World
of Warcraft iPhone client (legit or otherwise). iPhone is the new hotness in the mobile
space, and people will flock to it madly. <strong>NOW:</strong> Two more points, but
let's be honest—this was a fast-break layup, no work required on my part. <em>Ted
8; Wrongness 2.</em></li>
          <li>
            <strong>THEN</strong>: Another Oslo CTP will come out, and it will bear only a superficial
resemblance to the one that came out in October at PDC. Betting on Oslo right now
is a fools' bet, not because of any inherent weakness in the technology, but just
because it's way too early in the cycle to be thinking about for anything vaguely
resembling production code. <strong>NOW:</strong> If you've worked at all with Oslo,
you might argue with me, but I'm still taking my two points. The two CTPs were pretty
different in a number of ways. <em>Ted 10; Wrongness 2.</em></li>
          <li>
            <strong>THEN</strong>: The IronPython and IronRuby teams will find some serious versioning
issues as they try to manage the DLR versioning story between themselves and the CLR
as a whole. An initial hack will result, which will be codified into a standard practice
when .NET 4.0 ships. Then the next release of IPy or IRb will have to try and slip
around its restrictions in 2010/2011. By 2012, IPy and IRb will have to be shipping
as part of Visual Studio just to put the releases back into lockstep with one another
(and the rest of the .NET universe). <strong>NOW:</strong> Pressure is still building.
Let's see what happens by the time VS 2010 ships, and then see what the IPy/IRb teams
start to do to adjust to the versioning issues that arise. <em>Ted 8; Wrongness 2.</em></li>
          <li>
            <strong>THEN</strong>: The death of JSR-277 will spark an uprising among the two leading
groups hoping to foist it off on the Java community--OSGi and Maven--while the rest
of the Java world will breathe a huge sigh of relief and look to see what "modularity"
means in Java 7. Some of the alpha geeks in Java will start using--if not building--JDK
7 builds just to get a heads-up on its impact, and be quietly surprised and, I dare
say, perhaps even pleased. <strong>NOW:</strong> Ah, Ted, you really should never
underestimate the community's willingness to take a bad idea, strip all the goodness
out of it, and then cycle it back into the mix as something completely different yet
somehow just as dangerous and crazy. I give you Project Jigsaw. <em>Ted 10; Wrongness
2;</em></li>
          <li>
            <strong>THEN</strong>: The invokedynamic JSR will leapfrog in importance to the top
of the list. <strong>NOW:</strong> The invokedynamic JSR begat interest in other languages
on the JVM. The interest in other languages on the JVM begat the need to start thinking
about how to support them in the Java libraries. The need to start thinking about
supporting those languages begat a "Holy sh*t moment" somewhere inside Sun
and led them to (re-)propose closures for JDK 7. And in local sports news, Ted notched
up two more points on the scoreboard. <em>Ted 12; Wrongness 2.</em></li>
          <li>
            <strong>THEN</strong>: Another Windows 7 CTP will come out, and it will spawn huge
media interest that will eventually be remembered as Microsoft promises, that will
eventually be remembered as Microsoft guarantees, that will eventually be remembered
as Microsoft FUD and "promising much, delivering little". Microsoft ain't
always at fault for the inflated expectations people have--sometimes, yes, perhaps
even a lot of times, but not always. <strong>NOW:</strong> And then, just when the
game started to turn into a runaway, airballs started to fly. The Windows7 release
shipped, and contrary to what I expected, the general response to it was pretty warm.
Yes, there were a few issues that emerged, but overall the media liked it, the masses
liked it, and Microsoft seemed to have dodged a bullet. <em>Ted 12; Wrongness 5.</em></li>
          <li>
            <strong>THEN</strong>: Apple will begin to legally threaten the clone market again,
except this time somebody's going to get the DOJ involved. (Yes, this is the iPhone/iTunes
prediction from last year, carrying over. I still expect this to happen.) <strong>NOW:</strong> What
clones? The only people trying to clone Macs are those who are building Hackintosh
machines, and Apple can't sue them so long as they're using licensed copies of Mac
OS X (as far as I know). Which has never stopped them from trying, mind you, and I
still think Steve has some part of his brain whispering to him at night, calculating
all the hardware sales lost to Hackintosh netbooks out there. But in any event, that's
another shot missed. <em>Ted 12; Wrongness 7.</em></li>
          <li>
            <strong>THEN</strong>: Alpha-geek developers will start creating their own languages
(even if they're obscure or bizarre ones like Shakespeare or Ook#) just to have that
listed on their resume as the DSL/custom language buzz continues to build. <strong>NOW:</strong> I
give you Ioke. If I'd extended this to include outdated CPU interpreters, I'd have
made that three-pointer from half-court instead of just the top of the key. <em>Ted
14; Wrongness 7.</em></li>
          <li>
            <strong>THEN</strong>: Roy Fielding will officially disown most of the "REST"ful
authors and software packages available. Nobody will care--or worse, somebody looking
to make a name for themselves will proclaim that Roy "doesn't really understand
REST". And they'll be right--Roy doesn't understand what <em>they</em> consider
to be REST, and the fact that he created the term will be of no importance anymore.
Being "REST"ful will equate to "I did it myself!", complete with
expectations of a gold star and a lollipop. <strong>NOW:</strong> Does anybody in
the REST community care what Roy Fielding wrote way back when? I keep seeing "REST"ful
systems that seem to have designers who've never heard of Roy, or his thesis. Roy
hasn't officially disowned them, but damn if he doesn't seem close to it. Still....
No points. <em>Ted 14; Wrongness 9.</em></li>
          <li>
            <strong>THEN</strong>: The Parrot guys will make at least one more minor point release.
Nobody will notice or care, except for a few doggedly stubborn Perl hackers. They
will find themselves having nightmares of previous lives carrying around OS/2 books
and Amiga paraphernalia. Perl 6 will celebrate it's seventh... or is it eighth?...
anniversary of being announced, and nobody will notice. <strong>NOW:</strong> Does
anybody still follow Perl 6 development? Has the spec even been written yet? Google
on "Perl 6 release", and you get varying reports: "It'll ship 'when
it's ready'", "There are no such dates because this isn't a commericially-backed
effort", and "Spring 2010". Swish—nothin' but net. <em>Ted 16; Wrongness
9.</em></li>
          <li>
            <strong>THEN</strong>: The debate around "Scrum Certification" will rise
to a fever pitch as short-sighted money-tight companies start looking for reasons
to cut costs and either buy into agile at a superficial level and watch it fail, or
start looking to cut the agilists from their company in order to replace them with
cheaper labor. <strong>NOW:</strong> Agile has become another adjective meaning "best
practices", and as such, has essentially lost its meaning. Just ask Scott Bellware. <em>Ted
18; Wrongness 9.</em></li>
          <li>
            <strong>THEN</strong>: Adobe will continue to make Flex and AIR look more like C#
and the CLR even as Microsoft tries to make Silverlight look more like Flash and AIR.
Web designers will now get to experience the same fun that back-end web developers
have enjoyed for near-on a decade, as shops begin to artificially partition themselves
up as either "Flash" shops or "Silverlight" shops. <strong>NOW:</strong> Not
sure how to score this one—I haven't seen the explicit partitioning happen yet, but
the two environments definitely still seem to be looking to start tromping on each
others' turf, particularly when we look at the rapid releases coming from the Silverlight
team. <em>Ted 16; Wrongness 11.</em></li>
          <li>
            <strong>THEN</strong>: Gartner will still come knocking, looking to hire me for outrageous
sums of money to do nothing but blog and wax prophetic. <strong>NOW:</strong> Still
no job offers. Damn. Ah, well. <em>Ted 16; Wrongness 13.</em></li>
        </ul>
        <p>
A close game. Could've gone either way. *shrug* Ah, well. It was silly to try and
score it in basketball metaphor, anyway—that's the last time I watch ESPN before writing
this.
</p>
        <p>
For 2010, I predict....
</p>
        <ul>
          <li>
            <em>... I will offer 3- and 4-day training classes on F# and Scala, among other things.</em> OK,
that's not fair—yes, I have the materials, I just need to work out locations and times.
Contact me if you're interested in a private class, by the way.</li>
          <li>
            <em>... I will publish two books, one on F# and one on Scala.</em> OK, OK, another
plug. Or, rather, more of a resolution. One will be the "Professional F#"
I'm doing for Wiley/Wrox, the other isn't yet finalized. But it'll either be published
through a publisher, or self-published, by JavaOne 2010.</li>
          <li>
            <em>... DSLs will either "succeed" this year, or begin the short slide into
the dustbin of obscure programming ideas.</em> Domain-specific language advocates
have to put up some kind of strawman for developers to learn from and poke at, or
the whole concept will just fade away. Martin's book will help, if it ships this year,
but even that might not be enough to generate interest if it doesn't have some kind
of large-scale applicability in it. Patterns and refactoring and enterprise containers
all had a huge advantage in that developers could see pretty easily what the problem
was they solved; DSLs haven't made that clear yet.</li>
          <li>
            <em>... functional languages will start to see a backlash.</em> I hate to say it,
but "getting" the functional mindset is hard, and there's precious few resources
that are making it easy for mainstream (read: O-O) developers make that adjustment,
far fewer than there was during the procedural-to-object shift. If the functional
community doesn't want to become mainstream, then mainstream developers will find
ways to take functional's most compelling gateway use-case (parallel/concurrent programming)
and find a way to "git 'er done" in the traditional O-O approach, probably
through software transactional memory, and functional languages like Haskell and Erlang
will be relegated to the "What Might Have Been" of computer science history.
Not sure what I mean? Try this: walk into a functional language forum, and ask what
a monad is. Nobody yet has been able to produce an answer that doesn't involve math
theory, or that does involve a practical domain-object-based example. In fact, nobody
has really said why (or if) monads are even still useful. Or catamorphisms. Or any
of the other dime-store words that the functional community likes to toss around.</li>
          <li>
            <em>... Visual Studio 2010 will ship on time, and be one of the buggiest and/or slowest
releases in its history.</em> I hate to make this prediction, because I really don't
want to be right, but there's just so much happening in the Visual Studio refactoring
effort that it makes me incredibly nervous. Widespread adoption of VS2010 will wait
until SP1 at the earliest. In fact....</li>
          <li>
            <em>... Visual Studio 2010 SP 1 will ship within three months of the final product.</em> Microsoft
knows that people wait until SP 1 to think about upgrading, so they'll just plan for
an eager SP 1 release, and hope that managers will be too hung over from the New Year
(still) to notice that the necessary shakeout time hasn't happened.</li>
          <li>
            <em>... Apple will ship a tablet with multi-touch on it, and it will flop horribly.</em> Not
sure why I think this, but I just don't think the multi-touch paradigm that Apple
has cooked up for the iPhone will carry over to a tablet/laptop device. That won't
stop them from shipping it, and it won't stop Apple fan-boiz from buying it, but that's
about where the interest will end.</li>
          <li>
            <em>... JDK 7 closures will be debated for a few weeks, then become a fait accompli
as the Java community shrugs its collective shoulders.</em> Frankly, I think the Java
community has exhausted its interest in debating new language features for Java. Recent
college grads and open-source groups with an axe to grind will continue to try and
make an issue out of this, but I think the overall Java community just... doesn't...
care. They just want to see JDK 7 ship someday.</li>
          <li>
            <em>... Scala either "pops" in 2010, or begins to fall apart.</em> By "pops",
I mean reaches a critical mass of developers interested in using it, enough to convince
somebody to create a company around it, a la G2One.</li>
          <li>
            <em>... Oracle is going to make a serious "cloud" play, probably by offering
an Oracle-hosted version of Azure or AppEngine.</em> Oracle loves the enterprise space
too much, and derives too much money from it, to not at least appear to have some
kind of offering here. Now that they own Java, they'll marry it up against OpenSolaris,
the Oracle database, and throw the whole thing into a series of server centers all
over the continent, and call it "Oracle 12c" (c for Cloud, of course) or
something.</li>
          <li>
            <em>... Spring development will slow to a crawl and start to take a left turn toward
cloud ideas.</em> VMWare bought SpringSource for a reason, and I believe it's entirely
centered around VMWare's movement into the cloud space—they want to be more than "just"
a virtualization tool. Spring + Groovy makes a compelling development stack, particularly
if VMWare does some interesting hooks-n-hacks to make Spring a virtualization environment
in its own right somehow. But from a practical perspective, any community-driven development
against Spring is all but basically dead. The source may be downloadable later, like
the VMWare Player code is, but making contributions back? Fuhgeddabowdit.</li>
          <li>
            <em>... the explosion of e-book readers brings the Kindle 2009 edition way down to
size.</em> The era of the e-book reader is here, and honestly, while I'm glad I have
a Kindle, I'm expecting that I'll be dusting it off a shelf in a few years. Kinda
like I do with my iPods from a few years ago.</li>
          <li>
            <em>... "social networking" becomes the "Web 2.0" of 2010.</em> In
other words, using the term will basically identify you as a tech wannabe and clearly
out of touch with the bleeding edge.</li>
          <li>
            <em>... Facebook becomes a developer platform requirement.</em> I don't pretend to
know anything about Facebook—I'm not even on it, which amazes my family to no end—but
clearly Facebook is one of those mechanisms by which people reach each other, and
before long, it'll start showing up as a developer requirement for companies looking
to hire. If you're looking to build out your resume to make yourself attractive to
companies in 2010, mad Facebook skillz might not be a bad investment.</li>
          <li>
            <em>... Nintendo releases an open SDK for building games for its next-gen DS-based
device.</em> With the spectacular success of games on the iPhone, Nintendo clearly
must see that they're missing a huge opportunity every day developers can't write
games for the Nintendo DS that are easily downloadable to the device for playing.
Nintendo is not stupid—if they don't open up the SDK and promote "casual"
games like those on the iPhone and those that can now be downloaded to the Zune or
the XBox, they risk being marginalized out of existence.</li>
        </ul>
        <p>
And for the next decade, I predict....
</p>
        <ul>
          <li>
            <em>... colleges and unversities will begin issuing e-book reader devices to students.</em> It's
a helluvalot cheaper than issuing laptops or netbooks, and besides....</li>
          <li>
            <em>... netbooks and e-book readers will merge before the decade is out.</em> Let's
be honest—if the e-book reader could do email and browse the web, you have almost
the perfect paperback-sized mobile device. As for the credit-card sized mobile device....</li>
          <li>
            <em>... mobile phones will all but disappear as they turn into what PDAs tried to
be.</em> "The iPhone makes calls? Really? You mean Voice-over-IP, right? No,
wait, over cell signal? It can <em>do </em>that? Wow, there's really an app for everything,
isn't there?"</li>
          <li>
            <em>... wireless formats will skyrocket in importance all around the office and home.</em> Combine
the iPhone's Bluetooth (or something similar yet lower-power-consuming) with an equally-capable
(Bluetooth or otherwise) projector, and suddenly many executives can leave their netbook
or laptop at home for a business presentation. Throw in the Whispersync-aware e-book
reader/netbook-thing, and now most executives have absolutely zero reason to carry
anything but their e-book/netbook and their phone/PDA. The day somebody figures out
an easy way to combine Bluetooth with PayPal on the iPhone or Android phone, we will
have more or less made pocket change irrelevant. And believe me, that day will happen
before the end of the decade.</li>
          <li>
            <em>... either Android or Windows Mobile will gain some serious market share against
the iPhone the day they figure out how to support an open and unrestricted AppStore-like
app acquisition model.</em> Let's be honest, the attraction of iTunes and AppStore
is that I can see an "Oh, cool!" app on a buddy's iPhone, and have it on
mine less than 30 seconds later. If Android or WinMo can figure out how to offer that
same kind of experience without the draconian AppStore policies to go with it, they'll
start making up lost ground on iPhone in a hurry.</li>
          <li>
            <em>... Apple becomes the DOJ target of the decade.</em> Microsoft was it in the 2000's,
and Apple's stunning rising success is going to put it squarely in the sights of monopolist
accusations before long. Coupled with the unfortunate health distractions that Steve
Jobs has to deal with, Apple's going to get hammered pretty hard by the end of the
decade, but it will have mastered enough market share and mindshare to weather it
as Microsoft has.</li>
          <li>
            <em>... Google becomes the next Microsoft.</em> It won't be anything the founders
do, but Google will do "something evil", and it will be loudly and screechingly
pointed out by all of Google's corporate opponents, and the star will have fallen.</li>
          <li>
... <em>Microsoft finds its way again.</em> Microsoft, as a company, has lost its
way. This is a company that's not used to losing, and like Bill Belichick's Patriots,
they will find ways to adapt and adjust to the changed circumstances of their position
to find a way to win again. What that'll be, I have no idea, but historically, the
last decade notwithstanding, betting against Microsoft has historically been a bad
idea. My gut tells me they'll figure something new to get that mojo back.</li>
          <li>
            <em>... a politician will make himself or herself famous by standing up to the TSA.</em> The
scene will play out like this: during a Congressional hearing on airline security,
after some nut/terrorist tries to blow up another plane through nitroglycerine-soaked
underwear, the TSA director will suggest all passengers should fly naked in order
to preserve safety, the congressman/woman will stare open-mouthed at this suggestion,
proclaim, "Have you no sense of decency, sir?" and immediately get a standing
ovation and never have to worry about re-election again. Folks, if we want to prevent
any chance of loss of life from a terrorist act on an airplane, we have to prevent
passengers from getting on them. Otherwise, just accept that it might happen, do a
reasonable job of preventing it from happening, and let private insurance start offering
flight insurance against the possibility to reassure the paranoid.</li>
        </ul>
        <p>
See you all next year.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=680b8296-ba07-4230-b067-edceaf04e84b" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>2010 Predictions, 2009 Predictions Revisited</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,680b8296-ba07-4230-b067-edceaf04e84b.aspx</guid>
      <link>http://blogs.tedneward.com/2010/01/05/2010+Predictions+2009+Predictions+Revisited.aspx</link>
      <pubDate>Tue, 05 Jan 2010 09:45:59 GMT</pubDate>
      <description>&lt;p&gt;
Here we go again—another year, another set of predictions revisited and offered up
for the next 12 months. And maybe, if I'm feeling really ambitious, I'll take that
shot I thought about last year and try predicting for the decade. Without further
ado, I'll go back and revisit, unedited, my predictions for 2009 (&amp;quot;&lt;strong&gt;THEN&lt;/strong&gt;&amp;quot;),
and pontificate on those subjects for 2010 before adding any new material/topics.
Just for convenience, &lt;a href="http://blogs.tedneward.com/2009/01/01/2009+Predictions+2008+Predictions+Revisited.aspx" target="_blank"&gt;here's
a link back to last years' predictions&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Last year's predictions went something like this (complete with basketball-scoring):
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;THEN: &lt;/strong&gt;&amp;quot;Cloud&amp;quot; will become the next &amp;quot;ESB&amp;quot; or &amp;quot;SOA&amp;quot;,
in that it will be something that everybody will talk about, but few will understand
and even fewer will do anything with. (Considering the widespread disparity in the
definition of the term, this seems like a no-brainer.) &lt;strong&gt;NOW:&lt;/strong&gt; Oh, yeah.
Straight up. I get two points for this one. Does &lt;em&gt;anyone&lt;/em&gt; have a working definition
of &amp;quot;cloud&amp;quot; that applies to all of the major vendors' implementations? &lt;em&gt;Ted,
2; Wrongness, 0&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN: &lt;/strong&gt;Interest in Scala will continue to rise, as will the number
of detractors who point out that Scala is too hard to learn. &lt;strong&gt;NOW:&lt;/strong&gt; Two
points for this one, too. Not a hard one, mind you, but one of those &amp;quot;pass-and-shoot&amp;quot;
jumpers from twelve feet out. James Strachan even tweeted about this earlier today,
pointing out this comparison. As more Java developers who think of themselves as smart
people try to pick up Scala and fail, the numbers of sour grapes responses like &amp;quot;Scala's
too complex, and who needs that functional stuff anyway?&amp;quot; will continue to rise
in 2010. &lt;em&gt;Ted, 4; Wrongness, 0&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Interest in F# will continue to rise, as will the number of
detractors who point out that F# is too hard to learn. (Hey, the two really are cousins,
and the fortunes of one will serve as a pretty good indication of the fortunes of
the other, and both really seem to be on the same arc right now.) &lt;strong&gt;NOW:&lt;/strong&gt; Interestingly
enough, I haven't heard as many F# detractors as Scala detractors, possibly because
I think F# hasn't really reached the masses of .NET developers the way that Scala
has managed to find its way in front of Java developers. I think that'll change mighty
quickly in 2010, though, once VS 2010 hits the streets. &lt;em&gt;Ted, 4; Wrongness 2&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;&lt;em&gt;:&lt;/em&gt; Interest in all kinds of functional languages will
continue to rise, and more than one person will take a hint from Bob &amp;quot;crazybob&amp;quot;
Lee and liken functional programming to AOP, for good and for ill. People who took
classes on Haskell in college will find themselves reaching for their old college
textbooks again. &lt;strong&gt;NOW:&lt;/strong&gt; Yep, I'm claiming two points on this one, if
only because a bunch of Haskell books shipped this year, and they'll be the last to
do so for about five years after this. (By the way, does anybody still remember aspects?)
But I'm going the opposite way with this one now; yes, there's Haskell, and yes, there's
Erlang, and yes, there's a lot of other functional languages out there, but who cares?
They're hard to learn, they don't always translate well to other languages, and developers
want languages that work on the platform they use on a daily basis, and that means
F# and Scala or Clojure, or its simply not an option. &lt;em&gt;Ted 6; Wrongness 2&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;&lt;em&gt;:&lt;/em&gt; The iPhone is going to be hailed as &amp;quot;the enterprise
development platform of the future&amp;quot;, and companies will be rolling out apps to
it. Look for Quicken iPhone edition, PowerPoint and/or Keynote iPhone edition, along
with connectors to hook the iPhone up to a presentation device, and (I'll bet) a World
of Warcraft iPhone client (legit or otherwise). iPhone is the new hotness in the mobile
space, and people will flock to it madly. &lt;strong&gt;NOW:&lt;/strong&gt; Two more points, but
let's be honest—this was a fast-break layup, no work required on my part. &lt;em&gt;Ted
8; Wrongness 2.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Another Oslo CTP will come out, and it will bear only a superficial
resemblance to the one that came out in October at PDC. Betting on Oslo right now
is a fools' bet, not because of any inherent weakness in the technology, but just
because it's way too early in the cycle to be thinking about for anything vaguely
resembling production code. &lt;strong&gt;NOW:&lt;/strong&gt; If you've worked at all with Oslo,
you might argue with me, but I'm still taking my two points. The two CTPs were pretty
different in a number of ways. &lt;em&gt;Ted 10; Wrongness 2.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: The IronPython and IronRuby teams will find some serious versioning
issues as they try to manage the DLR versioning story between themselves and the CLR
as a whole. An initial hack will result, which will be codified into a standard practice
when .NET 4.0 ships. Then the next release of IPy or IRb will have to try and slip
around its restrictions in 2010/2011. By 2012, IPy and IRb will have to be shipping
as part of Visual Studio just to put the releases back into lockstep with one another
(and the rest of the .NET universe). &lt;strong&gt;NOW:&lt;/strong&gt; Pressure is still building.
Let's see what happens by the time VS 2010 ships, and then see what the IPy/IRb teams
start to do to adjust to the versioning issues that arise. &lt;em&gt;Ted 8; Wrongness 2.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: The death of JSR-277 will spark an uprising among the two leading
groups hoping to foist it off on the Java community--OSGi and Maven--while the rest
of the Java world will breathe a huge sigh of relief and look to see what &amp;quot;modularity&amp;quot;
means in Java 7. Some of the alpha geeks in Java will start using--if not building--JDK
7 builds just to get a heads-up on its impact, and be quietly surprised and, I dare
say, perhaps even pleased. &lt;strong&gt;NOW:&lt;/strong&gt; Ah, Ted, you really should never
underestimate the community's willingness to take a bad idea, strip all the goodness
out of it, and then cycle it back into the mix as something completely different yet
somehow just as dangerous and crazy. I give you Project Jigsaw. &lt;em&gt;Ted 10; Wrongness
2;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: The invokedynamic JSR will leapfrog in importance to the top
of the list. &lt;strong&gt;NOW:&lt;/strong&gt; The invokedynamic JSR begat interest in other languages
on the JVM. The interest in other languages on the JVM begat the need to start thinking
about how to support them in the Java libraries. The need to start thinking about
supporting those languages begat a &amp;quot;Holy sh*t moment&amp;quot; somewhere inside Sun
and led them to (re-)propose closures for JDK 7. And in local sports news, Ted notched
up two more points on the scoreboard. &lt;em&gt;Ted 12; Wrongness 2.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Another Windows 7 CTP will come out, and it will spawn huge
media interest that will eventually be remembered as Microsoft promises, that will
eventually be remembered as Microsoft guarantees, that will eventually be remembered
as Microsoft FUD and &amp;quot;promising much, delivering little&amp;quot;. Microsoft ain't
always at fault for the inflated expectations people have--sometimes, yes, perhaps
even a lot of times, but not always. &lt;strong&gt;NOW:&lt;/strong&gt; And then, just when the
game started to turn into a runaway, airballs started to fly. The Windows7 release
shipped, and contrary to what I expected, the general response to it was pretty warm.
Yes, there were a few issues that emerged, but overall the media liked it, the masses
liked it, and Microsoft seemed to have dodged a bullet. &lt;em&gt;Ted 12; Wrongness 5.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Apple will begin to legally threaten the clone market again,
except this time somebody's going to get the DOJ involved. (Yes, this is the iPhone/iTunes
prediction from last year, carrying over. I still expect this to happen.) &lt;strong&gt;NOW:&lt;/strong&gt; What
clones? The only people trying to clone Macs are those who are building Hackintosh
machines, and Apple can't sue them so long as they're using licensed copies of Mac
OS X (as far as I know). Which has never stopped them from trying, mind you, and I
still think Steve has some part of his brain whispering to him at night, calculating
all the hardware sales lost to Hackintosh netbooks out there. But in any event, that's
another shot missed. &lt;em&gt;Ted 12; Wrongness 7.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Alpha-geek developers will start creating their own languages
(even if they're obscure or bizarre ones like Shakespeare or Ook#) just to have that
listed on their resume as the DSL/custom language buzz continues to build. &lt;strong&gt;NOW:&lt;/strong&gt; I
give you Ioke. If I'd extended this to include outdated CPU interpreters, I'd have
made that three-pointer from half-court instead of just the top of the key. &lt;em&gt;Ted
14; Wrongness 7.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Roy Fielding will officially disown most of the &amp;quot;REST&amp;quot;ful
authors and software packages available. Nobody will care--or worse, somebody looking
to make a name for themselves will proclaim that Roy &amp;quot;doesn't really understand
REST&amp;quot;. And they'll be right--Roy doesn't understand what &lt;em&gt;they&lt;/em&gt; consider
to be REST, and the fact that he created the term will be of no importance anymore.
Being &amp;quot;REST&amp;quot;ful will equate to &amp;quot;I did it myself!&amp;quot;, complete with
expectations of a gold star and a lollipop. &lt;strong&gt;NOW:&lt;/strong&gt; Does anybody in
the REST community care what Roy Fielding wrote way back when? I keep seeing &amp;quot;REST&amp;quot;ful
systems that seem to have designers who've never heard of Roy, or his thesis. Roy
hasn't officially disowned them, but damn if he doesn't seem close to it. Still....
No points. &lt;em&gt;Ted 14; Wrongness 9.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: The Parrot guys will make at least one more minor point release.
Nobody will notice or care, except for a few doggedly stubborn Perl hackers. They
will find themselves having nightmares of previous lives carrying around OS/2 books
and Amiga paraphernalia. Perl 6 will celebrate it's seventh... or is it eighth?...
anniversary of being announced, and nobody will notice. &lt;strong&gt;NOW:&lt;/strong&gt; Does
anybody still follow Perl 6 development? Has the spec even been written yet? Google
on &amp;quot;Perl 6 release&amp;quot;, and you get varying reports: &amp;quot;It'll ship 'when
it's ready'&amp;quot;, &amp;quot;There are no such dates because this isn't a commericially-backed
effort&amp;quot;, and &amp;quot;Spring 2010&amp;quot;. Swish—nothin' but net. &lt;em&gt;Ted 16; Wrongness
9.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: The debate around &amp;quot;Scrum Certification&amp;quot; will rise
to a fever pitch as short-sighted money-tight companies start looking for reasons
to cut costs and either buy into agile at a superficial level and watch it fail, or
start looking to cut the agilists from their company in order to replace them with
cheaper labor. &lt;strong&gt;NOW:&lt;/strong&gt; Agile has become another adjective meaning &amp;quot;best
practices&amp;quot;, and as such, has essentially lost its meaning. Just ask Scott Bellware. &lt;em&gt;Ted
18; Wrongness 9.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Adobe will continue to make Flex and AIR look more like C#
and the CLR even as Microsoft tries to make Silverlight look more like Flash and AIR.
Web designers will now get to experience the same fun that back-end web developers
have enjoyed for near-on a decade, as shops begin to artificially partition themselves
up as either &amp;quot;Flash&amp;quot; shops or &amp;quot;Silverlight&amp;quot; shops. &lt;strong&gt;NOW:&lt;/strong&gt; Not
sure how to score this one—I haven't seen the explicit partitioning happen yet, but
the two environments definitely still seem to be looking to start tromping on each
others' turf, particularly when we look at the rapid releases coming from the Silverlight
team. &lt;em&gt;Ted 16; Wrongness 11.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THEN&lt;/strong&gt;: Gartner will still come knocking, looking to hire me for outrageous
sums of money to do nothing but blog and wax prophetic. &lt;strong&gt;NOW:&lt;/strong&gt; Still
no job offers. Damn. Ah, well. &lt;em&gt;Ted 16; Wrongness 13.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A close game. Could've gone either way. *shrug* Ah, well. It was silly to try and
score it in basketball metaphor, anyway—that's the last time I watch ESPN before writing
this.
&lt;/p&gt;
&lt;p&gt;
For 2010, I predict....
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;... I will offer 3- and 4-day training classes on F# and Scala, among other things.&lt;/em&gt; OK,
that's not fair—yes, I have the materials, I just need to work out locations and times.
Contact me if you're interested in a private class, by the way.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... I will publish two books, one on F# and one on Scala.&lt;/em&gt; OK, OK, another
plug. Or, rather, more of a resolution. One will be the &amp;quot;Professional F#&amp;quot;
I'm doing for Wiley/Wrox, the other isn't yet finalized. But it'll either be published
through a publisher, or self-published, by JavaOne 2010.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... DSLs will either &amp;quot;succeed&amp;quot; this year, or begin the short slide into
the dustbin of obscure programming ideas.&lt;/em&gt; Domain-specific language advocates
have to put up some kind of strawman for developers to learn from and poke at, or
the whole concept will just fade away. Martin's book will help, if it ships this year,
but even that might not be enough to generate interest if it doesn't have some kind
of large-scale applicability in it. Patterns and refactoring and enterprise containers
all had a huge advantage in that developers could see pretty easily what the problem
was they solved; DSLs haven't made that clear yet.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... functional languages will start to see a backlash.&lt;/em&gt; I hate to say it,
but &amp;quot;getting&amp;quot; the functional mindset is hard, and there's precious few resources
that are making it easy for mainstream (read: O-O) developers make that adjustment,
far fewer than there was during the procedural-to-object shift. If the functional
community doesn't want to become mainstream, then mainstream developers will find
ways to take functional's most compelling gateway use-case (parallel/concurrent programming)
and find a way to &amp;quot;git 'er done&amp;quot; in the traditional O-O approach, probably
through software transactional memory, and functional languages like Haskell and Erlang
will be relegated to the &amp;quot;What Might Have Been&amp;quot; of computer science history.
Not sure what I mean? Try this: walk into a functional language forum, and ask what
a monad is. Nobody yet has been able to produce an answer that doesn't involve math
theory, or that does involve a practical domain-object-based example. In fact, nobody
has really said why (or if) monads are even still useful. Or catamorphisms. Or any
of the other dime-store words that the functional community likes to toss around.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Visual Studio 2010 will ship on time, and be one of the buggiest and/or slowest
releases in its history.&lt;/em&gt; I hate to make this prediction, because I really don't
want to be right, but there's just so much happening in the Visual Studio refactoring
effort that it makes me incredibly nervous. Widespread adoption of VS2010 will wait
until SP1 at the earliest. In fact....&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Visual Studio 2010 SP 1 will ship within three months of the final product.&lt;/em&gt; Microsoft
knows that people wait until SP 1 to think about upgrading, so they'll just plan for
an eager SP 1 release, and hope that managers will be too hung over from the New Year
(still) to notice that the necessary shakeout time hasn't happened.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Apple will ship a tablet with multi-touch on it, and it will flop horribly.&lt;/em&gt; Not
sure why I think this, but I just don't think the multi-touch paradigm that Apple
has cooked up for the iPhone will carry over to a tablet/laptop device. That won't
stop them from shipping it, and it won't stop Apple fan-boiz from buying it, but that's
about where the interest will end.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... JDK 7 closures will be debated for a few weeks, then become a fait accompli
as the Java community shrugs its collective shoulders.&lt;/em&gt; Frankly, I think the Java
community has exhausted its interest in debating new language features for Java. Recent
college grads and open-source groups with an axe to grind will continue to try and
make an issue out of this, but I think the overall Java community just... doesn't...
care. They just want to see JDK 7 ship someday.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Scala either &amp;quot;pops&amp;quot; in 2010, or begins to fall apart.&lt;/em&gt; By &amp;quot;pops&amp;quot;,
I mean reaches a critical mass of developers interested in using it, enough to convince
somebody to create a company around it, a la G2One.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Oracle is going to make a serious &amp;quot;cloud&amp;quot; play, probably by offering
an Oracle-hosted version of Azure or AppEngine.&lt;/em&gt; Oracle loves the enterprise space
too much, and derives too much money from it, to not at least appear to have some
kind of offering here. Now that they own Java, they'll marry it up against OpenSolaris,
the Oracle database, and throw the whole thing into a series of server centers all
over the continent, and call it &amp;quot;Oracle 12c&amp;quot; (c for Cloud, of course) or
something.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Spring development will slow to a crawl and start to take a left turn toward
cloud ideas.&lt;/em&gt; VMWare bought SpringSource for a reason, and I believe it's entirely
centered around VMWare's movement into the cloud space—they want to be more than &amp;quot;just&amp;quot;
a virtualization tool. Spring + Groovy makes a compelling development stack, particularly
if VMWare does some interesting hooks-n-hacks to make Spring a virtualization environment
in its own right somehow. But from a practical perspective, any community-driven development
against Spring is all but basically dead. The source may be downloadable later, like
the VMWare Player code is, but making contributions back? Fuhgeddabowdit.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... the explosion of e-book readers brings the Kindle 2009 edition way down to
size.&lt;/em&gt; The era of the e-book reader is here, and honestly, while I'm glad I have
a Kindle, I'm expecting that I'll be dusting it off a shelf in a few years. Kinda
like I do with my iPods from a few years ago.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... &amp;quot;social networking&amp;quot; becomes the &amp;quot;Web 2.0&amp;quot; of 2010.&lt;/em&gt; In
other words, using the term will basically identify you as a tech wannabe and clearly
out of touch with the bleeding edge.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Facebook becomes a developer platform requirement.&lt;/em&gt; I don't pretend to
know anything about Facebook—I'm not even on it, which amazes my family to no end—but
clearly Facebook is one of those mechanisms by which people reach each other, and
before long, it'll start showing up as a developer requirement for companies looking
to hire. If you're looking to build out your resume to make yourself attractive to
companies in 2010, mad Facebook skillz might not be a bad investment.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Nintendo releases an open SDK for building games for its next-gen DS-based
device.&lt;/em&gt; With the spectacular success of games on the iPhone, Nintendo clearly
must see that they're missing a huge opportunity every day developers can't write
games for the Nintendo DS that are easily downloadable to the device for playing.
Nintendo is not stupid—if they don't open up the SDK and promote &amp;quot;casual&amp;quot;
games like those on the iPhone and those that can now be downloaded to the Zune or
the XBox, they risk being marginalized out of existence.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
And for the next decade, I predict....
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;... colleges and unversities will begin issuing e-book reader devices to students.&lt;/em&gt; It's
a helluvalot cheaper than issuing laptops or netbooks, and besides....&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... netbooks and e-book readers will merge before the decade is out.&lt;/em&gt; Let's
be honest—if the e-book reader could do email and browse the web, you have almost
the perfect paperback-sized mobile device. As for the credit-card sized mobile device....&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... mobile phones will all but disappear as they turn into what PDAs tried to
be.&lt;/em&gt; &amp;quot;The iPhone makes calls? Really? You mean Voice-over-IP, right? No,
wait, over cell signal? It can &lt;em&gt;do &lt;/em&gt;that? Wow, there's really an app for everything,
isn't there?&amp;quot;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... wireless formats will skyrocket in importance all around the office and home.&lt;/em&gt; Combine
the iPhone's Bluetooth (or something similar yet lower-power-consuming) with an equally-capable
(Bluetooth or otherwise) projector, and suddenly many executives can leave their netbook
or laptop at home for a business presentation. Throw in the Whispersync-aware e-book
reader/netbook-thing, and now most executives have absolutely zero reason to carry
anything but their e-book/netbook and their phone/PDA. The day somebody figures out
an easy way to combine Bluetooth with PayPal on the iPhone or Android phone, we will
have more or less made pocket change irrelevant. And believe me, that day will happen
before the end of the decade.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... either Android or Windows Mobile will gain some serious market share against
the iPhone the day they figure out how to support an open and unrestricted AppStore-like
app acquisition model.&lt;/em&gt; Let's be honest, the attraction of iTunes and AppStore
is that I can see an &amp;quot;Oh, cool!&amp;quot; app on a buddy's iPhone, and have it on
mine less than 30 seconds later. If Android or WinMo can figure out how to offer that
same kind of experience without the draconian AppStore policies to go with it, they'll
start making up lost ground on iPhone in a hurry.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Apple becomes the DOJ target of the decade.&lt;/em&gt; Microsoft was it in the 2000's,
and Apple's stunning rising success is going to put it squarely in the sights of monopolist
accusations before long. Coupled with the unfortunate health distractions that Steve
Jobs has to deal with, Apple's going to get hammered pretty hard by the end of the
decade, but it will have mastered enough market share and mindshare to weather it
as Microsoft has.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... Google becomes the next Microsoft.&lt;/em&gt; It won't be anything the founders
do, but Google will do &amp;quot;something evil&amp;quot;, and it will be loudly and screechingly
pointed out by all of Google's corporate opponents, and the star will have fallen.&lt;/li&gt;
&lt;li&gt;
... &lt;em&gt;Microsoft finds its way again.&lt;/em&gt; Microsoft, as a company, has lost its
way. This is a company that's not used to losing, and like Bill Belichick's Patriots,
they will find ways to adapt and adjust to the changed circumstances of their position
to find a way to win again. What that'll be, I have no idea, but historically, the
last decade notwithstanding, betting against Microsoft has historically been a bad
idea. My gut tells me they'll figure something new to get that mojo back.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;... a politician will make himself or herself famous by standing up to the TSA.&lt;/em&gt; The
scene will play out like this: during a Congressional hearing on airline security,
after some nut/terrorist tries to blow up another plane through nitroglycerine-soaked
underwear, the TSA director will suggest all passengers should fly naked in order
to preserve safety, the congressman/woman will stare open-mouthed at this suggestion,
proclaim, &amp;quot;Have you no sense of decency, sir?&amp;quot; and immediately get a standing
ovation and never have to worry about re-election again. Folks, if we want to prevent
any chance of loss of life from a terrorist act on an airplane, we have to prevent
passengers from getting on them. Otherwise, just accept that it might happen, do a
reasonable job of preventing it from happening, and let private insurance start offering
flight insurance against the possibility to reassure the paranoid.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
See you all next year.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=680b8296-ba07-4230-b067-edceaf04e84b" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,680b8296-ba07-4230-b067-edceaf04e84b.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Security</category>
      <category>Social</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>VMWare</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=d3b4c5aa-2964-492c-9af3-523cb403b444</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,d3b4c5aa-2964-492c-9af3-523cb403b444.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,d3b4c5aa-2964-492c-9af3-523cb403b444.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d3b4c5aa-2964-492c-9af3-523cb403b444</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Paul asked me to review this, his first book, and my comment to him was that he had
a pretty high bar to match; being of the same "series" as <em>Release It!</em>,
Mike Nygard's take on building software ready for production (and, in my repeatedly
stated opinion, the most important-to-read book of the decade), <em>Debug It!</em> had
some pretty impressive shoes to fill. Paul's comment was pretty predictable: "Thanks
for keeping the pressure to a minimum."
</p>
        <p>
My copy arrived in the mail while I was at the NFJS show in Denver this past weekend,
and with a certain amount of dread and excitement, I opened the envelope and sat down
to read for a few minutes. I managed to get halfway through it before deciding I had
to post a review before I get too caught up in my next trip and forget.
</p>
        <h4>
          <em>Short version</em>
        </h4>
        <p>
          <em>Debug It!</em> is a great resource for anyone looking to learn the science of
good debugging. It is entirely language- and platform-agnostic, preferring to focus
entirely on the <em>process</em> and <em>mindset</em> of debugging, rather than on
edge cases or command-line switches in a tool or language. Overall, the writing is
clear and straightforward without being preachy or judgmental, and is liberally annotated
with real-life case stories from both the authors' and the Pragmatic Programmers'
own history, which keeps the tone lighter and yet still proving the point of the text.
Highly recommended for the junior developers on the team; senior developers will likely
find some good tidbits in here as well. 
</p>
        <h4>
          <em>Long version</em>
        </h4>
        <p>
          <em>Debug It!</em> is an excellently-written and to-the-point description of the process
of not only identifying and fixing defects in software, but also of the attitudes
required to keep software from failing. Rather than simply tossing off old maxims
or warming them over with new terminology ("You should always verify the parameters
to your procedure calls" replaced with "You should always verify the parameters
entering a method and ensure the fields follow the invariants established in the specification"),
Paul ensures that when making a point, his prose is clear, the rationale carefully
explained, and the consequences of not following this advice are clearly spelled out.
His advice is pragmatic, and takes into account that developers can't always follow
the absolute rules we'd like to—he talks about some of his experiences with "bug
priorities" and how users pretty quickly figured out to always set the bug's
priority at the highest level in order to get developer attention, for example, and
some ways to try and address that all-too-human failing of bug-tracking systems.
</p>
        <p>
It needs to be said, right from the beginning, that <em>Debug It!</em> will not teach
you how to use the debugging features of your favorite IDE, however. This is because
Paul (deliberately, it seems) takes a platform- and language-agnostic approach to
the book—there are no examples of how to set breakpoints in gdb, or how to attach
the Visual Studio IDE to a running Windows service, for example. This will likely
weed out those readers who are looking for "Google-able" answers to their
common debugging problems, and that's a shame, because those are probably the very
readers that need to read this book. Having said that, however, I like this agnostic
approach, because these ideas and thought processes, the ones that are entirely independent
of the language or platform, are exactly the kinds of things that senior developers
carry over with them from one platform to the next. Still, the junior developer who
picks this book up is going to still need a reference manual or the user manual for
their IDE or toolchain, and will need to practice some with both books in hand if
they want to maximize the effectiveness of what's in here.
</p>
        <p>
One of the things I like most about this book is that it is liberally adorned with
real-life discussions of various scenarios the author team has experienced; the reason
I say "author team" here is because although the stories (for the most part)
remain unattributed, there are obvious references to "Dave" and "Andy",
which I assume pretty obviously refer to Dave Thomas and Andy Hunt, the Pragmatic
Programmers and the owners of Pragmatic Bookshelf. Some of the stories are humorous,
and some of them probably would be humorous if they didn't strike so close to my own
bitterly-remembered experiences. All of them do a good job of reinforcing the point,
however, thus rendering the prose more effective in communicating the idea without
getting to be too preachy or bombastic.
</p>
        <p>
The book obviously intends to target a junior developer audience, because most senior
developers have already intuitively (or experientially) figured out many of the processes
described in here. But, quite frankly, I think it would be a shame for senior developers
to pass on this one; though the temptation will be to simply toss it aside and say,
"I already do all this stuff", senior developers should resist that urge
and read it through cover to cover. If nothing else, it'll help reinforce certain
ideas, bring some of the intuitive process more to light and allow us to analyze what
we do right and what we do wrong, and perhaps most importantly, give us a common backdrop
against which we can mentor junior developers in the science of debugging.
</p>
        <p>
One of the chapters I like in particular, "Chapter 7: Pragmatic Zero Tolerance",
is particularly good reading for those shops that currently suffer from a deficit
of management support for writing good software. In it, Paul talks specifically about
some of the triage process about bugs ("When to fix bugs"), the mental approach
developers should have to fixing bugs ("The debugging mind-set") and how
to get started on creating good software out of bad ("How to dig yourself out
of a quality hole"). These are techniques that a senior developer can bring to
the team and implement at a grass-roots level, in many cases without management even
being aware of what's going on. (It's a sad state of affairs that we sometimes have
to work behind management's back to write good-quality code, but I know that some
developers out there are in exactly that situation, and simply saying, "Quit
and find a new job", although pithy and good for a laugh on a panel, doesn't
really offer much in the way of help. Paul doesn't take that route here, and that
alone makes this book worth reading.)
</p>
        <p>
Another of the chapters that resonates well with me is the first one in Part III ("Debug
Fu"), Chapter 8, entitled "Special Cases", in which he tackles a number
of "advanced" debugging topics, such as "Patching Existing Releases"
and "Hesenbugs" (Concurrency-related bugs). I won't spoil the punchline
for you, but suffice it to say that I wish I'd had that chapter on hand to give out
to teammates on a few projects I've worked on in the past.
</p>
        <p>
Overall, this book is going to be a huge win, and I think it's a worthy successor
to the <em>Release It!</em> reputation. Development managers and team leads should
get a copy for the junior developers on their team as a Christmas gift, but only after
the senior developers have read through it as well. (Senior devs, don't despair—at
190 pages, you can rip through this in a single night, and I can almost guarantee
that you'll learn a few ideas you can put into practice the next morning to boot.)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=d3b4c5aa-2964-492c-9af3-523cb403b444" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Book Review: Debug It! (Paul Butcher, Pragmatic Bookshelf)</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,d3b4c5aa-2964-492c-9af3-523cb403b444.aspx</guid>
      <link>http://blogs.tedneward.com/2009/11/23/Book+Review+Debug+It+Paul+Butcher+Pragmatic+Bookshelf.aspx</link>
      <pubDate>Mon, 23 Nov 2009 07:24:41 GMT</pubDate>
      <description>&lt;p&gt;
Paul asked me to review this, his first book, and my comment to him was that he had
a pretty high bar to match; being of the same &amp;quot;series&amp;quot; as &lt;em&gt;Release It!&lt;/em&gt;,
Mike Nygard's take on building software ready for production (and, in my repeatedly
stated opinion, the most important-to-read book of the decade), &lt;em&gt;Debug It!&lt;/em&gt; had
some pretty impressive shoes to fill. Paul's comment was pretty predictable: &amp;quot;Thanks
for keeping the pressure to a minimum.&amp;quot;
&lt;/p&gt;
&lt;p&gt;
My copy arrived in the mail while I was at the NFJS show in Denver this past weekend,
and with a certain amount of dread and excitement, I opened the envelope and sat down
to read for a few minutes. I managed to get halfway through it before deciding I had
to post a review before I get too caught up in my next trip and forget.
&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;Short version&lt;/em&gt;
&lt;/h4&gt;
&lt;p&gt;
&lt;em&gt;Debug It!&lt;/em&gt; is a great resource for anyone looking to learn the science of
good debugging. It is entirely language- and platform-agnostic, preferring to focus
entirely on the &lt;em&gt;process&lt;/em&gt; and &lt;em&gt;mindset&lt;/em&gt; of debugging, rather than on
edge cases or command-line switches in a tool or language. Overall, the writing is
clear and straightforward without being preachy or judgmental, and is liberally annotated
with real-life case stories from both the authors' and the Pragmatic Programmers'
own history, which keeps the tone lighter and yet still proving the point of the text.
Highly recommended for the junior developers on the team; senior developers will likely
find some good tidbits in here as well. 
&lt;/p&gt;
&lt;h4&gt;&lt;em&gt;Long version&lt;/em&gt;
&lt;/h4&gt;
&lt;p&gt;
&lt;em&gt;Debug It!&lt;/em&gt; is an excellently-written and to-the-point description of the process
of not only identifying and fixing defects in software, but also of the attitudes
required to keep software from failing. Rather than simply tossing off old maxims
or warming them over with new terminology (&amp;quot;You should always verify the parameters
to your procedure calls&amp;quot; replaced with &amp;quot;You should always verify the parameters
entering a method and ensure the fields follow the invariants established in the specification&amp;quot;),
Paul ensures that when making a point, his prose is clear, the rationale carefully
explained, and the consequences of not following this advice are clearly spelled out.
His advice is pragmatic, and takes into account that developers can't always follow
the absolute rules we'd like to—he talks about some of his experiences with &amp;quot;bug
priorities&amp;quot; and how users pretty quickly figured out to always set the bug's
priority at the highest level in order to get developer attention, for example, and
some ways to try and address that all-too-human failing of bug-tracking systems.
&lt;/p&gt;
&lt;p&gt;
It needs to be said, right from the beginning, that &lt;em&gt;Debug It!&lt;/em&gt; will not teach
you how to use the debugging features of your favorite IDE, however. This is because
Paul (deliberately, it seems) takes a platform- and language-agnostic approach to
the book—there are no examples of how to set breakpoints in gdb, or how to attach
the Visual Studio IDE to a running Windows service, for example. This will likely
weed out those readers who are looking for &amp;quot;Google-able&amp;quot; answers to their
common debugging problems, and that's a shame, because those are probably the very
readers that need to read this book. Having said that, however, I like this agnostic
approach, because these ideas and thought processes, the ones that are entirely independent
of the language or platform, are exactly the kinds of things that senior developers
carry over with them from one platform to the next. Still, the junior developer who
picks this book up is going to still need a reference manual or the user manual for
their IDE or toolchain, and will need to practice some with both books in hand if
they want to maximize the effectiveness of what's in here.
&lt;/p&gt;
&lt;p&gt;
One of the things I like most about this book is that it is liberally adorned with
real-life discussions of various scenarios the author team has experienced; the reason
I say &amp;quot;author team&amp;quot; here is because although the stories (for the most part)
remain unattributed, there are obvious references to &amp;quot;Dave&amp;quot; and &amp;quot;Andy&amp;quot;,
which I assume pretty obviously refer to Dave Thomas and Andy Hunt, the Pragmatic
Programmers and the owners of Pragmatic Bookshelf. Some of the stories are humorous,
and some of them probably would be humorous if they didn't strike so close to my own
bitterly-remembered experiences. All of them do a good job of reinforcing the point,
however, thus rendering the prose more effective in communicating the idea without
getting to be too preachy or bombastic.
&lt;/p&gt;
&lt;p&gt;
The book obviously intends to target a junior developer audience, because most senior
developers have already intuitively (or experientially) figured out many of the processes
described in here. But, quite frankly, I think it would be a shame for senior developers
to pass on this one; though the temptation will be to simply toss it aside and say,
&amp;quot;I already do all this stuff&amp;quot;, senior developers should resist that urge
and read it through cover to cover. If nothing else, it'll help reinforce certain
ideas, bring some of the intuitive process more to light and allow us to analyze what
we do right and what we do wrong, and perhaps most importantly, give us a common backdrop
against which we can mentor junior developers in the science of debugging.
&lt;/p&gt;
&lt;p&gt;
One of the chapters I like in particular, &amp;quot;Chapter 7: Pragmatic Zero Tolerance&amp;quot;,
is particularly good reading for those shops that currently suffer from a deficit
of management support for writing good software. In it, Paul talks specifically about
some of the triage process about bugs (&amp;quot;When to fix bugs&amp;quot;), the mental approach
developers should have to fixing bugs (&amp;quot;The debugging mind-set&amp;quot;) and how
to get started on creating good software out of bad (&amp;quot;How to dig yourself out
of a quality hole&amp;quot;). These are techniques that a senior developer can bring to
the team and implement at a grass-roots level, in many cases without management even
being aware of what's going on. (It's a sad state of affairs that we sometimes have
to work behind management's back to write good-quality code, but I know that some
developers out there are in exactly that situation, and simply saying, &amp;quot;Quit
and find a new job&amp;quot;, although pithy and good for a laugh on a panel, doesn't
really offer much in the way of help. Paul doesn't take that route here, and that
alone makes this book worth reading.)
&lt;/p&gt;
&lt;p&gt;
Another of the chapters that resonates well with me is the first one in Part III (&amp;quot;Debug
Fu&amp;quot;), Chapter 8, entitled &amp;quot;Special Cases&amp;quot;, in which he tackles a number
of &amp;quot;advanced&amp;quot; debugging topics, such as &amp;quot;Patching Existing Releases&amp;quot;
and &amp;quot;Hesenbugs&amp;quot; (Concurrency-related bugs). I won't spoil the punchline
for you, but suffice it to say that I wish I'd had that chapter on hand to give out
to teammates on a few projects I've worked on in the past.
&lt;/p&gt;
&lt;p&gt;
Overall, this book is going to be a huge win, and I think it's a worthy successor
to the &lt;em&gt;Release It!&lt;/em&gt; reputation. Development managers and team leads should
get a copy for the junior developers on their team as a Christmas gift, but only after
the senior developers have read through it as well. (Senior devs, don't despair—at
190 pages, you can rip through this in a single night, and I can almost guarantee
that you'll learn a few ideas you can put into practice the next morning to boot.)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=d3b4c5aa-2964-492c-9af3-523cb403b444" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,d3b4c5aa-2964-492c-9af3-523cb403b444.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=53f9b658-3b27-4f1a-b93e-14d3a57a8ec1</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,53f9b658-3b27-4f1a-b93e-14d3a57a8ec1.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,53f9b658-3b27-4f1a-b93e-14d3a57a8ec1.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=53f9b658-3b27-4f1a-b93e-14d3a57a8ec1</wfw:commentRss>
      <slash:comments>35</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The above quote was tossed off by Billy Hollis at the patterns&amp;practices Summit
this week in Redmond. I passed the quote out to the Twitter masses, along with my
+1, and predictably, the comments started coming in shortly thereafter. Rather than
limit the thoughts to the 120 or so characters that Twitter limits us to, I thought
this subject deserved some greater expansion.
</p>
        <p>
But before I do, let me try (badly) to paraphrase the lightning talk that Billy gave
here, which sets context for the discussion:
</p>
        <ul>
          <li>
Keeping track of all the stuff Microsoft is releasing is hard work: LINQ, EF, Silverlight,
ASP.NET MVC, Enterprise Library, Azure, Prism, Sparkle, MEF, WCF, WF, WPF, InfoCard,
CardSpace, the list goes on and on, and frankly, nobody (and I mean nobody) can track
it all.</li>
          <li>
Microsoft released all this stuff because they were chasing the "enterprise"
part of the developer/business curve, as opposed to the "long tail" part
of the curve that they used to chase down. They did this because they believed that
this was good business practice—like banks, "enterprises are where the money
is". (If you're not familiar with this curve, imagine a graph with a single curve
asymptotically reaching for both axes, where Y is the number of developers on the
project, and X is the number of projects. What you get is a curve of a few high-developer-population
projects on the left, to a large number of projects with just 1 or 2 developers. This
right-hand portion of the curve is known as "the long tail" of the software
industry.)</li>
          <li>
A lot of software written back in the 90's was written by 1 or 2 guys working for
just a few months to slam something out and see if it was useful. What chances do
those kinds of projects have today? What tools would you use to build them?</li>
          <li>
The problem is the complexity of the tools we have available to us today preclude
that kind of software development.</li>
          <li>
Agile doesn't solve this problem—the agile movement suggests that we have to create
story cards, we have to build unit tests, we have to have a continuous integration
server, we have to have standup meetings every day, .... In short, particularly among
the agile evangelists (by which we really mean <em>zealots</em>), if you aren't doing
a full agile process, you are simply failing. <em>(If this is true, how on earth did
all those thousands of applications written in FoxPro or Access ever manage to succeed?
–-Me)</em> At one point, an agilist said point-blank, "If you don't do agile,
what happens when your project reaches a thousand users?" As Billy put it, "Think
about that for a second: This agile guy is <em>threatening</em> us with success."</li>
          <li>
Agile is for managing complexity. What we need is to recognize that there is a place
for outright simplicity instead.</li>
        </ul>
        <p>
By the way, let me say this out loud: if you have not heard Billy Hollis speak, you
should. Even if you're a Java or Ruby developer, you should listen to what he has
to say. He's been developing software for a long time, has seen a lot of these technology-industry
trends come and go, and even if you disagree with him, you need to listen to him.
</p>
        <p>
Let me rephrase Billy's talk this way:
</p>
        <blockquote>
          <p>
            <em>Where is this decade's Access?</em>
          </p>
        </blockquote>
        <p>
It may seem like a snarky and trolling question, but think about it for a moment:
for a decade or so, I was brought into project after project that was designed to
essentially rebuild/rearchitect the Access database created by one of the department's
more tech-savvy employees into something that could scale beyond just the department. 
</p>
        <blockquote>
          <p>
            <em>(Actually, in about half of them, the goal wasn't even to scale it up, it was
just to put it on the web. It was only in the subsequent meetings and discussions
that the issues of scale came up, and if my memory is accurate, I was the one who
raised those issues, not the customer. I wonder now, looking back at it, if that was
pure gold-plating on my part.)</em>
          </p>
        </blockquote>
        <p>
Others, including many people I care about (Rod Paddock, Markus Eggers, Ken Levy,
Cathi Gero, for starters) made a healthy living off of building "line of business"
applications in FoxPro, which Microsoft has now officially shut down. For those who
did Office applications, Visual Basic for Applications has now been officially deprecated
in favor of VSTO (Visual Studio Tools for Office), a set of libraries that are available
for use by any .NET application language, and of course classic Visual Basic itself
has been "brought into the fold" by making it a fully-fledged object-oriented
language complete with XML literals and LINQ query capabilities.
</p>
        <p>
Which means, if somebody working for a small school district in western Pennsylvania
wants to build a simple application for tracking students' attendance (rather than
tracking it on paper anymore), what do they do?
</p>
        <p>
Bruce Tate alluded to this in his <em>Beyond Java</em>, based on the realization that
the Java space was no better—to bring a college/university student up to speed on
all the necessary technologies required of a "productive" Java developer,
he calculated at least five or six weeks of training was required. And that's not
a bad estimate, and might even be a bit on the shortened side. You can maybe get away
with less if they're joining a team which collectively has these skills distributed
across the entire team, but if we're talking about a standalone developer who's going
to be building software by himself, it's a pretty impressive list. Here's my back-of-the-envelope
calculations:
</p>
        <ul>
          <li>
Week one: Java language. (Nobody ever comes out of college knowing all the Java language
they need.)</li>
          <li>
Week two: Java virtual machine: threading/concurrency, ClassLoaders, Serialization,
RMI, XML parsing, reference types (weak, soft, phantom).</li>
          <li>
Week three: Infrastructure: Ant, JUnit, continuous integration, Spring.</li>
          <li>
Week four: Data access: JDBC, Hibernate. (Yes, I think you need a full week on Hibernate
to be able to use it effectively.)</li>
          <li>
Week five: Web: HTTP, HTML, servlets, filters, servlet context and listeners, JSP,
model-view-controller, and probably some Ajax to boot.</li>
        </ul>
        <p>
I could go on (seriously! no JMS? no REST? no Web services?), but you get the point.
And lest the .NET community start feeling complacent, put together a similar list
for the standalone .NET developer, and you'll come out to something pretty equivalent.
(Just look at the <a href="http://www.pluralsight.com/main/ilt/Courses.aspx" target="_blank">Pluralsight
list of courses</a>—name the <em>one</em> course you would give that college kid to
bring him up to speed. Stumped? Don't feel bad—I can't, either. And it's not them—pick
on any of the training companies.)
</p>
        <p>
Now throw agile into that mix: <em>how does an agile process reduce the complexity
load?</em> And the answer, of course, is that it doesn't—it simply tries to muddle
through as best it can, by doing all of the things that developers need to be doing:
gathering as much feedback from every corner of their world as they can, through tests,
customer interaction, and frequent releases. <em>All of which is good</em>. I'm <em>not</em> here
to suggest that we should all give up agile and immediately go back to waterfall and
Big Design Up Front. Anybody who uses Billy's quote as a sound bite to suggest that
is a subversive and a terrorist and should have their arguments refuted with <em>extreme
prejudice</em>.
</p>
        <p>
But agile is not going to reduce the technology complexity load, which is the root
cause of the problem.
</p>
        <p>
Or, perhaps, let me ask it this way: your 16-year-old wants to build a system to track
the cards in his Magic deck. What language do you teach him?
</p>
        <p>
We are in <em>desperate</em> need of simplicity in this industry. Whoever gets that,
and gets it right, defines the "Next Big Thing".
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=53f9b658-3b27-4f1a-b93e-14d3a57a8ec1" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>&amp;quot;Agile is treating the symptoms, not the disease&amp;quot;</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,53f9b658-3b27-4f1a-b93e-14d3a57a8ec1.aspx</guid>
      <link>http://blogs.tedneward.com/2009/10/12/quotAgile+Is+Treating+The+Symptoms+Not+The+Diseasequot.aspx</link>
      <pubDate>Mon, 12 Oct 2009 23:51:39 GMT</pubDate>
      <description>&lt;p&gt;
The above quote was tossed off by Billy Hollis at the patterns&amp;amp;practices Summit
this week in Redmond. I passed the quote out to the Twitter masses, along with my
+1, and predictably, the comments started coming in shortly thereafter. Rather than
limit the thoughts to the 120 or so characters that Twitter limits us to, I thought
this subject deserved some greater expansion.
&lt;/p&gt;
&lt;p&gt;
But before I do, let me try (badly) to paraphrase the lightning talk that Billy gave
here, which sets context for the discussion:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Keeping track of all the stuff Microsoft is releasing is hard work: LINQ, EF, Silverlight,
ASP.NET MVC, Enterprise Library, Azure, Prism, Sparkle, MEF, WCF, WF, WPF, InfoCard,
CardSpace, the list goes on and on, and frankly, nobody (and I mean nobody) can track
it all.&lt;/li&gt;
&lt;li&gt;
Microsoft released all this stuff because they were chasing the &amp;quot;enterprise&amp;quot;
part of the developer/business curve, as opposed to the &amp;quot;long tail&amp;quot; part
of the curve that they used to chase down. They did this because they believed that
this was good business practice—like banks, &amp;quot;enterprises are where the money
is&amp;quot;. (If you're not familiar with this curve, imagine a graph with a single curve
asymptotically reaching for both axes, where Y is the number of developers on the
project, and X is the number of projects. What you get is a curve of a few high-developer-population
projects on the left, to a large number of projects with just 1 or 2 developers. This
right-hand portion of the curve is known as &amp;quot;the long tail&amp;quot; of the software
industry.)&lt;/li&gt;
&lt;li&gt;
A lot of software written back in the 90's was written by 1 or 2 guys working for
just a few months to slam something out and see if it was useful. What chances do
those kinds of projects have today? What tools would you use to build them?&lt;/li&gt;
&lt;li&gt;
The problem is the complexity of the tools we have available to us today preclude
that kind of software development.&lt;/li&gt;
&lt;li&gt;
Agile doesn't solve this problem—the agile movement suggests that we have to create
story cards, we have to build unit tests, we have to have a continuous integration
server, we have to have standup meetings every day, .... In short, particularly among
the agile evangelists (by which we really mean &lt;em&gt;zealots&lt;/em&gt;), if you aren't doing
a full agile process, you are simply failing. &lt;em&gt;(If this is true, how on earth did
all those thousands of applications written in FoxPro or Access ever manage to succeed?
–-Me)&lt;/em&gt; At one point, an agilist said point-blank, &amp;quot;If you don't do agile,
what happens when your project reaches a thousand users?&amp;quot; As Billy put it, &amp;quot;Think
about that for a second: This agile guy is &lt;em&gt;threatening&lt;/em&gt; us with success.&amp;quot;&lt;/li&gt;
&lt;li&gt;
Agile is for managing complexity. What we need is to recognize that there is a place
for outright simplicity instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
By the way, let me say this out loud: if you have not heard Billy Hollis speak, you
should. Even if you're a Java or Ruby developer, you should listen to what he has
to say. He's been developing software for a long time, has seen a lot of these technology-industry
trends come and go, and even if you disagree with him, you need to listen to him.
&lt;/p&gt;
&lt;p&gt;
Let me rephrase Billy's talk this way:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;Where is this decade's Access?&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
It may seem like a snarky and trolling question, but think about it for a moment:
for a decade or so, I was brought into project after project that was designed to
essentially rebuild/rearchitect the Access database created by one of the department's
more tech-savvy employees into something that could scale beyond just the department. 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;(Actually, in about half of them, the goal wasn't even to scale it up, it was
just to put it on the web. It was only in the subsequent meetings and discussions
that the issues of scale came up, and if my memory is accurate, I was the one who
raised those issues, not the customer. I wonder now, looking back at it, if that was
pure gold-plating on my part.)&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Others, including many people I care about (Rod Paddock, Markus Eggers, Ken Levy,
Cathi Gero, for starters) made a healthy living off of building &amp;quot;line of business&amp;quot;
applications in FoxPro, which Microsoft has now officially shut down. For those who
did Office applications, Visual Basic for Applications has now been officially deprecated
in favor of VSTO (Visual Studio Tools for Office), a set of libraries that are available
for use by any .NET application language, and of course classic Visual Basic itself
has been &amp;quot;brought into the fold&amp;quot; by making it a fully-fledged object-oriented
language complete with XML literals and LINQ query capabilities.
&lt;/p&gt;
&lt;p&gt;
Which means, if somebody working for a small school district in western Pennsylvania
wants to build a simple application for tracking students' attendance (rather than
tracking it on paper anymore), what do they do?
&lt;/p&gt;
&lt;p&gt;
Bruce Tate alluded to this in his &lt;em&gt;Beyond Java&lt;/em&gt;, based on the realization that
the Java space was no better—to bring a college/university student up to speed on
all the necessary technologies required of a &amp;quot;productive&amp;quot; Java developer,
he calculated at least five or six weeks of training was required. And that's not
a bad estimate, and might even be a bit on the shortened side. You can maybe get away
with less if they're joining a team which collectively has these skills distributed
across the entire team, but if we're talking about a standalone developer who's going
to be building software by himself, it's a pretty impressive list. Here's my back-of-the-envelope
calculations:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Week one: Java language. (Nobody ever comes out of college knowing all the Java language
they need.)&lt;/li&gt;
&lt;li&gt;
Week two: Java virtual machine: threading/concurrency, ClassLoaders, Serialization,
RMI, XML parsing, reference types (weak, soft, phantom).&lt;/li&gt;
&lt;li&gt;
Week three: Infrastructure: Ant, JUnit, continuous integration, Spring.&lt;/li&gt;
&lt;li&gt;
Week four: Data access: JDBC, Hibernate. (Yes, I think you need a full week on Hibernate
to be able to use it effectively.)&lt;/li&gt;
&lt;li&gt;
Week five: Web: HTTP, HTML, servlets, filters, servlet context and listeners, JSP,
model-view-controller, and probably some Ajax to boot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I could go on (seriously! no JMS? no REST? no Web services?), but you get the point.
And lest the .NET community start feeling complacent, put together a similar list
for the standalone .NET developer, and you'll come out to something pretty equivalent.
(Just look at the &lt;a href="http://www.pluralsight.com/main/ilt/Courses.aspx" target="_blank"&gt;Pluralsight
list of courses&lt;/a&gt;—name the &lt;em&gt;one&lt;/em&gt; course you would give that college kid to
bring him up to speed. Stumped? Don't feel bad—I can't, either. And it's not them—pick
on any of the training companies.)
&lt;/p&gt;
&lt;p&gt;
Now throw agile into that mix: &lt;em&gt;how does an agile process reduce the complexity
load?&lt;/em&gt; And the answer, of course, is that it doesn't—it simply tries to muddle
through as best it can, by doing all of the things that developers need to be doing:
gathering as much feedback from every corner of their world as they can, through tests,
customer interaction, and frequent releases. &lt;em&gt;All of which is good&lt;/em&gt;. I'm &lt;em&gt;not&lt;/em&gt; here
to suggest that we should all give up agile and immediately go back to waterfall and
Big Design Up Front. Anybody who uses Billy's quote as a sound bite to suggest that
is a subversive and a terrorist and should have their arguments refuted with &lt;em&gt;extreme
prejudice&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
But agile is not going to reduce the technology complexity load, which is the root
cause of the problem.
&lt;/p&gt;
&lt;p&gt;
Or, perhaps, let me ask it this way: your 16-year-old wants to build a system to track
the cards in his Magic deck. What language do you teach him?
&lt;/p&gt;
&lt;p&gt;
We are in &lt;em&gt;desperate&lt;/em&gt; need of simplicity in this industry. Whoever gets that,
and gets it right, defines the &amp;quot;Next Big Thing&amp;quot;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=53f9b658-3b27-4f1a-b93e-14d3a57a8ec1" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,53f9b658-3b27-4f1a-b93e-14d3a57a8ec1.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Social</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>WCF</category>
      <category>Windows</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=3026e434-b1c8-4525-816a-2efcd5d2a6e6</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,3026e434-b1c8-4525-816a-2efcd5d2a6e6.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,3026e434-b1c8-4525-816a-2efcd5d2a6e6.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3026e434-b1c8-4525-816a-2efcd5d2a6e6</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently, an email crossed my Inbox from a friend who was concerned about some questionable
practices involving my content (as well as a few others'); apparently, I have been
listed as an "author" for SysCon, I have a "domain" with them,
and that I've been writing for them since 10 January, 2003, including two articles,
"Effective Enterprise Java" and "Java/.NET Interoperability".
</p>
        <p>
Given that both of those "articles" are summaries from <em>presentations</em> I've
done at conferences past, I'm a touch skeptical. In fact, it feels like those summaries
were scraped from conferences I've done in the past, and I <em>certainly</em> don't
remember ever giving Sys-Con (or any other conference) the right to reprint my presentation
as an article.
</p>
        <p>
Then it turns out that apparently <a href="http://aralbalkan.com/2284" target="_blank">I'm
not the only one suffering this problem</a>. Go. Read that article, then come back.
I promise, I'll wait.
</p>
        <p>
(Seriously, go read it.)
</p>
        <p>
Wow. Just... wow. If even <em>half</em> of what Aral's story is true (and I'm inclined
to believe at least part of it, given that he's done some pretty meticulous documentation
of at least his side of the story), then this is beyond outrageous, and squarely into
"completely unethical".
</p>
        <p>
Now, I'll be the first to admit, I've not heard back from Sys-Con about any of this,
so if I get any sort of response I'll be sure to update this blog post. But...
</p>
        <p>
          <em>Calling anyone a "homosexual son of a bitch", "terrorist"
or "fag" is so unbelievably offensive it staggers the mind.</em> Normally,
I'd be a bit hesitant to just give either party the benefit of the doubt on that one,
given just how ludicrous the accusation sounds, but Aral includes screen shots of
the articles, which in of itself lends an air of credibility to the accusation—either
Aral is the world's worst Turkish translator, or Sys-Con's translation into Turkish
is a bit on the "edgy" side, or Sys-Con really did call him that. Which
implies that whichever way this goes, doesn't look good for one of the two parties.
But even if we leave that to one side....
</p>
        <p>
          <em>Sys-Con is playing with fire by collecting my content and claiming me as an author.</em> Sys-Con
never contacted me about becoming a part of their "Ulitzer" website. They
never asked me for permission to reprint my articles, though, I'll admit, I can't
find where the articles actually exist, nor links to the articles, so maybe they didn't,
actually, reprint the article, but just link to them... except I can't find the links
to the articles or the presentations, either. They never asked me for an updated bio
or photo, and in fact, they pretty clearly grabbed both bio, photo and "summaries"
from an old location, because that bio lists me as a DevelopMentor instructor (which
I haven't been for two years or so), and as living in Sacramento, CA (which I haven't
been for about three years or so). Let me be very clear about this: <strong>I do not
write for Sys-Con Media. I never have. They have never asked permission to reuse any
of the content I have produced. I am appalled at being included in such a fashion.</strong></p>
        <p>
Note that I'm not opposed to being linked to, mind you—if I put material on my blog,
I generally expect (and hope) that people will link to it, and I don't demand permission
or even notification when it happens. But to claim that I've written material for
an entity <em>does</em> mean I expect to at least be asked if it's OK to use my likeness,
name, or material. No such request was ever made of me, so far as I can remember or
find (through my own email archives, which stretch back to 2001).
</p>
        <p>
And I can say that I've thought about this issue before, from the other side of the
story—back when I was editor at TheServerSide.NET, we began a "blogger's program"
that would take interesting blog posts from around the Internet and "collect"
them in some fashion for TSS.NET readers. Originally, the thought was to simply reproduce
the content directly on our site, and I hated that idea, for the same reasons as I
dislike it when somebody does it to me. Regardless of the licensing model the blog
entries are published under, to me, a publication or media firm owes the author at
least the right of refusal, and a chance to be notified when their material is reused.
(In the end, we chose to ask authors if we could reproduce their material in the program,
and we never (to my knowledge) had an author refuse.) It doesn't take a real rocket
scientist's brain to figure out that asking permission is never a bad thing to do
if you want to maintain good will with your sources of material.
</p>
        <p>
This is an open and public request to Sys-Con media: either contact me about using
my name, likeness and material on your website, or remove it. (I have emailed their
editorial and asked them to acknowledge receipt of my request.)
</p>
        <p>
In the meantime, I will be making every effort to make sure that other content-producers
I know are aware of Sys-Con's practices, so they can act as they see fit.
</p>
        <p>
If you are a reader, and find this distasteful as well, then I suggest you follow
some of the suggestions mentioned in Aral's blog post:
</p>
        <ul>
          <ul>
            <li>
Tell everyone you know about what Sys-Con is doing (but don't link to them so as not
to give them Google Juice). If tweeting, leave out the http:// bit so that your URL
is not automatically made into a link. 
</li>
            <li>
Sys-Con feeds upon the work of authors and speakers to live. If all authors had their
content removed from Sys-Con and Ulitzer, they would not have pages to put ads on.
So go through their list of authors and notify the ones you know. If they are unaware
that they're listed there, they will most likely want themselves removed. <strong>Update:</strong> I've
created a single list of all Sys-Con's Ulitzer authors. <a href="http://aralbalkan.com/2303">More
information and the full list are in this post</a>. The original list of authors is
at http://www.ulitzer.com/?q=authors. You can ask for your Ulitzer/Sys-Con author
page to be removed by emailing <a href="mailto:editorial@sys-con.com">editorial@sys-con.com</a>. 
</li>
            <li>
Contact their advertisers and tell them what you think of their association with Sys-Con. 
</li>
            <li>
If you know any speakers speaking at Sys-Con events, make sure they know the kind
of company they are associating themselves with. Do the same with anyone you know
who is thinking of attending one of their events. Raise awareness about their events
at your place of work. 
</li>
            <li>
Make sure Google knows that Sys-Con/Ulitzer is spamming Google with tons of duplicate
content. <a href="http://www.google.com/contact/spamreport.html">Report them on Google's
spam page for posting duplicate content</a>. According to their terms and conditions,
Google should stop indexing Sys-Con/Ulitzer. <a href="http://aralbalkan.com/2284#comment-256711">See
this comment for a template you can use when reporting them.</a></li>
            <li>
Make sure Google News knows that they are syndicating libelous articles from Sys-Con.
Use the <a href="http://www.google.com/support/news_pub/bin/request.py?contact_type=report_an_issue">Google
News Report an Issue form</a> to report the following articles: http://internetvideo.sys-con.com/node/1017038,
http://internetvideo.sys-con.com/node/1028923, http://www.sys-con.com/node/1035252,
http://air.ulitzer.com/node/1038383, http://openwebdeveloper.sys-con.com/node/1039556,
and http://cloudcomputing.sys-con.com/node/1047589 
</li>
          </ul>
        </ul>
        <p>
Meanwhile, I'm going to be talking about this to everybody I know at Microsoft, desperately
seeking to find out which department engaged the advertising with Sys-Con, and looking
to convince them that they don't need this kind of press or association. Ditto for
the contacts (far fewer in number) I have with IBM, and any other Sys-Con advertiser
I find.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=3026e434-b1c8-4525-816a-2efcd5d2a6e6" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>More on journalistic integrity: Sys-Con, Ulitzer, theft and libel</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,3026e434-b1c8-4525-816a-2efcd5d2a6e6.aspx</guid>
      <link>http://blogs.tedneward.com/2009/07/29/More+On+Journalistic+Integrity+SysCon+Ulitzer+Theft+And+Libel.aspx</link>
      <pubDate>Wed, 29 Jul 2009 01:58:00 GMT</pubDate>
      <description>&lt;p&gt;
Recently, an email crossed my Inbox from a friend who was concerned about some questionable
practices involving my content (as well as a few others'); apparently, I have been
listed as an &amp;quot;author&amp;quot; for SysCon, I have a &amp;quot;domain&amp;quot; with them,
and that I've been writing for them since 10 January, 2003, including two articles,
&amp;quot;Effective Enterprise Java&amp;quot; and &amp;quot;Java/.NET Interoperability&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
Given that both of those &amp;quot;articles&amp;quot; are summaries from &lt;em&gt;presentations&lt;/em&gt; I've
done at conferences past, I'm a touch skeptical. In fact, it feels like those summaries
were scraped from conferences I've done in the past, and I &lt;em&gt;certainly&lt;/em&gt; don't
remember ever giving Sys-Con (or any other conference) the right to reprint my presentation
as an article.
&lt;/p&gt;
&lt;p&gt;
Then it turns out that apparently &lt;a href="http://aralbalkan.com/2284" target="_blank"&gt;I'm
not the only one suffering this problem&lt;/a&gt;. Go. Read that article, then come back.
I promise, I'll wait.
&lt;/p&gt;
&lt;p&gt;
(Seriously, go read it.)
&lt;/p&gt;
&lt;p&gt;
Wow. Just... wow. If even &lt;em&gt;half&lt;/em&gt; of what Aral's story is true (and I'm inclined
to believe at least part of it, given that he's done some pretty meticulous documentation
of at least his side of the story), then this is beyond outrageous, and squarely into
&amp;quot;completely unethical&amp;quot;.
&lt;/p&gt;
&lt;p&gt;
Now, I'll be the first to admit, I've not heard back from Sys-Con about any of this,
so if I get any sort of response I'll be sure to update this blog post. But...
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Calling anyone a &amp;quot;homosexual son of a bitch&amp;quot;, &amp;quot;terrorist&amp;quot;
or &amp;quot;fag&amp;quot; is so unbelievably offensive it staggers the mind.&lt;/em&gt; Normally,
I'd be a bit hesitant to just give either party the benefit of the doubt on that one,
given just how ludicrous the accusation sounds, but Aral includes screen shots of
the articles, which in of itself lends an air of credibility to the accusation—either
Aral is the world's worst Turkish translator, or Sys-Con's translation into Turkish
is a bit on the &amp;quot;edgy&amp;quot; side, or Sys-Con really did call him that. Which
implies that whichever way this goes, doesn't look good for one of the two parties.
But even if we leave that to one side....
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Sys-Con is playing with fire by collecting my content and claiming me as an author.&lt;/em&gt; Sys-Con
never contacted me about becoming a part of their &amp;quot;Ulitzer&amp;quot; website. They
never asked me for permission to reprint my articles, though, I'll admit, I can't
find where the articles actually exist, nor links to the articles, so maybe they didn't,
actually, reprint the article, but just link to them... except I can't find the links
to the articles or the presentations, either. They never asked me for an updated bio
or photo, and in fact, they pretty clearly grabbed both bio, photo and &amp;quot;summaries&amp;quot;
from an old location, because that bio lists me as a DevelopMentor instructor (which
I haven't been for two years or so), and as living in Sacramento, CA (which I haven't
been for about three years or so). Let me be very clear about this: &lt;strong&gt;I do not
write for Sys-Con Media. I never have. They have never asked permission to reuse any
of the content I have produced. I am appalled at being included in such a fashion.&lt;/strong&gt; 
&lt;/p&gt;
&lt;p&gt;
Note that I'm not opposed to being linked to, mind you—if I put material on my blog,
I generally expect (and hope) that people will link to it, and I don't demand permission
or even notification when it happens. But to claim that I've written material for
an entity &lt;em&gt;does&lt;/em&gt; mean I expect to at least be asked if it's OK to use my likeness,
name, or material. No such request was ever made of me, so far as I can remember or
find (through my own email archives, which stretch back to 2001).
&lt;/p&gt;
&lt;p&gt;
And I can say that I've thought about this issue before, from the other side of the
story—back when I was editor at TheServerSide.NET, we began a &amp;quot;blogger's program&amp;quot;
that would take interesting blog posts from around the Internet and &amp;quot;collect&amp;quot;
them in some fashion for TSS.NET readers. Originally, the thought was to simply reproduce
the content directly on our site, and I hated that idea, for the same reasons as I
dislike it when somebody does it to me. Regardless of the licensing model the blog
entries are published under, to me, a publication or media firm owes the author at
least the right of refusal, and a chance to be notified when their material is reused.
(In the end, we chose to ask authors if we could reproduce their material in the program,
and we never (to my knowledge) had an author refuse.) It doesn't take a real rocket
scientist's brain to figure out that asking permission is never a bad thing to do
if you want to maintain good will with your sources of material.
&lt;/p&gt;
&lt;p&gt;
This is an open and public request to Sys-Con media: either contact me about using
my name, likeness and material on your website, or remove it. (I have emailed their
editorial and asked them to acknowledge receipt of my request.)
&lt;/p&gt;
&lt;p&gt;
In the meantime, I will be making every effort to make sure that other content-producers
I know are aware of Sys-Con's practices, so they can act as they see fit.
&lt;/p&gt;
&lt;p&gt;
If you are a reader, and find this distasteful as well, then I suggest you follow
some of the suggestions mentioned in Aral's blog post:
&lt;/p&gt;
&lt;ul&gt;
&lt;ul&gt;
&lt;li&gt;
Tell everyone you know about what Sys-Con is doing (but don't link to them so as not
to give them Google Juice). If tweeting, leave out the http:// bit so that your URL
is not automatically made into a link. 
&lt;/li&gt;
&lt;li&gt;
Sys-Con feeds upon the work of authors and speakers to live. If all authors had their
content removed from Sys-Con and Ulitzer, they would not have pages to put ads on.
So go through their list of authors and notify the ones you know. If they are unaware
that they're listed there, they will most likely want themselves removed. &lt;strong&gt;Update:&lt;/strong&gt; I've
created a single list of all Sys-Con's Ulitzer authors. &lt;a href="http://aralbalkan.com/2303"&gt;More
information and the full list are in this post&lt;/a&gt;. The original list of authors is
at http://www.ulitzer.com/?q=authors. You can ask for your Ulitzer/Sys-Con author
page to be removed by emailing &lt;a href="mailto:editorial@sys-con.com"&gt;editorial@sys-con.com&lt;/a&gt;. 
&lt;/li&gt;
&lt;li&gt;
Contact their advertisers and tell them what you think of their association with Sys-Con. 
&lt;/li&gt;
&lt;li&gt;
If you know any speakers speaking at Sys-Con events, make sure they know the kind
of company they are associating themselves with. Do the same with anyone you know
who is thinking of attending one of their events. Raise awareness about their events
at your place of work. 
&lt;/li&gt;
&lt;li&gt;
Make sure Google knows that Sys-Con/Ulitzer is spamming Google with tons of duplicate
content. &lt;a href="http://www.google.com/contact/spamreport.html"&gt;Report them on Google's
spam page for posting duplicate content&lt;/a&gt;. According to their terms and conditions,
Google should stop indexing Sys-Con/Ulitzer. &lt;a href="http://aralbalkan.com/2284#comment-256711"&gt;See
this comment for a template you can use when reporting them.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Make sure Google News knows that they are syndicating libelous articles from Sys-Con.
Use the &lt;a href="http://www.google.com/support/news_pub/bin/request.py?contact_type=report_an_issue"&gt;Google
News Report an Issue form&lt;/a&gt; to report the following articles: http://internetvideo.sys-con.com/node/1017038,
http://internetvideo.sys-con.com/node/1028923, http://www.sys-con.com/node/1035252,
http://air.ulitzer.com/node/1038383, http://openwebdeveloper.sys-con.com/node/1039556,
and http://cloudcomputing.sys-con.com/node/1047589 
&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;
Meanwhile, I'm going to be talking about this to everybody I know at Microsoft, desperately
seeking to find out which department engaged the advertising with Sys-Con, and looking
to convince them that they don't need this kind of press or association. Ditto for
the contacts (far fewer in number) I have with IBM, and any other Sys-Con advertiser
I find.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=3026e434-b1c8-4525-816a-2efcd5d2a6e6" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,3026e434-b1c8-4525-816a-2efcd5d2a6e6.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>F#</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Security</category>
      <category>Social</category>
      <category>VMWare</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=256ef373-ecd5-47c8-b4c4-a794e04e663c</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,256ef373-ecd5-47c8-b4c4-a794e04e663c.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,256ef373-ecd5-47c8-b4c4-a794e04e663c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=256ef373-ecd5-47c8-b4c4-a794e04e663c</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This <a href="http://www.techcrunch.com/2009/07/14/in-our-inbox-hundreds-of-confidential-twitter-documents/" target="_blank">post
from TechCrunch</a> crossed my attention inbox today, and I find myself quite flummoxed
on the subject of how I think I should react.
</p>
        <p>
Assume you have managed, through no overt work on your part (meaning, you didn't explicitly
solicit, ask, or otherwise endeavor to obtain), to get ownership of "hundreds
of confidential corporate and personal documents" for a company. Assume further
that these documents are genuine—there is little to no chance that they could have
been forged or fabricated. The documents span a range of sensitivity, from documents
that are "somewhat embarrassing to various individuals, but not otherwise interesting",
to documents that "show floorplans and security passcodes to get into the Twitter
offices", to documents "showing financial projections, product plans and
notes from executive strategy meetings". In other words, documents that yes,
could create a certain amount of havoc to the corporate entity in question, could
embarrass individuals within (and not within) that company, and documents that could
lead to a competitive advantage for the entity's competitors.
</p>
        <p>
Now also assume, for the purpose of the discussion, that you are an entity whose business
model or <em>raison d'etre</em> is to publish—you are a blogger, a "social networking
maven", a media outlet, whatever.
</p>
        <p>
Is it unethical to publish these documents? Is it simply trolling for hits? Is there
a "journalistic responsibility" to publish this material?
</p>
        <p>
The people from TechCrunch feel like they have a right/responsibility to publish at
least some of the documents, and are unswayed by the arguments in the blog's comments
about the morality of such a move, including such comments as "This is an a**hole
move" and "there's still an appearance of lapse of ethics here" (and
that's just within the first half-dozen comments or so". What is particularly
interesting is the response from (someone I assume to be) one of the blog's owners:
</p>
        <blockquote>
          <p>
lol. if we only posted things that companies gave us permission to post this would
be a press release site and none of you would be here. News is stuff someone doesn’t
want you to write. The rest is advertising.
</p>
        </blockquote>
        <p>
This comment disturbs me on several levels—it's only news if it's "stuff someone
doesn't want you to write"? That's a pretty shallow and narrowly-defined sense
of the term, if you ask me, and it puts periodicals like National Enquirer and Star
magazines on the same level as the New York Times and CNN. (Although, and I'll freely
admit this, having just come through the Michael Jackson media blitz, sometimes it
feels difficult to tell the difference between all four of those.)
</p>
        <p>
At the same time, though, it's clear from our own history that journalism has served
the public good by shining a bright light into shady corners that some powers-that-be
would prefer left unexposed. The abuses described by Upton Sinclair in the turn-of-the-century
factories, the rampant sexual harassment in the military exposed by the Tailhook scandal,
and certainly the outright blatantly violent suppression of Civil Rights movement
of the 60's in the South were all shining examples of journalism at its finest, showing
off dark and ugly parts of the world and—either implicitly or explicitly—demanding
society to acknowledge it and either openly accept it or strive to change it (with
all three of my examples seeing society choosing the latter).
</p>
        <p>
What is "journalistic responsibility" here?
</p>
        <p>
In our chosen field—that of computer science and software—there is clearly a responsibility
for those "in the know" to reveal scenarios where information is being purloined
or made available that violates individuals' rights to privacy. It's one thing if
I trade my personal sales habits to a grocery store chain in exchange for a percentage
off the final sale. That's a choice I'm making, consciously and knowingly. (By this
point, if you haven't figured that out, you're just deliberately hiding from the fact.)
But for somebody else to disclose my purchasing history <em>without my consent</em> to
another party, that's brushing a very ugly moral dark area. And if a company is choosing
to take its customers' personal data and make it available for anyone else to use
as they see fit—for whatever purpose that third party can imagine—then cheers and
kudos to the whistle-blower who brings media attention on that behavior.
</p>
        <p>
But Twitter doesn't have much of my personal data, and they certainly didn't give
it away to anybody—it was stolen from them, according to what I've read so far. What's
more, I don't really have that much personal data stored with them—certainly no credit
cards, birthdates, financial or medical information, or even family notes. What's
there is actually pretty tame, as a Twitter customer.
</p>
        <p>
(Twitter employees are a totally different matter. Admittedly. But let's just stick
with the Twitter customer data for now.)
</p>
        <p>
So where is the "journalistic responsibility" in publishing this material?
</p>
        <p>
And are bloggers journalists? Should they be held to the same standards as journalists?
And if not, then with all these formerly print-only media moving to the Internet and
putting more and more of their material online, where do we draw that line? What's
the difference between Fareed Zakaria writing a column on Middle East affairs for
Newsweek.com on a monthly basis and Joe Sixpack posting a monthly rant on the illegal
and illicit activities of his hometown rival's sports team? Is it just the domain
name? And if Joe Sixpack decides to say, point blank, "TechCrunch paid for that
material, they hired the guy who broke into the Twitter offices and stole it"
on his blog, what avenues does TechCrunch have to decry and/or reverse that trend?
</p>
        <p>
For the record, I oppose what TechCrunch is doing <em>except</em> if there is some
blatantly legal violation of consumers' privacy. Frankly, if the hacker had approached
me with those documents, I'd be working with the FBI to see the guy tossed in jail,
because folks, if he did it to them, he could just as easily do it to you.
</p>
        <p>
But this still leaves the deeper question about where bloggers sit in the journalistic
continuum, and I admit, I have a lot of mixed feelings on the subject.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=256ef373-ecd5-47c8-b4c4-a794e04e663c" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>What is &amp;quot;news&amp;quot;, and what is &amp;quot;unethical&amp;quot;?</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,256ef373-ecd5-47c8-b4c4-a794e04e663c.aspx</guid>
      <link>http://blogs.tedneward.com/2009/07/15/What+Is+Quotnewsquot+And+What+Is+Quotunethicalquot.aspx</link>
      <pubDate>Wed, 15 Jul 2009 08:35:50 GMT</pubDate>
      <description>&lt;p&gt;
This &lt;a href="http://www.techcrunch.com/2009/07/14/in-our-inbox-hundreds-of-confidential-twitter-documents/" target="_blank"&gt;post
from TechCrunch&lt;/a&gt; crossed my attention inbox today, and I find myself quite flummoxed
on the subject of how I think I should react.
&lt;/p&gt;
&lt;p&gt;
Assume you have managed, through no overt work on your part (meaning, you didn't explicitly
solicit, ask, or otherwise endeavor to obtain), to get ownership of &amp;quot;hundreds
of confidential corporate and personal documents&amp;quot; for a company. Assume further
that these documents are genuine—there is little to no chance that they could have
been forged or fabricated. The documents span a range of sensitivity, from documents
that are &amp;quot;somewhat embarrassing to various individuals, but not otherwise interesting&amp;quot;,
to documents that &amp;quot;show floorplans and security passcodes to get into the Twitter
offices&amp;quot;, to documents &amp;quot;showing financial projections, product plans and
notes from executive strategy meetings&amp;quot;. In other words, documents that yes,
could create a certain amount of havoc to the corporate entity in question, could
embarrass individuals within (and not within) that company, and documents that could
lead to a competitive advantage for the entity's competitors.
&lt;/p&gt;
&lt;p&gt;
Now also assume, for the purpose of the discussion, that you are an entity whose business
model or &lt;em&gt;raison d'etre&lt;/em&gt; is to publish—you are a blogger, a &amp;quot;social networking
maven&amp;quot;, a media outlet, whatever.
&lt;/p&gt;
&lt;p&gt;
Is it unethical to publish these documents? Is it simply trolling for hits? Is there
a &amp;quot;journalistic responsibility&amp;quot; to publish this material?
&lt;/p&gt;
&lt;p&gt;
The people from TechCrunch feel like they have a right/responsibility to publish at
least some of the documents, and are unswayed by the arguments in the blog's comments
about the morality of such a move, including such comments as &amp;quot;This is an a**hole
move&amp;quot; and &amp;quot;there's still an appearance of lapse of ethics here&amp;quot; (and
that's just within the first half-dozen comments or so&amp;quot;. What is particularly
interesting is the response from (someone I assume to be) one of the blog's owners:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
lol. if we only posted things that companies gave us permission to post this would
be a press release site and none of you would be here. News is stuff someone doesn’t
want you to write. The rest is advertising.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
This comment disturbs me on several levels—it's only news if it's &amp;quot;stuff someone
doesn't want you to write&amp;quot;? That's a pretty shallow and narrowly-defined sense
of the term, if you ask me, and it puts periodicals like National Enquirer and Star
magazines on the same level as the New York Times and CNN. (Although, and I'll freely
admit this, having just come through the Michael Jackson media blitz, sometimes it
feels difficult to tell the difference between all four of those.)
&lt;/p&gt;
&lt;p&gt;
At the same time, though, it's clear from our own history that journalism has served
the public good by shining a bright light into shady corners that some powers-that-be
would prefer left unexposed. The abuses described by Upton Sinclair in the turn-of-the-century
factories, the rampant sexual harassment in the military exposed by the Tailhook scandal,
and certainly the outright blatantly violent suppression of Civil Rights movement
of the 60's in the South were all shining examples of journalism at its finest, showing
off dark and ugly parts of the world and—either implicitly or explicitly—demanding
society to acknowledge it and either openly accept it or strive to change it (with
all three of my examples seeing society choosing the latter).
&lt;/p&gt;
&lt;p&gt;
What is &amp;quot;journalistic responsibility&amp;quot; here?
&lt;/p&gt;
&lt;p&gt;
In our chosen field—that of computer science and software—there is clearly a responsibility
for those &amp;quot;in the know&amp;quot; to reveal scenarios where information is being purloined
or made available that violates individuals' rights to privacy. It's one thing if
I trade my personal sales habits to a grocery store chain in exchange for a percentage
off the final sale. That's a choice I'm making, consciously and knowingly. (By this
point, if you haven't figured that out, you're just deliberately hiding from the fact.)
But for somebody else to disclose my purchasing history &lt;em&gt;without my consent&lt;/em&gt; to
another party, that's brushing a very ugly moral dark area. And if a company is choosing
to take its customers' personal data and make it available for anyone else to use
as they see fit—for whatever purpose that third party can imagine—then cheers and
kudos to the whistle-blower who brings media attention on that behavior.
&lt;/p&gt;
&lt;p&gt;
But Twitter doesn't have much of my personal data, and they certainly didn't give
it away to anybody—it was stolen from them, according to what I've read so far. What's
more, I don't really have that much personal data stored with them—certainly no credit
cards, birthdates, financial or medical information, or even family notes. What's
there is actually pretty tame, as a Twitter customer.
&lt;/p&gt;
&lt;p&gt;
(Twitter employees are a totally different matter. Admittedly. But let's just stick
with the Twitter customer data for now.)
&lt;/p&gt;
&lt;p&gt;
So where is the &amp;quot;journalistic responsibility&amp;quot; in publishing this material?
&lt;/p&gt;
&lt;p&gt;
And are bloggers journalists? Should they be held to the same standards as journalists?
And if not, then with all these formerly print-only media moving to the Internet and
putting more and more of their material online, where do we draw that line? What's
the difference between Fareed Zakaria writing a column on Middle East affairs for
Newsweek.com on a monthly basis and Joe Sixpack posting a monthly rant on the illegal
and illicit activities of his hometown rival's sports team? Is it just the domain
name? And if Joe Sixpack decides to say, point blank, &amp;quot;TechCrunch paid for that
material, they hired the guy who broke into the Twitter offices and stole it&amp;quot;
on his blog, what avenues does TechCrunch have to decry and/or reverse that trend?
&lt;/p&gt;
&lt;p&gt;
For the record, I oppose what TechCrunch is doing &lt;em&gt;except&lt;/em&gt; if there is some
blatantly legal violation of consumers' privacy. Frankly, if the hacker had approached
me with those documents, I'd be working with the FBI to see the guy tossed in jail,
because folks, if he did it to them, he could just as easily do it to you.
&lt;/p&gt;
&lt;p&gt;
But this still leaves the deeper question about where bloggers sit in the journalistic
continuum, and I admit, I have a lot of mixed feelings on the subject.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=256ef373-ecd5-47c8-b4c4-a794e04e663c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,256ef373-ecd5-47c8-b4c4-a794e04e663c.aspx</comments>
      <category>Industry</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Social</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=eb632e02-f7de-43ce-a9fe-8c857b0b2554</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,eb632e02-f7de-43ce-a9fe-8c857b0b2554.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,eb632e02-f7de-43ce-a9fe-8c857b0b2554.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=eb632e02-f7de-43ce-a9fe-8c857b0b2554</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
OK, OK, I admit it. Maybe significant whitespace isn't all bad. (But don't let me
ever catch you quoting me say that.)
</p>
        <p>
The reason for my (maybe) shift in thinking? Manning Publications sent me a copy of <em>Iron
Python in Action</em>, and I have to say, I like the book and its approach. Getting
me to like Python as a primary language for development will probably take more than
just one book can give, but... *shrug* Who knows?
</p>
        <p>
Bear in mind, I have plenty of reasons to like IronPython (Microsoft's Python implementation
for the .NET environment):
</p>
        <ul>
          <li>
A good friend of mine, Harry Pierson (aka @DevHawk), is the PM on the IPy project,
and I'm generally prejudiced in favor of those things that people I know and respect.</li>
          <li>
I'm generally a fan of dynamic languages, particularly those that let you do strange
and twisted things to the type system and its instances at runtime. (Yes, I'm looking
at you, ECMAScript...)</li>
          <li>
I spent some quality time with IronPython Studio last year while researching a Visual
Studio Extensibility "Deep Dive" paper.</li>
          <li>
I've known Jim Hugunin (the creator of IronPython, and Jython before that) for some
years, ever since his days working on AspectJ, and he's one of those scary-smart guys
that, despite knowing they're scary-smart, still render me stunned when I listen to
them.</li>
          <li>
I'm a huge fan of the DLR. It's like having Parrot, but without having to wait a decade
(give or take).</li>
        </ul>
        <p>
But, just to counterbalance the scales, I have plenty of good reasons to dislike IronPython,
too:
</p>
        <ul>
          <li>
Significant whitespace.</li>
          <li>
The "There's only one way to do it" oath that Pythonistas seem to hold as
religion. (Somebody told me that building C-Python—the original implementation—only
works for you if you swear a holy oath to The One True Way on the One True Way Bible.
Needless to say, I believe them, and have never tried to build C-Python from sources
as a result.)</li>
          <li>
Significant whitespace.</li>
          <li>
Uh.... did I mention significant whitespace yet?</li>
        </ul>
        <p>
I admit, it was with some hesitation that I cracked open the book. Actually, to be
honest, I was really ready to just take out all my dislike of significant whitespace
and pour it into a heated, vitriolic diatribe on everything that was just <em>wrong</em> with
Python.
</p>
        <p>
And...?
</p>
        <p>
Well, OK, I admit it. Maybe significant whitespace isn't all bad.
</p>
        <p>
But this is a review of the book, not the technology. So, on we go.
</p>
        <h3>What I liked about the book
</h3>
        <ul>
          <li>
The focus is on both .NET and Python, and doesn't try to short-change either the "Python"-ness
or the ".NET'-ness by trying to be a "Python book (that happens to run on
.NET)" or a ".NET book (that happens to use Python for code samples)".
The authors, I think, did a very good job of balancing the two, making this <em>the</em> book
to get if you're in that area on the Venn diagram where "Python" overlaps
with ".NET".</li>
          <li>
Part 2, <em>"Core development techniques"</em>, starts down the "feed
you the Python Kool-Ade" pretty quickly, heading straight into Chapter 4 ("<em>Writing
an application and design patterns with IronPython"</em>) without much of a pause
for breath. The authors get into duck typing, protocols, and Model-View-Controller
within the first four pages, and begin working on a running example to highlight some
of the ideas. (Interestingly enough, they also take a few moments to point out that
IronPython on Mono works, and include a couple of screen shots to that effect as we
go, though I personally wonder just how many people are really going down this path.)
I like the no-holds-barred, show-you-the-code style, but only because they also take
time throughout the prose to talk about some of the concepts at work underneath and
laced throughout the code. "Show me then tell me" is a time-honored tradition,
but too many authors forget the "tell me" part and stop with code. These
guys do a good job of following through.</li>
          <li>
The chapters in Part 3, "<em>IronPython and advanced .NET</em>", form an
interesting collection of how IronPython can fit into the rest of the .NET stack,
demonstrating how to use IronPython with WPF, ASP.NET, and IronPython's crowning glory,
Silverlight. If you're into front-end stuff, this is the section where I think you're
going to have the most fun.</li>
          <li>
The chapters in Part 4, "<em>Reaching out with IronPython</em>", is I think
the most important part of the book, showing how to extend IronPython (chapter 14)
with C#/VB extensions (similar to how a C-Python developer would extend Python by
writing C code, but much much simpler) and the opposite—how to embed IronPython inside
of existing C#/VB applications (chapter 15), which is really an exercise in using
the DLR Hosting APIs. While the discussion in chapter 15 is good, I wish it'd had
a bit more thorough discussion of how the DLR could be hosted regardless of the scripting
language, though I admit that's pretty beyond the scope of this book (which is focused,
after all, entirely on IronPython, and as a result <em>should</em> stay focused on
how to host IPy).</li>
        </ul>
        <h3>
          <strong>What I found "Meh" about the book</strong>
        </h3>
        <ul>
          <li>
Part 1 (<em>"A new language for .NET"</em>, <em>"Introduction to Python"</em>,
and <em>".NET objects and IronPythong"</em>) does a good job of bringing
the rank beginner up to speed, getting some basic Python ideas across in the same
breath that they bring .NET home. The only problem is, it only works well if you're
neither a Python programmer nor a .NET programmer. Chapter 1, for example, does a
sort of Cannonball-into-the-pool kind of dive into Python, but dives equally into
the "Iron" parts as it does the "Python" parts. If you're either
a Pythonista or a .NETter, I suspect you're going to be tempted to flip pages pretty
quickly, and (I suspect) miss a few things. Chapter 2 is all about Python (meaning
.NETters will probably spend some time here), but it certainly doesn't feel like an
exhaustive reference, nor does Chapter 3 stand as an exhaustive discussion about all
things .NET, either. I almost wish all three chapters had been collapsed into one—suffice
it to say, I don't feel like I know the Python language, and don't feel like this
book could be my Python reference next to me as I learn it, and I know that it's not
a great .NET reference, either. Fortunately, the goal of these three chapters feels
pretty clearly to be "Teach you just enough to make you dangerous (and able to
understand the rest of the book)", and once we hit Part 2, rubber meets road
pretty quickly.</li>
          <li>
By the time you hit Chapter 7, less than halfway through the book, the authors have
created a fairly nice, if simplistic, application for later dissection, but it's not
until you hit Chapter 7 that they begin to start unit-testing, even though they insist
(on page 17) that "Dynamic language programmers are often proponents of <em>strong
testing rather than strong typing</em>" (a quote they attribute to Bruce Eckel,
though I'm relatively certain I heard Dave Thomas and Neal Ford say it with respect
to Ruby, long before Eckel started "Thinking in Python... or Flex... or whatever").
If unit-testing is that important, why wait three chapters into the application's
development before writing a single unit-test? This doesn't jibe with me, somehow.</li>
          <li>
If you're into back-end stuff, chapter 12 on <em>"Databases and web services"</em> is
pretty bland. The fact that the two are combined into a single chapter is indicative,
all by itself, of how deep or intensive the coverage goes, and there's zero mention
of anything beyond basic ADO.NET. The coverage on web services covers REST relatively
well, but there's zero coverage of WCF, and the whole of SOAP-based services is all
of four or five pages. And Workflow? Doesn't exist, isn't even mentioned (except for
an appearance in a table, "The major new APIs of .NET 3.0"). Yikes.</li>
        </ul>
        <h3>
          <strong>What I actively disliked about the book</strong>
        </h3>
        <p>
Actually, not much. Manning did their usual superb job of arrowed callouts to point
out particular concepts in the code listings, the copyediting is professional (meaning
there's no obvious typos or misspellings that just break up the flow of prose, something
that not all publishers seem to take seriously), and the graphics flow nicely alongside
the prose, not dominating the page but accentuating it.
</p>
        <p>
In fact, about the only thing I'd care to criticize is the <em>huge</em> number of
footnotes, particularly in the first chapter. (By page 20 in the book, there have
already been 30 footnotes.) When you have three footnotes <em>per page</em>, on average
(and sometimes more), it does tend to distract, at least to me it does. It feels like
there were ways, for most of them, to inject the idea or concept into the main prose,
or leave it out entirely, but that could just be a difference of writing style, too.
</p>
        <h3>
          <strong>Summation</strong>
        </h3>
        <p>
If you're a .NET developer interested in learning/using IronPython on your next project,
this is a definite winner. If you're a Python developer looking to see how to break
into .NET, I'm not so sure this is your book, but I say that mostly because I'm <em>not</em> a
Pythonista and can't really speak to how that mindset will find this as an introduction
to the .NET space. My intuition tells me that this would be a good springboard into
another book on .NET for the Python programmer, but I'll have to leave that to Pythonistas
who've read this book to comment one way or another.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=eb632e02-f7de-43ce-a9fe-8c857b0b2554" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Review: &amp;quot;Iron Python in Action&amp;quot; by Michael Foord and Christian Muirhead</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,eb632e02-f7de-43ce-a9fe-8c857b0b2554.aspx</guid>
      <link>http://blogs.tedneward.com/2009/07/01/Review+QuotIron+Python+In+Actionquot+By+Michael+Foord+And+Christian+Muirhead.aspx</link>
      <pubDate>Wed, 01 Jul 2009 09:00:14 GMT</pubDate>
      <description>&lt;p&gt;
OK, OK, I admit it. Maybe significant whitespace isn't all bad. (But don't let me
ever catch you quoting me say that.)
&lt;/p&gt;
&lt;p&gt;
The reason for my (maybe) shift in thinking? Manning Publications sent me a copy of &lt;em&gt;Iron
Python in Action&lt;/em&gt;, and I have to say, I like the book and its approach. Getting
me to like Python as a primary language for development will probably take more than
just one book can give, but... *shrug* Who knows?
&lt;/p&gt;
&lt;p&gt;
Bear in mind, I have plenty of reasons to like IronPython (Microsoft's Python implementation
for the .NET environment):
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A good friend of mine, Harry Pierson (aka @DevHawk), is the PM on the IPy project,
and I'm generally prejudiced in favor of those things that people I know and respect.&lt;/li&gt;
&lt;li&gt;
I'm generally a fan of dynamic languages, particularly those that let you do strange
and twisted things to the type system and its instances at runtime. (Yes, I'm looking
at you, ECMAScript...)&lt;/li&gt;
&lt;li&gt;
I spent some quality time with IronPython Studio last year while researching a Visual
Studio Extensibility &amp;quot;Deep Dive&amp;quot; paper.&lt;/li&gt;
&lt;li&gt;
I've known Jim Hugunin (the creator of IronPython, and Jython before that) for some
years, ever since his days working on AspectJ, and he's one of those scary-smart guys
that, despite knowing they're scary-smart, still render me stunned when I listen to
them.&lt;/li&gt;
&lt;li&gt;
I'm a huge fan of the DLR. It's like having Parrot, but without having to wait a decade
(give or take).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
But, just to counterbalance the scales, I have plenty of good reasons to dislike IronPython,
too:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Significant whitespace.&lt;/li&gt;
&lt;li&gt;
The &amp;quot;There's only one way to do it&amp;quot; oath that Pythonistas seem to hold as
religion. (Somebody told me that building C-Python—the original implementation—only
works for you if you swear a holy oath to The One True Way on the One True Way Bible.
Needless to say, I believe them, and have never tried to build C-Python from sources
as a result.)&lt;/li&gt;
&lt;li&gt;
Significant whitespace.&lt;/li&gt;
&lt;li&gt;
Uh.... did I mention significant whitespace yet?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I admit, it was with some hesitation that I cracked open the book. Actually, to be
honest, I was really ready to just take out all my dislike of significant whitespace
and pour it into a heated, vitriolic diatribe on everything that was just &lt;em&gt;wrong&lt;/em&gt; with
Python.
&lt;/p&gt;
&lt;p&gt;
And...?
&lt;/p&gt;
&lt;p&gt;
Well, OK, I admit it. Maybe significant whitespace isn't all bad.
&lt;/p&gt;
&lt;p&gt;
But this is a review of the book, not the technology. So, on we go.
&lt;/p&gt;
&lt;h3&gt;What I liked about the book
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
The focus is on both .NET and Python, and doesn't try to short-change either the &amp;quot;Python&amp;quot;-ness
or the &amp;quot;.NET'-ness by trying to be a &amp;quot;Python book (that happens to run on
.NET)&amp;quot; or a &amp;quot;.NET book (that happens to use Python for code samples)&amp;quot;.
The authors, I think, did a very good job of balancing the two, making this &lt;em&gt;the&lt;/em&gt; book
to get if you're in that area on the Venn diagram where &amp;quot;Python&amp;quot; overlaps
with &amp;quot;.NET&amp;quot;.&lt;/li&gt;
&lt;li&gt;
Part 2, &lt;em&gt;&amp;quot;Core development techniques&amp;quot;&lt;/em&gt;, starts down the &amp;quot;feed
you the Python Kool-Ade&amp;quot; pretty quickly, heading straight into Chapter 4 (&amp;quot;&lt;em&gt;Writing
an application and design patterns with IronPython&amp;quot;&lt;/em&gt;) without much of a pause
for breath. The authors get into duck typing, protocols, and Model-View-Controller
within the first four pages, and begin working on a running example to highlight some
of the ideas. (Interestingly enough, they also take a few moments to point out that
IronPython on Mono works, and include a couple of screen shots to that effect as we
go, though I personally wonder just how many people are really going down this path.)
I like the no-holds-barred, show-you-the-code style, but only because they also take
time throughout the prose to talk about some of the concepts at work underneath and
laced throughout the code. &amp;quot;Show me then tell me&amp;quot; is a time-honored tradition,
but too many authors forget the &amp;quot;tell me&amp;quot; part and stop with code. These
guys do a good job of following through.&lt;/li&gt;
&lt;li&gt;
The chapters in Part 3, &amp;quot;&lt;em&gt;IronPython and advanced .NET&lt;/em&gt;&amp;quot;, form an
interesting collection of how IronPython can fit into the rest of the .NET stack,
demonstrating how to use IronPython with WPF, ASP.NET, and IronPython's crowning glory,
Silverlight. If you're into front-end stuff, this is the section where I think you're
going to have the most fun.&lt;/li&gt;
&lt;li&gt;
The chapters in Part 4, &amp;quot;&lt;em&gt;Reaching out with IronPython&lt;/em&gt;&amp;quot;, is I think
the most important part of the book, showing how to extend IronPython (chapter 14)
with C#/VB extensions (similar to how a C-Python developer would extend Python by
writing C code, but much much simpler) and the opposite—how to embed IronPython inside
of existing C#/VB applications (chapter 15), which is really an exercise in using
the DLR Hosting APIs. While the discussion in chapter 15 is good, I wish it'd had
a bit more thorough discussion of how the DLR could be hosted regardless of the scripting
language, though I admit that's pretty beyond the scope of this book (which is focused,
after all, entirely on IronPython, and as a result &lt;em&gt;should&lt;/em&gt; stay focused on
how to host IPy).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;What I found &amp;quot;Meh&amp;quot; about the book&lt;/strong&gt;
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
Part 1 (&lt;em&gt;&amp;quot;A new language for .NET&amp;quot;&lt;/em&gt;, &lt;em&gt;&amp;quot;Introduction to Python&amp;quot;&lt;/em&gt;,
and &lt;em&gt;&amp;quot;.NET objects and IronPythong&amp;quot;&lt;/em&gt;) does a good job of bringing
the rank beginner up to speed, getting some basic Python ideas across in the same
breath that they bring .NET home. The only problem is, it only works well if you're
neither a Python programmer nor a .NET programmer. Chapter 1, for example, does a
sort of Cannonball-into-the-pool kind of dive into Python, but dives equally into
the &amp;quot;Iron&amp;quot; parts as it does the &amp;quot;Python&amp;quot; parts. If you're either
a Pythonista or a .NETter, I suspect you're going to be tempted to flip pages pretty
quickly, and (I suspect) miss a few things. Chapter 2 is all about Python (meaning
.NETters will probably spend some time here), but it certainly doesn't feel like an
exhaustive reference, nor does Chapter 3 stand as an exhaustive discussion about all
things .NET, either. I almost wish all three chapters had been collapsed into one—suffice
it to say, I don't feel like I know the Python language, and don't feel like this
book could be my Python reference next to me as I learn it, and I know that it's not
a great .NET reference, either. Fortunately, the goal of these three chapters feels
pretty clearly to be &amp;quot;Teach you just enough to make you dangerous (and able to
understand the rest of the book)&amp;quot;, and once we hit Part 2, rubber meets road
pretty quickly.&lt;/li&gt;
&lt;li&gt;
By the time you hit Chapter 7, less than halfway through the book, the authors have
created a fairly nice, if simplistic, application for later dissection, but it's not
until you hit Chapter 7 that they begin to start unit-testing, even though they insist
(on page 17) that &amp;quot;Dynamic language programmers are often proponents of &lt;em&gt;strong
testing rather than strong typing&lt;/em&gt;&amp;quot; (a quote they attribute to Bruce Eckel,
though I'm relatively certain I heard Dave Thomas and Neal Ford say it with respect
to Ruby, long before Eckel started &amp;quot;Thinking in Python... or Flex... or whatever&amp;quot;).
If unit-testing is that important, why wait three chapters into the application's
development before writing a single unit-test? This doesn't jibe with me, somehow.&lt;/li&gt;
&lt;li&gt;
If you're into back-end stuff, chapter 12 on &lt;em&gt;&amp;quot;Databases and web services&amp;quot;&lt;/em&gt; is
pretty bland. The fact that the two are combined into a single chapter is indicative,
all by itself, of how deep or intensive the coverage goes, and there's zero mention
of anything beyond basic ADO.NET. The coverage on web services covers REST relatively
well, but there's zero coverage of WCF, and the whole of SOAP-based services is all
of four or five pages. And Workflow? Doesn't exist, isn't even mentioned (except for
an appearance in a table, &amp;quot;The major new APIs of .NET 3.0&amp;quot;). Yikes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;What I actively disliked about the book&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
Actually, not much. Manning did their usual superb job of arrowed callouts to point
out particular concepts in the code listings, the copyediting is professional (meaning
there's no obvious typos or misspellings that just break up the flow of prose, something
that not all publishers seem to take seriously), and the graphics flow nicely alongside
the prose, not dominating the page but accentuating it.
&lt;/p&gt;
&lt;p&gt;
In fact, about the only thing I'd care to criticize is the &lt;em&gt;huge&lt;/em&gt; number of
footnotes, particularly in the first chapter. (By page 20 in the book, there have
already been 30 footnotes.) When you have three footnotes &lt;em&gt;per page&lt;/em&gt;, on average
(and sometimes more), it does tend to distract, at least to me it does. It feels like
there were ways, for most of them, to inject the idea or concept into the main prose,
or leave it out entirely, but that could just be a difference of writing style, too.
&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Summation&lt;/strong&gt;
&lt;/h3&gt;
&lt;p&gt;
If you're a .NET developer interested in learning/using IronPython on your next project,
this is a definite winner. If you're a Python developer looking to see how to break
into .NET, I'm not so sure this is your book, but I say that mostly because I'm &lt;em&gt;not&lt;/em&gt; a
Pythonista and can't really speak to how that mindset will find this as an introduction
to the .NET space. My intuition tells me that this would be a good springboard into
another book on .NET for the Python programmer, but I'll have to leave that to Pythonistas
who've read this book to comment one way or another.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=eb632e02-f7de-43ce-a9fe-8c857b0b2554" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,eb632e02-f7de-43ce-a9fe-8c857b0b2554.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>Languages</category>
      <category>Python</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Visual Basic</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=bfd09520-fc73-4358-9a87-14f433f40095</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,bfd09520-fc73-4358-9a87-14f433f40095.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,bfd09520-fc73-4358-9a87-14f433f40095.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=bfd09520-fc73-4358-9a87-14f433f40095</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <blockquote>
          <p>
            <em>
              <strong>(Disclaimer:</strong> In the spirit of full disclosure, Stu is a friend,
fellow NFJS speaker, and former co-worker of mine from DevelopMentor.)</em>
          </p>
        </blockquote>
        <p>
I present this review to you in two parts.
</p>
        <p>
          <strong>Short version:</strong> If you want to learn Clojure, and you're familiar
with at least one programming language, you'll find this a great resource. If you
don't already know a programming language, or if you already know Clojure, or if you're
looking for "best practices" to cut-and-paste, you're going to be disappointed.
</p>
        <p>
          <strong>Long version:</strong> Recently, fellow NFJS speaker Stu Halloway decided
to take up a new language, and came to Clojure. He found the language interesting
enough to write a book on it, something he hasn't done since his Java days, and the
result is a nice walk through the language and its environment for experienced Java
developers who want to understand Clojure's language, concurrency concepts, and programming
model.
</p>
        <p>
Now, let's be 100% honest about this: if you're coming at this book expecting it to
be a language reference, you will probably be disappointed (as <a href="http://www.amazon.com/review/R3NM9CKFWYFKAE/ref=cm_cr_rdp_perm" target="_blank">this
guy</a> obviously is). Stu's not like that—he's not going to re-create material that's
available elsewhere, or that can be found with an easy Google search. Stu will not
waste your time that way—he wants to tell you a story, one that takes you from "I'm
a Java guy, but clueless about Lisp, dynamic languages, functional programming, concurrency,
or macros" to "Wow. I know kung-fu." in the shortest path possible,
but without trying to lobotomize you. He wants—no, <em>expects</em>—the readers of
his book to be propping the text open with a cell phone on one side and the dinner
plate on the other, craning your neck over to scan the pages and type in the examples
into the REPL shell to try them out, see them work, then spend a few minutes experimenting
with them before moving on to the next paragraph or page. 
</p>
        <p>
(Oh, I suppose you could just cut and paste them from the PDF version of the book,
but where's the fun in that?)
</p>
        <p>
The fact is, the <em>concepts</em> behind Clojure make up what's important to learn
here, and readers of this book will come away like the panda from the movie, realizing
that "There is no Secret Ingredient", that the power of Clojure comes not
from its super-secret language sauce or special libraries, but in the way Clojure
programmers approach problems and think about programming. And for that reason, if
you're a programmer—even if you don't program on the JVM—you really want to take a
look at what Stu's talking about (and Rich Hickey is creating).
</p>
        <p>
Just remember, cellphone and dinner plate. Otherwise you'll be missing out on so much.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=bfd09520-fc73-4358-9a87-14f433f40095" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Review: &amp;quot;Programming Clojure&amp;quot;, by Stu Halloway</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,bfd09520-fc73-4358-9a87-14f433f40095.aspx</guid>
      <link>http://blogs.tedneward.com/2009/06/28/Review+QuotProgramming+Clojurequot+By+Stu+Halloway.aspx</link>
      <pubDate>Sun, 28 Jun 2009 05:34:56 GMT</pubDate>
      <description>&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;(Disclaimer:&lt;/strong&gt; In the spirit of full disclosure, Stu is a friend,
fellow NFJS speaker, and former co-worker of mine from DevelopMentor.)&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I present this review to you in two parts.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Short version:&lt;/strong&gt; If you want to learn Clojure, and you're familiar
with at least one programming language, you'll find this a great resource. If you
don't already know a programming language, or if you already know Clojure, or if you're
looking for &amp;quot;best practices&amp;quot; to cut-and-paste, you're going to be disappointed.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Long version:&lt;/strong&gt; Recently, fellow NFJS speaker Stu Halloway decided
to take up a new language, and came to Clojure. He found the language interesting
enough to write a book on it, something he hasn't done since his Java days, and the
result is a nice walk through the language and its environment for experienced Java
developers who want to understand Clojure's language, concurrency concepts, and programming
model.
&lt;/p&gt;
&lt;p&gt;
Now, let's be 100% honest about this: if you're coming at this book expecting it to
be a language reference, you will probably be disappointed (as &lt;a href="http://www.amazon.com/review/R3NM9CKFWYFKAE/ref=cm_cr_rdp_perm" target="_blank"&gt;this
guy&lt;/a&gt; obviously is). Stu's not like that—he's not going to re-create material that's
available elsewhere, or that can be found with an easy Google search. Stu will not
waste your time that way—he wants to tell you a story, one that takes you from &amp;quot;I'm
a Java guy, but clueless about Lisp, dynamic languages, functional programming, concurrency,
or macros&amp;quot; to &amp;quot;Wow. I know kung-fu.&amp;quot; in the shortest path possible,
but without trying to lobotomize you. He wants—no, &lt;em&gt;expects&lt;/em&gt;—the readers of
his book to be propping the text open with a cell phone on one side and the dinner
plate on the other, craning your neck over to scan the pages and type in the examples
into the REPL shell to try them out, see them work, then spend a few minutes experimenting
with them before moving on to the next paragraph or page. 
&lt;/p&gt;
&lt;p&gt;
(Oh, I suppose you could just cut and paste them from the PDF version of the book,
but where's the fun in that?)
&lt;/p&gt;
&lt;p&gt;
The fact is, the &lt;em&gt;concepts&lt;/em&gt; behind Clojure make up what's important to learn
here, and readers of this book will come away like the panda from the movie, realizing
that &amp;quot;There is no Secret Ingredient&amp;quot;, that the power of Clojure comes not
from its super-secret language sauce or special libraries, but in the way Clojure
programmers approach problems and think about programming. And for that reason, if
you're a programmer—even if you don't program on the JVM—you really want to take a
look at what Stu's talking about (and Rich Hickey is creating).
&lt;/p&gt;
&lt;p&gt;
Just remember, cellphone and dinner plate. Otherwise you'll be missing out on so much.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=bfd09520-fc73-4358-9a87-14f433f40095" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,bfd09520-fc73-4358-9a87-14f433f40095.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>F#</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Visual Basic</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=dd85708f-48d8-47dc-a9c6-cc4a1287ad31</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,dd85708f-48d8-47dc-a9c6-cc4a1287ad31.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,dd85708f-48d8-47dc-a9c6-cc4a1287ad31.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=dd85708f-48d8-47dc-a9c6-cc4a1287ad31</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <blockquote>
          <p>
            <strong>Update:</strong> See below, but I wanted to include the text Mike Abercrombie
(DM's owner) posted as a comment to this post, in the body of the blog post itself. <em>"Ted
- All of us at DevelopMentor greatly appreciate your admiration. We're also grateful
for your contributions to DevelopMentor when you were part of our staff. However,
all of us that work here, especially our technical staff that write and delivery our
courses today, would appreciate it if you would check your sources before writing
our eulogy. DevelopMentor is open for business and delivering courses this week and
we intend to remain doing so."</em> Duly noted, Mike. Apology offered (and hopefully
accepted).
</p>
        </blockquote>
        <p>
An email crossed my desk today, announcing that DevelopMentor, home to so many good
people and fond memories, has (at least temporarily) closed its doors.
</p>
        <p>
I admit to a small, carefully-cushioned place in my heart where I mourn over this.
</p>
        <p>
DevelopMentor was such a transcendent place for me. Much, if not most or all, of the
acceleration that came in my career came not only while I was there, but <em>because</em> I
was there.
</p>
        <p>
          <em>So</em> much of my speaking persona and skill I owe to Ron Sumida, who took a
half-baked neophyte of intermediate speaking skill, and in an eight-hour marathon
session still referred to in my mental memoirs as my "Night with Scary Ron",
shaped me and taught me tricks about speaking that I continue to use to this day.
That I got to know him as a friend and confidant later still to this day ranks as
one of my greatest blessings.
</p>
        <p>
I remember my first DM Instructor Retreat, where I met so many of the names I'd read
about or heard about, and feeling "Oh, my God" fanboy-ish. I remember Tim
Ewald giving a talk on transactions at that retreat that left me agape—I seriously
didn't understand half of what he was saying, and rather than feeling overwhelmed
or ashamed, I remember distinctly thinking, "Wow—I have found a home where I
can learn SO much more." It was like waking up one morning to find that your
writing workshop group suddenly included Neal Stephenson, Stephen Pinker, C.S. Lewis
and Ernest Hemingway. (Yes, I know those last two are dead. Work with me here.)
</p>
        <p>
I remember the day that Lorie (the ops manager at the time) called me to say that
Don Box wanted me to work with him on the C# course. I was convinced that she'd called
the wrong Ted, meaning instead to reach for Ted Pattison in her Rolodex and coming
up a few letters shy. She tartly informed me, "No, I know exactly who I'm talking
to, and are you interested or not?" How could I refuse? Help the Diety of COM
write DM's flagship course on Microsoft's flagship technology for the next decade?
"Hmm...", I say out loud, not because I needed time to think about it, but
because a thread in the back of my head says, "Is there <em>any</em> scenario
here where I say no?"
</p>
        <p>
I still fondly recall doing a Guerilla .NET at the Torrance Hilton shortly after the
.NET 1.0 release, and having a conversation with Don in my hotel room later that night;
that was when he told me "Microsoft is working on an open-source version of the
CLR". I was stunned—I had no idea that said version would factor pretty largely
in my life later. But it opened my eyes, in a very practical way, to how deeply-connected
DevelopMentor was to Microsoft, and how that could play out in a direct fashion.
</p>
        <p>
When Peter Drayton joined, he asked me to do a quick review pass on the reference
section of his <em>C# in a Nutshell</em>, and I agreed because Peter was a good guy
(and somebody I'd hoped would become a friend), and wanted to see the book do well.
That went from informal review to formal review to "well, could you maybe make
it an editing pass?" to "Would you like to write a few chapters?" to
"Well, let's sign you up as a co-author...". That project is what introduced
me to John Osborn, which in turn led him to call me one day and say, "Some guys
at Microsoft are working on an open-source version of the CLR, and would like to have
a 'professional writer' help them write a book on it. Interested?" That led to <em>SSCLI
Internals</em>, working with David Stutz, and wow, did I learn a helluvalot from <em>that</em> project,
too.
</p>
        <p>
          <em>Effective Enterprise Java</em> came through DevelopMentor, thanks again to Don
Box, who introduced me to the folks at Addison-Wesley that put the contract (and Scott
Meyers, another blessing) in front of me.
</p>
        <p>
DM got me my start in the conference circuit, as well. In 2002, John Lam pinged me
over email—he'd recently become track chair for Connections down in Orlando, and was
I interested in speaking there? I was such a newbie to the whole idea, but having
taught classes roughly twice every month, I wasn't worried about the speaking part,
but the rest of the process. John walked me through the process, and in doing so,
set me down a path that would almost completely redefine my career within a year or
so.
</p>
        <p>
Even my Java chops got built up—the head of our Java curriculum was Stu Halloway (recently
of Clojure fame), and between him, Kevin Jones, Si Horrell, Brian Maso and Owen Tallman,
man, did I feel simultaneously like a small child among giants and like a kid in a
candy store. Every time I turned around, they'd discovered something new about the
Java platform that floored me. Bob Beauchemin has forgotten more about databases in
general than I will ever learn, and he had some insights on the intersection of Java
+ databases that still hang with me today.
</p>
        <p>
And my start with No Fluff Just Stuff came through DevelopMentor, too. Jason Whittington
heard through a mutual friend (Erik Hatcher, of Ant fame) about this cool little conference
being held in Denver, and maybe I should look into it. That led to an email intro
to Jay Zimmerman, a dinner together while I was teaching in Denver a few weeks later,
and before I knew it, I was on the Denver NFJS schedule, including the speaker panel,
where I uttered the then-infamous line, "Swing sucks. Get over it."
</p>
        <p>
DevelopMentor, you shaped my career—and my life—in so many ways, you will always be
a source of pleasant memories and a group of friends and acquaintances that I would
never have had otherwise. Thank you <em>so</em> much.
</p>
        <p>
Rest in peace.
</p>
        <p>
          <strong>Update:</strong> Well, as it turns out, I have to rescind at least part of
my eulogy, as the post itself generated quite a stir—the folks at DevelopMentor were
pretty quick to email me, pointing out that they're still alive and well. In fact,
as one of them (a friend of mine still working there) put it, "We were all kinda
surprised when we came to work this morning and discovered that we could go home."
Fortunately, the DevelopMentor folks were pretty gracious about what could've been
a <em>very</em> ugly situation, and I apologize for to them for the misunderstanding—all
I can say is that my "source" must've also been mistaken, and I'm glad that
we're all still good. And lest it need to be said out loud, I <em>heartily</em> want
nothing but the best for DM, and hope that I never have to write this message again.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=dd85708f-48d8-47dc-a9c6-cc4a1287ad31" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>A eulogy: DevelopMentor, RIP</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,dd85708f-48d8-47dc-a9c6-cc4a1287ad31.aspx</guid>
      <link>http://blogs.tedneward.com/2009/06/01/A+Eulogy+DevelopMentor+RIP.aspx</link>
      <pubDate>Mon, 01 Jun 2009 06:32:07 GMT</pubDate>
      <description>&lt;blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; See below, but I wanted to include the text Mike Abercrombie
(DM's owner) posted as a comment to this post, in the body of the blog post itself. &lt;em&gt;&amp;quot;Ted
- All of us at DevelopMentor greatly appreciate your admiration. We're also grateful
for your contributions to DevelopMentor when you were part of our staff. However,
all of us that work here, especially our technical staff that write and delivery our
courses today, would appreciate it if you would check your sources before writing
our eulogy. DevelopMentor is open for business and delivering courses this week and
we intend to remain doing so.&amp;quot;&lt;/em&gt; Duly noted, Mike. Apology offered (and hopefully
accepted).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
An email crossed my desk today, announcing that DevelopMentor, home to so many good
people and fond memories, has (at least temporarily) closed its doors.
&lt;/p&gt;
&lt;p&gt;
I admit to a small, carefully-cushioned place in my heart where I mourn over this.
&lt;/p&gt;
&lt;p&gt;
DevelopMentor was such a transcendent place for me. Much, if not most or all, of the
acceleration that came in my career came not only while I was there, but &lt;em&gt;because&lt;/em&gt; I
was there.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;So&lt;/em&gt; much of my speaking persona and skill I owe to Ron Sumida, who took a
half-baked neophyte of intermediate speaking skill, and in an eight-hour marathon
session still referred to in my mental memoirs as my &amp;quot;Night with Scary Ron&amp;quot;,
shaped me and taught me tricks about speaking that I continue to use to this day.
That I got to know him as a friend and confidant later still to this day ranks as
one of my greatest blessings.
&lt;/p&gt;
&lt;p&gt;
I remember my first DM Instructor Retreat, where I met so many of the names I'd read
about or heard about, and feeling &amp;quot;Oh, my God&amp;quot; fanboy-ish. I remember Tim
Ewald giving a talk on transactions at that retreat that left me agape—I seriously
didn't understand half of what he was saying, and rather than feeling overwhelmed
or ashamed, I remember distinctly thinking, &amp;quot;Wow—I have found a home where I
can learn SO much more.&amp;quot; It was like waking up one morning to find that your
writing workshop group suddenly included Neal Stephenson, Stephen Pinker, C.S. Lewis
and Ernest Hemingway. (Yes, I know those last two are dead. Work with me here.)
&lt;/p&gt;
&lt;p&gt;
I remember the day that Lorie (the ops manager at the time) called me to say that
Don Box wanted me to work with him on the C# course. I was convinced that she'd called
the wrong Ted, meaning instead to reach for Ted Pattison in her Rolodex and coming
up a few letters shy. She tartly informed me, &amp;quot;No, I know exactly who I'm talking
to, and are you interested or not?&amp;quot; How could I refuse? Help the Diety of COM
write DM's flagship course on Microsoft's flagship technology for the next decade?
&amp;quot;Hmm...&amp;quot;, I say out loud, not because I needed time to think about it, but
because a thread in the back of my head says, &amp;quot;Is there &lt;em&gt;any&lt;/em&gt; scenario
here where I say no?&amp;quot;
&lt;/p&gt;
&lt;p&gt;
I still fondly recall doing a Guerilla .NET at the Torrance Hilton shortly after the
.NET 1.0 release, and having a conversation with Don in my hotel room later that night;
that was when he told me &amp;quot;Microsoft is working on an open-source version of the
CLR&amp;quot;. I was stunned—I had no idea that said version would factor pretty largely
in my life later. But it opened my eyes, in a very practical way, to how deeply-connected
DevelopMentor was to Microsoft, and how that could play out in a direct fashion.
&lt;/p&gt;
&lt;p&gt;
When Peter Drayton joined, he asked me to do a quick review pass on the reference
section of his &lt;em&gt;C# in a Nutshell&lt;/em&gt;, and I agreed because Peter was a good guy
(and somebody I'd hoped would become a friend), and wanted to see the book do well.
That went from informal review to formal review to &amp;quot;well, could you maybe make
it an editing pass?&amp;quot; to &amp;quot;Would you like to write a few chapters?&amp;quot; to
&amp;quot;Well, let's sign you up as a co-author...&amp;quot;. That project is what introduced
me to John Osborn, which in turn led him to call me one day and say, &amp;quot;Some guys
at Microsoft are working on an open-source version of the CLR, and would like to have
a 'professional writer' help them write a book on it. Interested?&amp;quot; That led to &lt;em&gt;SSCLI
Internals&lt;/em&gt;, working with David Stutz, and wow, did I learn a helluvalot from &lt;em&gt;that&lt;/em&gt; project,
too.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Effective Enterprise Java&lt;/em&gt; came through DevelopMentor, thanks again to Don
Box, who introduced me to the folks at Addison-Wesley that put the contract (and Scott
Meyers, another blessing) in front of me.
&lt;/p&gt;
&lt;p&gt;
DM got me my start in the conference circuit, as well. In 2002, John Lam pinged me
over email—he'd recently become track chair for Connections down in Orlando, and was
I interested in speaking there? I was such a newbie to the whole idea, but having
taught classes roughly twice every month, I wasn't worried about the speaking part,
but the rest of the process. John walked me through the process, and in doing so,
set me down a path that would almost completely redefine my career within a year or
so.
&lt;/p&gt;
&lt;p&gt;
Even my Java chops got built up—the head of our Java curriculum was Stu Halloway (recently
of Clojure fame), and between him, Kevin Jones, Si Horrell, Brian Maso and Owen Tallman,
man, did I feel simultaneously like a small child among giants and like a kid in a
candy store. Every time I turned around, they'd discovered something new about the
Java platform that floored me. Bob Beauchemin has forgotten more about databases in
general than I will ever learn, and he had some insights on the intersection of Java
+ databases that still hang with me today.
&lt;/p&gt;
&lt;p&gt;
And my start with No Fluff Just Stuff came through DevelopMentor, too. Jason Whittington
heard through a mutual friend (Erik Hatcher, of Ant fame) about this cool little conference
being held in Denver, and maybe I should look into it. That led to an email intro
to Jay Zimmerman, a dinner together while I was teaching in Denver a few weeks later,
and before I knew it, I was on the Denver NFJS schedule, including the speaker panel,
where I uttered the then-infamous line, &amp;quot;Swing sucks. Get over it.&amp;quot;
&lt;/p&gt;
&lt;p&gt;
DevelopMentor, you shaped my career—and my life—in so many ways, you will always be
a source of pleasant memories and a group of friends and acquaintances that I would
never have had otherwise. Thank you &lt;em&gt;so&lt;/em&gt; much.
&lt;/p&gt;
&lt;p&gt;
Rest in peace.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Update:&lt;/strong&gt; Well, as it turns out, I have to rescind at least part of
my eulogy, as the post itself generated quite a stir—the folks at DevelopMentor were
pretty quick to email me, pointing out that they're still alive and well. In fact,
as one of them (a friend of mine still working there) put it, &amp;quot;We were all kinda
surprised when we came to work this morning and discovered that we could go home.&amp;quot;
Fortunately, the DevelopMentor folks were pretty gracious about what could've been
a &lt;em&gt;very&lt;/em&gt; ugly situation, and I apologize for to them for the misunderstanding—all
I can say is that my &amp;quot;source&amp;quot; must've also been mistaken, and I'm glad that
we're all still good. And lest it need to be said out loud, I &lt;em&gt;heartily&lt;/em&gt; want
nothing but the best for DM, and hope that I never have to write this message again.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=dd85708f-48d8-47dc-a9c6-cc4a1287ad31" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,dd85708f-48d8-47dc-a9c6-cc4a1287ad31.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Industry</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Scala</category>
      <category>Security</category>
      <category>Visual Basic</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=50d89561-e424-4164-bbb5-31453121a0c0</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,50d89561-e424-4164-bbb5-31453121a0c0.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,50d89561-e424-4164-bbb5-31453121a0c0.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=50d89561-e424-4164-bbb5-31453121a0c0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://callvirt.net/blog" target="_blank">Joel's weblog</a> appears to be
down, so in response to some emails I've posted my draft copy of <em>SSCLI 2.0 Internals</em><a href="http://www.tedneward.com/files/SSCLI2Internals-DRAFT.pdf" target="_blank">here</a>.
I think it's the same PDF that Joel had on his weblog, but I haven't made absolutely
certain of the fact. :-/
</p>
        <p>
If you've not checked out the first version of SSCLI Internals, it's cool—the second
edition is basically everything that the first edition is, plus a new chapter on Generics
(and how they changed the internals of the CLR to reflect generics all the way through
the system), so you're good. And if you're not sure where to get the codebase for
Rotor 2.0 (the SSCLI), well, <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&amp;displaylang=en" target="_blank">here</a>,
I'll make it easy for you. ;-)
</p>
        <p>
Gotta say, this is almost without question my favorite book to have written. Just
wish Microsoft would've kept Rotor up with the successive CLR releases (3.5 SP 1 and
now the forthcoming 4.0). Maybe, if I can find that wishing ring....
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=50d89561-e424-4164-bbb5-31453121a0c0" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>SSCLI 2.0 Internals</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,50d89561-e424-4164-bbb5-31453121a0c0.aspx</guid>
      <link>http://blogs.tedneward.com/2009/05/27/SSCLI+20+Internals.aspx</link>
      <pubDate>Wed, 27 May 2009 01:42:49 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://callvirt.net/blog" target="_blank"&gt;Joel's weblog&lt;/a&gt; appears to be
down, so in response to some emails I've posted my draft copy of &lt;em&gt;SSCLI 2.0 Internals&lt;/em&gt; &lt;a href="http://www.tedneward.com/files/SSCLI2Internals-DRAFT.pdf" target="_blank"&gt;here&lt;/a&gt;.
I think it's the same PDF that Joel had on his weblog, but I haven't made absolutely
certain of the fact. :-/
&lt;/p&gt;
&lt;p&gt;
If you've not checked out the first version of SSCLI Internals, it's cool—the second
edition is basically everything that the first edition is, plus a new chapter on Generics
(and how they changed the internals of the CLR to reflect generics all the way through
the system), so you're good. And if you're not sure where to get the codebase for
Rotor 2.0 (the SSCLI), well, &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&amp;amp;displaylang=en" target="_blank"&gt;here&lt;/a&gt;,
I'll make it easy for you. ;-)
&lt;/p&gt;
&lt;p&gt;
Gotta say, this is almost without question my favorite book to have written. Just
wish Microsoft would've kept Rotor up with the successive CLR releases (3.5 SP 1 and
now the forthcoming 4.0). Maybe, if I can find that wishing ring....
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=50d89561-e424-4164-bbb5-31453121a0c0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,50d89561-e424-4164-bbb5-31453121a0c0.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>F#</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Visual Basic</category>
      <category>Windows</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=f3062e21-fcf4-40f0-ac1f-8e212c931667</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,f3062e21-fcf4-40f0-ac1f-8e212c931667.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,f3062e21-fcf4-40f0-ac1f-8e212c931667.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=f3062e21-fcf4-40f0-ac1f-8e212c931667</wfw:commentRss>
      <slash:comments>7</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The <a href="http://www.simple-talk.com/newsletter-archive/">Simple-Talk newsletter</a> is
a monthly e-zine that the folks over at Red Gate Software (makers of some pretty cool
toys, including their ANTS Profiler, and recent inheritors of the Reflector utility
legacy) produce, usually to good effect.
</p>
        <p>
But <a href="http://www.simple-talk.com/newsletter/v.aspx?n=144">this month</a> carried
with it an interesting editorial piece, which I reproduce in its entirety here:
</p>
        <blockquote>
          <p>
When the market is slack, nothing succeeds better at tightening it up than promoting
serial group-panic within the community. As an example of this, a wave of multi-core
panic spread across the Internet about 18 months ago. IT organizations, it was said,
urgently had to improve application performance by an order of magnitude in order
to cope with rising demand. We wouldn't be able to meet that need because we were
at the "end of the road" with regard to step changes in processor power
and clock speed. Multi-core technology was the only sure route to improving the speed
of applications but, unfortunately, our current "serial" programming techniques,
and the limited multithreading capabilities of our programming languages and programmers,
left us ill-equipped to exploit it. Multi-core mania gripped the industry.
</p>
          <p>
However, the fever was surprisingly short-lived. Intel's "largest open-source
effort ever" to provide a standard tool for writing multi-threaded code, caused
little more than a ripple of interest. Various books, rushed out while the temperature
soared, advocated the urgent need for new "multi-core-friendly" programming
models, involving such things as "software pipelines". Interesting as they
undoubtedly are, they sit stolidly on bookshelves, unread.
</p>
          <p>
The truth is that it's simply not a big issue for the majority of people. Writing
truly "concurrent" applications in languages such as C# is difficult, as
you get very little help from the language. It means getting involved with low-level
concurrency primitives, such as lock statements and so on.
</p>
          <p>
Many programmers lack the skills to do this, but more pertinently lack the need. Increasingly,
programmers work in a web environment. As long as these web applications are deployed
to a load-balanced web farm, then page requests can be handled in parallel so all
available cores will be used efficiently without the need for the programmer to be
concerned with fine-grained parallelism.
</p>
          <p>
Furthermore, the SQL Server engine behind these web applications is intrinsically
"parallel", and can handle and use effectively about as many cores as you
care to throw at it. SQL itself is a declarative rather than procedural language,
so it is fundamentally concurrent.
</p>
          <p>
A minority of programmers, for example games programmers or those who deal with "embarrassingly
parallel" desktop applications such as Photoshop, do need to start working with
the current tools and 'low-level' coding techniques that will allow them to exploit
multi-core technology. Although currently perceived to be more of "academic"
interest, concurrent languages such as Erlang, and concurrency techniques such as
"software transactional memory", may yet prove to be significant.
</p>
          <p>
For most programmers and for most web applications, however, the multi-core furore
is a storm in a teacup; it's just not relevant. The web and database platforms already
cope with concurrency requirements. We are already doing it.
</p>
        </blockquote>
        <p>
My <em>hope</em> is that this newsletter, sent on April 1st, was intended to be a
joke. Having said that, I can’t find any verbage in the email that suggests that it
is, in which case, I have to treat it as a legitimate editorial. 
</p>
        <p>
And frankly, I think it’s all crap. 
</p>
        <p>
It's dangerously ostrichian in nature—it encourages developers to simply bury their
heads in the sand and ignore the freight train that's coming their way. Permit me,
if you will, a few minutes of your time, that I may be allowed to go through and demonstrate
the reasons why I say this.
</p>
        <p>
To begin ...
</p>
        <blockquote>
          <p>
When the market is slack, nothing succeeds better at tightening it up than promoting
serial group-panic within the community. As an example of this, a wave of multi-core
panic spread across the Internet about 18 months ago. IT organizations, it was said,
urgently had to improve application performance by an order of magnitude in order
to cope with rising demand. [...] Multi-core mania gripped the industry.
</p>
        </blockquote>
        <p>
Point of fact: The “panic” cited here didn’t start about 18 months ago, it started
with Herb Sutter’s most excellent (and not only highly recommended but highly required)
article, “The Free Lunch is Over: A Fundamental Turn Toward Concurrency in Software”,
appeared in the pages of Dr. Dobb’s Journal in March of 2005. (Herb’s website notes
that “a much briefer version under the title “The Concurrency Revolution” appeared
in C/C++ User’s Journal” the previous month.) And the panic itself wasn’t rooted in
the idea that we weren’t going to be able to cope with rising demand, but that multi-core
CPUs, back then a rarity and reserved only for hardware systems in highly-specialized
roles, were in fact becoming commonplace in servers, and worse, as they migrated into
desktops, they would quickly a fact of life that every developer would need to face.
Herb demonstrated this by pointing out that CPU speeds had taken an interesting change
of pace in early 2003:
</p>
        <blockquote>
          <p>
Around the beginning of 2003, <em>[looking at the website Figure 1 graph] </em>you’ll
note a disturbing sharp turn in the previous trend toward ever-faster CPU clock speeds.
I’ve added lines to show the limit trends in maximum clock speed; instead of continuing
on the previous path, as indicated by the thin dotted line, there is a sharp flattening.
It has become harder and harder to exploit higher clock speeds due to not just one
but several physical issues, notably heat (too much of it and too hard to dissipate),
power consumption (too high), and current leakage problems.
</p>
        </blockquote>
        <p>
Joe Armstrong, creator of Erlang, noted in a presentation at QCon London 2007 that
another of those physical limitations was the speed of light—that for the first time,
CPU signal couldn't get from one end of the chip to the other in a single clock cycle.
</p>
        <blockquote>
          <p>
Quick: What’s the clock speed on the CPU(s) in your current workstation? Are you running
at 10GHz? On Intel chips, we reached 2GHz a long time ago (August 2001), and according
to CPU trends before 2003, now in early 2005 we should have the first 10GHz Pentium-family
chips.
</p>
        </blockquote>
        <p>
Just to (re-)emphasize the point, here, now, in early 200<strong>9</strong>, we should
be seeing the first 20 or 40 GHz processors, and clearly we’re still plodding along
in the 2 – 3 GHz range. The "Quake Rule" (when asked about perf problems,
tell your boss you'll need eighteen months to get a 2X improvement, then bury yourselves
in a closet for 18 months playing Quake until the next gen of Intel hardware comes
out) no longer works.
</p>
        <blockquote>
          <p>
For the near-term future, meaning for the next few years, the performance gains in
new chips will be fueled by three main approaches, only one of which is the same as
in the past. The near-term future performance growth drivers are:
</p>
          <ul>
            <li>
hyperthreading</li>
            <li>
multicore</li>
            <li>
cache</li>
          </ul>
          <p>
Hyperthreading is about running two or more threads in parallel inside a single CPU.
Hyperthreaded CPUs are already available today, and they do allow some instructions
to run in parallel. A limiting factor, however, is that although a hyper-threaded
CPU has some extra hardware including extra registers, it still has just one cache,
one integer math unit, one FPU, and in general just one each of most basic CPU features.
Hyperthreading is sometimes cited as offering a 5% to 15% performance boost for reasonably
well-written multi-threaded applications, or even as much as 40% under ideal conditions
for carefully written multi-threaded applications. That’s good, but it’s hardly double,
and it doesn’t help single-threaded applications.
</p>
          <p>
Multicore is about running two or more actual CPUs on one chip. Some chips, including
Sparc and PowerPC, have multicore versions available already. The initial Intel and
AMD designs, both due in 2005, vary in their level of integration but are functionally
similar. AMD’s seems to have some initial performance design advantages, such as better
integration of support functions on the same die, whereas Intel’s initial entry basically
just glues together two Xeons on a single die. The performance gains should initially
be about the same as having a true dual-CPU system (only the system will be cheaper
because the motherboard doesn’t have to have two sockets and associated “glue” chippery),
which means something less than double the speed even in the ideal case, and just
like today it will boost reasonably well-written multi-threaded applications. Not
single-threaded ones.
</p>
          <p>
Finally, on-die cache sizes can be expected to continue to grow, at least in the near
term. Of these three areas, only this one will broadly benefit most existing applications.
The continuing growth in on-die cache sizes is an incredibly important and highly
applicable benefit for many applications, simply because space is speed. Accessing
main memory is expensive, and you really don’t want to touch RAM if you can help it.
On today’s systems, a cache miss that goes out to main memory often costs 10 to 50
times as much getting the information from the cache; this, incidentally, continues
to surprise people because we all think of memory as fast, and it is fast compared
to disks and networks, but not compared to on-board cache which runs at faster speeds.
If an application’s working set fits into cache, we’re golden, and if it doesn’t,
we’re not. That is why increased cache sizes will save some existing applications
and breathe life into them for a few more years without requiring significant redesign:
As existing applications manipulate more and more data, and as they are incrementally
updated to include more code for new features, performance-sensitive operations need
to continue to fit into cache. As the Depression-era old-timers will be quick to remind
you, “Cache is king.”
</p>
        </blockquote>
        <p>
Herb’s article was a pretty serious wake-up call to programmers who hadn’t noticed
the trend themselves. (Being one of those who hadn’t noticed, I remember reading his
piece, looking at that graph, glancing at the open ad from Fry’s Electronics sitting
on the dining room table next to me, and saying to myself, “Holy sh*t, he’s right!”.)
Does that qualify it as a “mania”? Perhaps if you’re trying to pooh-pooh the concern,
sure. But if you’re a developer who’s wondering where you’re going to get the processing
power to address the ever-expanding list of features your users want, something Herb
points out as a basic fact of life in the software development world ...
</p>
        <blockquote>
          <p>
There’s an interesting phenomenon that’s known as “Andy giveth, and Bill taketh away.”
No matter how fast processors get, software consistently finds new ways to eat up
the extra speed. Make a CPU ten times as fast, and software will usually find ten
times as much to do (or, in some cases, will feel at liberty to do it ten times less
efficiently).
</p>
        </blockquote>
        <p>
...  then eking out the best performance from an application is going to remain
at the top of the priority list. Users are classic consumers: they will always want
more and more for the same money as before. Ignore this truth of software (actually,
of basic microeconomics) at your peril.
</p>
        <p>
To get back to the editorial, we next come to ...
</p>
        <blockquote>
          <p>
However, the fever was surprisingly short-lived. Intel's "largest open-source
effort ever" to provide a standard tool for writing multi-threaded code, caused
little more than a ripple of interest. Various books, rushed out while the temperature
soared, advocated the urgent need for new "multi-core-friendly" programming
models, involving such things as "software pipelines". Interesting as they
undoubtedly are, they sit stolidly on bookshelves, unread.
</p>
        </blockquote>
        <p>
Wow. Talk about your pretty aggressive accusation without any supporting evidence
or citation whatsoever.
</p>
        <p>
Intel's not big into the open-source space, so it doesn't take much for an open-source
project from them to be their "largest open-source effort ever". (What,
they're going to open-source the schematics for the Intel chipline? Who could read
them even if they did? Who would offer up a patch? What good would it do?) The fact
that Intel made the software available in the first place meant that they knew the
hurdle that had yet to be overcome, and wanted to aid developers in overcoming it.
They're members of the OpenMP group for the same reason.
</p>
        <p>
Rogue Wave's software pipelines programming model is another case where real benefits
have accrued, backed by case studies. (Disclaimer: I know this because I ghost-wrote
an article for them on their Software Pipelines implementation.) Let's not knock something
that's actually delivered value. Pipelines aren't going to be the solution to every
problem, granted, but they're a useful way of structuring a design, one that's curiously
similar to what I see in functional programming languages.
</p>
        <p>
But simply defending Intel's generosity or the validity of an alternative programming
model doesn't support the idea that concurrency is still a hot topic. No, for that,
I need real evidence, something with actual concrete numbers and verifiable fact to
it. 
</p>
        <p>
Thus, I point to Brian Goetz’s <em>Java Concurrency in Practice</em>, one of those
“books, rushed out while the temperature soared”, which also turned out to be the
best-selling book at Java One 2007, <em>and</em> the second-best-selling book (behind
only Joshua Bloch’s unbelievably good <em>Effective Java (2nd Ed) </em>) at Java One
2008. Clearly, yes, bestselling concurrency books are just a myth, alongside the magical
device that will receive messages from all over the world and play them into your
brain (by way of your ears) on demand, or the magical silver bird that can wing its
way through the air with no visible means of support as it does so. Myths, clearly,
all of them.
</p>
        <p>
To continue...
</p>
        <blockquote>
          <p>
The truth is that it's simply not a big issue for the majority of people. Writing
truly "concurrent" applications in languages such as C# is difficult, as
you get very little help from the language. It means getting involved with low-level
concurrency primitives, such as lock statements and so on. 
</p>
          <p>
Many programmers lack the skills to do this, but more pertinently lack the need. Increasingly,
programmers work in a web environment. As long as these web applications are deployed
to a load-balanced web farm, then page requests can be handled in parallel so all
available cores will be used efficiently without the need for the programmer to be
concerned with fine-grained parallelism.
</p>
        </blockquote>
        <p>
He’s right when he says you get very little help from the language, be it C# or Java
or C++. And getting involved with low-level concurrency primitives is clearly not
in anybody’s best interests, particularly if you’re not a concurrency guru like Brian.
(And let’s be honest, even low-level concurrency gurus like Brian, or Joe Duffy, who
wrote <em>Concurrent Programming on Windows</em>, or Mike Woodring, who co-authored <em>Win32
Multithreaded Programming</em>, have better things to do.) But to say that they “pertinently
lack the need” is a rather impertinent statement. “As long as these web applications
are deployed to a load-balanced web farm", which is very likely to continue to
happen, “then page requests can be handled in parallel so all available cores will
be used …”
</p>
        <p>
Um... excuse me?
</p>
        <p>
Didn’t you <em>just</em> say that programmers <em>didn’t</em> need to learn concurrency
constructs? It would strike me that if their page requests are being handled <em>in
parallel</em> that they have to learn how to write code that won’t break when it’s
accessed <em>in parallel</em> or lead to data-corruption problems or race conditions
when their pages are accessed <em>in parallel.</em> If parallelism is a fundamental
part of the Web, don’t you think it’s important for them to learn how to write programs
that can behave correctly <em>in parallel</em>?
</p>
        <p>
Look for just a moment at the average web application: if data is stored in a per-user
collection, and two simultaneous requests come in from a given user (perhaps because
the page has AJAX requests being generated by the user on the page, or perhaps because
there’s a frameset that’s generating requests for each sub-frame, or ...), what happens
if the code is written to read a value from the session, increment it, and store it
back? ASP.NET can save you here, a little, in that it used to establish a per-user
lock on the entirety of the page request (I don’t know if it still does this—I really
have lost any desire to build web apps ever again), but that essentially puts an artificial
throttle on the scalability of your system, and makes the end-users’ experience that
much slower. Load-balancer going to spray the request all over the farm? So long as
the user session state is stored on every machine in the farm, that’ll work... But
of course if you store the user’s state in the SQL instance behind each of those machines
on the farm, then you take the performance hit of an <em>extra</em> network round-trip
(at which point we’re back to concurrency in the database) ...
</p>
        <p>
... all because the programmer couldn’t figure out how to make “lock” work? This is
progress?
</p>
        <p>
The Java Servlet specification specifically backed away from this "lock on every
request" approach because of the performance implications. I heard a fair amount
of wailing and gnashing during the early ASP.NET days over this. I heard the ASP.NET
dev team say they made their decision because the average developer can't figure out
concurrency correctly anyway.
</p>
        <p>
And, by the way folks, this editorial completely ignores XML services. I guess "real"
applications don't write services much, either.
</p>
        <p>
The next part is even better:
</p>
        <blockquote>
          <p>
Furthermore, the SQL Server engine behind these web applications is intrinsically
"parallel", and can handle and use effectively about as many cores as you
care to throw at it. SQL itself is a declarative rather than procedural language,
so it is fundamentally concurrent.
</p>
        </blockquote>
        <p>
True… and false. SQL is fundamentally “parallel” (largely because SQL is a non-strict
functional language, not just a “declarative” one), but T-SQL isn’t. And how many
developers actually know where the line is drawn between SQL and T-SQL? More importantly,
though, how many <em>effective</em> applications can be written with a complete ignorance
of the underlying locking model? Why do DBAs spend hours tuning the database’s physical
constructs, establishing where isolation levels can be turned down, establishing where
the scope of a transaction is too large, putting in indexed columns where necessary,
and figuring out where page, row, or table locking will be most efficient? Because
despite the view that a relational database presents, these queries are being executed<em> in
parallel</em>, and if a developer wants to avoid writing an application that requires
a new server for each and every new user added to the system, they need to learn how
to maximize their use of the database’s parallelism. So even if the <em>language</em> is
"fundamentally concurrent" and can thus be relied upon to do the right thing
on behalf of the developer, the <em>implementation</em> isn't, and needs to be understood
in order to be implemented efficiently.
</p>
        <p>
He finishes:
</p>
        <blockquote>
          <p>
For most programmers and for most web applications, however, the multi-core furore
is a storm in a teacup; it's just not relevant. The web and database platforms already
cope with concurrency requirements. We are already doing it.
</p>
        </blockquote>
        <p>
This is one of those times I wish I had a time machine handy—I'd love to step forward
five years, have a look around, then come back and report the findings. I'm tempted
to close with the challenge to just let’s come back in five years and see what the
programming language landscape and hardware landscape looks like. But that's too easy
an "out", and frankly, doesn't do much to really instill confidence, in
my opinion.
</p>
        <p>
To ignore the developers building "rich" applications (be they being done
in Flex/Flash, Cocoa/iPhone, WinForms, Swing, WPF, or what-have-you) is to also ignore
a relatively large segment of the market. Not every application is being built on
the web and is backed by a relational database—to simply brush those off and not even
consider them as part of the editorial reveals a dangerous bias on the editor's part.
And those applications aren't hosted in an "intrinsically 'parallel'" container
that developers can just bury their head inside.
</p>
        <p>
Like it or not, folks, the path forward isn't one that you get to choose. Intel, AMD,
and other chip manufacturers have already made that clear. They're <em>not</em> going
to abandon the multicore approach now, not when doing so would mean trying to wrestle
with so many problems (including trying to change the speed of light) that simply
aren't there when using a multicore foundation. That isn't up for debate anymore.
Multicore has won for the forseeable future. And, as a result, multicore is going
to be a fact of the developer's life for the forseeable future. Concurrency is thus
also a fact of the developer's life for the forseeable future. 
</p>
        <p>
The web and database platforms “cope” with concurrency requirements by either making
"one-size-fits-all" decisions that almost always end up being the wrong
decision for high-scale systems (but I'm sure your new startup-based idea, like a
system that allows people to push "micro-entries" of no more than 140 characters
in length to a publicly-trackable feed would never actually take off and start carrying
millions and millions of messages every day, right?), or by punting entirely and forcing
developers to dig deeper beneath the covers to see the concurrency there. So if you're
happy with your applications running no faster than 2GHz for the rest of the forseeable
future, then sure, you don't need to worry about learning concurrency-friendly kinds
of programming techniques. Bear in mind, by the way, that this essentially locks you
in to small-scale, web-plus-database systems for the forseeable future, and clearly
nothing with any sort of CPU intensiveness to it whatsoever. Be happy in your niche,
and wave to the other COBOL programmers who made the same decision.
</p>
        <p>
This is a leaky abstraction, full stop, end of story. Anyone who tells you otherwise
is either trolling for hits, trying to sell you something, or striving to persuade
developers that ignorance isn't such a bad place to be.
</p>
        <p>
All you ignorant developers, this is the phrase you will be forced to learn before
you start your next job: "Would you like fries with that?"
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=f3062e21-fcf4-40f0-ac1f-8e212c931667" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>&amp;quot;Multi-core Mania&amp;quot;: A Rebuttal</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,f3062e21-fcf4-40f0-ac1f-8e212c931667.aspx</guid>
      <link>http://blogs.tedneward.com/2009/04/01/quotMulticore+Maniaquot+A+Rebuttal.aspx</link>
      <pubDate>Wed, 01 Apr 2009 08:44:35 GMT</pubDate>
      <description>&lt;p&gt;
The &lt;a href="http://www.simple-talk.com/newsletter-archive/"&gt;Simple-Talk newsletter&lt;/a&gt; is
a monthly e-zine that the folks over at Red Gate Software (makers of some pretty cool
toys, including their ANTS Profiler, and recent inheritors of the Reflector utility
legacy) produce, usually to good effect.
&lt;/p&gt;
&lt;p&gt;
But &lt;a href="http://www.simple-talk.com/newsletter/v.aspx?n=144"&gt;this month&lt;/a&gt; carried
with it an interesting editorial piece, which I reproduce in its entirety here:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
When the market is slack, nothing succeeds better at tightening it up than promoting
serial group-panic within the community. As an example of this, a wave of multi-core
panic spread across the Internet about 18 months ago. IT organizations, it was said,
urgently had to improve application performance by an order of magnitude in order
to cope with rising demand. We wouldn't be able to meet that need because we were
at the &amp;quot;end of the road&amp;quot; with regard to step changes in processor power
and clock speed. Multi-core technology was the only sure route to improving the speed
of applications but, unfortunately, our current &amp;quot;serial&amp;quot; programming techniques,
and the limited multithreading capabilities of our programming languages and programmers,
left us ill-equipped to exploit it. Multi-core mania gripped the industry.
&lt;/p&gt;
&lt;p&gt;
However, the fever was surprisingly short-lived. Intel's &amp;quot;largest open-source
effort ever&amp;quot; to provide a standard tool for writing multi-threaded code, caused
little more than a ripple of interest. Various books, rushed out while the temperature
soared, advocated the urgent need for new &amp;quot;multi-core-friendly&amp;quot; programming
models, involving such things as &amp;quot;software pipelines&amp;quot;. Interesting as they
undoubtedly are, they sit stolidly on bookshelves, unread.
&lt;/p&gt;
&lt;p&gt;
The truth is that it's simply not a big issue for the majority of people. Writing
truly &amp;quot;concurrent&amp;quot; applications in languages such as C# is difficult, as
you get very little help from the language. It means getting involved with low-level
concurrency primitives, such as lock statements and so on.
&lt;/p&gt;
&lt;p&gt;
Many programmers lack the skills to do this, but more pertinently lack the need. Increasingly,
programmers work in a web environment. As long as these web applications are deployed
to a load-balanced web farm, then page requests can be handled in parallel so all
available cores will be used efficiently without the need for the programmer to be
concerned with fine-grained parallelism.
&lt;/p&gt;
&lt;p&gt;
Furthermore, the SQL Server engine behind these web applications is intrinsically
&amp;quot;parallel&amp;quot;, and can handle and use effectively about as many cores as you
care to throw at it. SQL itself is a declarative rather than procedural language,
so it is fundamentally concurrent.
&lt;/p&gt;
&lt;p&gt;
A minority of programmers, for example games programmers or those who deal with &amp;quot;embarrassingly
parallel&amp;quot; desktop applications such as Photoshop, do need to start working with
the current tools and 'low-level' coding techniques that will allow them to exploit
multi-core technology. Although currently perceived to be more of &amp;quot;academic&amp;quot;
interest, concurrent languages such as Erlang, and concurrency techniques such as
&amp;quot;software transactional memory&amp;quot;, may yet prove to be significant.
&lt;/p&gt;
&lt;p&gt;
For most programmers and for most web applications, however, the multi-core furore
is a storm in a teacup; it's just not relevant. The web and database platforms already
cope with concurrency requirements. We are already doing it.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
My &lt;em&gt;hope&lt;/em&gt; is that this newsletter, sent on April 1st, was intended to be a
joke. Having said that, I can’t find any verbage in the email that suggests that it
is, in which case, I have to treat it as a legitimate editorial. 
&lt;/p&gt;
&lt;p&gt;
And frankly, I think it’s all crap. 
&lt;/p&gt;
&lt;p&gt;
It's dangerously ostrichian in nature—it encourages developers to simply bury their
heads in the sand and ignore the freight train that's coming their way. Permit me,
if you will, a few minutes of your time, that I may be allowed to go through and demonstrate
the reasons why I say this.
&lt;/p&gt;
&lt;p&gt;
To begin ...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
When the market is slack, nothing succeeds better at tightening it up than promoting
serial group-panic within the community. As an example of this, a wave of multi-core
panic spread across the Internet about 18 months ago. IT organizations, it was said,
urgently had to improve application performance by an order of magnitude in order
to cope with rising demand. [...] Multi-core mania gripped the industry.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Point of fact: The “panic” cited here didn’t start about 18 months ago, it started
with Herb Sutter’s most excellent (and not only highly recommended but highly required)
article, “The Free Lunch is Over: A Fundamental Turn Toward Concurrency in Software”,
appeared in the pages of Dr. Dobb’s Journal in March of 2005. (Herb’s website notes
that “a much briefer version under the title “The Concurrency Revolution” appeared
in C/C++ User’s Journal” the previous month.) And the panic itself wasn’t rooted in
the idea that we weren’t going to be able to cope with rising demand, but that multi-core
CPUs, back then a rarity and reserved only for hardware systems in highly-specialized
roles, were in fact becoming commonplace in servers, and worse, as they migrated into
desktops, they would quickly a fact of life that every developer would need to face.
Herb demonstrated this by pointing out that CPU speeds had taken an interesting change
of pace in early 2003:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Around the beginning of 2003, &lt;em&gt;[looking at the website Figure 1 graph] &lt;/em&gt;you’ll
note a disturbing sharp turn in the previous trend toward ever-faster CPU clock speeds.
I’ve added lines to show the limit trends in maximum clock speed; instead of continuing
on the previous path, as indicated by the thin dotted line, there is a sharp flattening.
It has become harder and harder to exploit higher clock speeds due to not just one
but several physical issues, notably heat (too much of it and too hard to dissipate),
power consumption (too high), and current leakage problems.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Joe Armstrong, creator of Erlang, noted in a presentation at QCon London 2007 that
another of those physical limitations was the speed of light—that for the first time,
CPU signal couldn't get from one end of the chip to the other in a single clock cycle.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Quick: What’s the clock speed on the CPU(s) in your current workstation? Are you running
at 10GHz? On Intel chips, we reached 2GHz a long time ago (August 2001), and according
to CPU trends before 2003, now in early 2005 we should have the first 10GHz Pentium-family
chips.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Just to (re-)emphasize the point, here, now, in early 200&lt;strong&gt;9&lt;/strong&gt;, we should
be seeing the first 20 or 40 GHz processors, and clearly we’re still plodding along
in the 2 – 3 GHz range. The &amp;quot;Quake Rule&amp;quot; (when asked about perf problems,
tell your boss you'll need eighteen months to get a 2X improvement, then bury yourselves
in a closet for 18 months playing Quake until the next gen of Intel hardware comes
out) no longer works.
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
For the near-term future, meaning for the next few years, the performance gains in
new chips will be fueled by three main approaches, only one of which is the same as
in the past. The near-term future performance growth drivers are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
hyperthreading&lt;/li&gt;
&lt;li&gt;
multicore&lt;/li&gt;
&lt;li&gt;
cache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Hyperthreading is about running two or more threads in parallel inside a single CPU.
Hyperthreaded CPUs are already available today, and they do allow some instructions
to run in parallel. A limiting factor, however, is that although a hyper-threaded
CPU has some extra hardware including extra registers, it still has just one cache,
one integer math unit, one FPU, and in general just one each of most basic CPU features.
Hyperthreading is sometimes cited as offering a 5% to 15% performance boost for reasonably
well-written multi-threaded applications, or even as much as 40% under ideal conditions
for carefully written multi-threaded applications. That’s good, but it’s hardly double,
and it doesn’t help single-threaded applications.
&lt;/p&gt;
&lt;p&gt;
Multicore is about running two or more actual CPUs on one chip. Some chips, including
Sparc and PowerPC, have multicore versions available already. The initial Intel and
AMD designs, both due in 2005, vary in their level of integration but are functionally
similar. AMD’s seems to have some initial performance design advantages, such as better
integration of support functions on the same die, whereas Intel’s initial entry basically
just glues together two Xeons on a single die. The performance gains should initially
be about the same as having a true dual-CPU system (only the system will be cheaper
because the motherboard doesn’t have to have two sockets and associated “glue” chippery),
which means something less than double the speed even in the ideal case, and just
like today it will boost reasonably well-written multi-threaded applications. Not
single-threaded ones.
&lt;/p&gt;
&lt;p&gt;
Finally, on-die cache sizes can be expected to continue to grow, at least in the near
term. Of these three areas, only this one will broadly benefit most existing applications.
The continuing growth in on-die cache sizes is an incredibly important and highly
applicable benefit for many applications, simply because space is speed. Accessing
main memory is expensive, and you really don’t want to touch RAM if you can help it.
On today’s systems, a cache miss that goes out to main memory often costs 10 to 50
times as much getting the information from the cache; this, incidentally, continues
to surprise people because we all think of memory as fast, and it is fast compared
to disks and networks, but not compared to on-board cache which runs at faster speeds.
If an application’s working set fits into cache, we’re golden, and if it doesn’t,
we’re not. That is why increased cache sizes will save some existing applications
and breathe life into them for a few more years without requiring significant redesign:
As existing applications manipulate more and more data, and as they are incrementally
updated to include more code for new features, performance-sensitive operations need
to continue to fit into cache. As the Depression-era old-timers will be quick to remind
you, “Cache is king.”
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Herb’s article was a pretty serious wake-up call to programmers who hadn’t noticed
the trend themselves. (Being one of those who hadn’t noticed, I remember reading his
piece, looking at that graph, glancing at the open ad from Fry’s Electronics sitting
on the dining room table next to me, and saying to myself, “Holy sh*t, he’s right!”.)
Does that qualify it as a “mania”? Perhaps if you’re trying to pooh-pooh the concern,
sure. But if you’re a developer who’s wondering where you’re going to get the processing
power to address the ever-expanding list of features your users want, something Herb
points out as a basic fact of life in the software development world ...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
There’s an interesting phenomenon that’s known as “Andy giveth, and Bill taketh away.”
No matter how fast processors get, software consistently finds new ways to eat up
the extra speed. Make a CPU ten times as fast, and software will usually find ten
times as much to do (or, in some cases, will feel at liberty to do it ten times less
efficiently).
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
...&amp;#160; then eking out the best performance from an application is going to remain
at the top of the priority list. Users are classic consumers: they will always want
more and more for the same money as before. Ignore this truth of software (actually,
of basic microeconomics) at your peril.
&lt;/p&gt;
&lt;p&gt;
To get back to the editorial, we next come to ...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
However, the fever was surprisingly short-lived. Intel's &amp;quot;largest open-source
effort ever&amp;quot; to provide a standard tool for writing multi-threaded code, caused
little more than a ripple of interest. Various books, rushed out while the temperature
soared, advocated the urgent need for new &amp;quot;multi-core-friendly&amp;quot; programming
models, involving such things as &amp;quot;software pipelines&amp;quot;. Interesting as they
undoubtedly are, they sit stolidly on bookshelves, unread.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Wow. Talk about your pretty aggressive accusation without any supporting evidence
or citation whatsoever.
&lt;/p&gt;
&lt;p&gt;
Intel's not big into the open-source space, so it doesn't take much for an open-source
project from them to be their &amp;quot;largest open-source effort ever&amp;quot;. (What,
they're going to open-source the schematics for the Intel chipline? Who could read
them even if they did? Who would offer up a patch? What good would it do?) The fact
that Intel made the software available in the first place meant that they knew the
hurdle that had yet to be overcome, and wanted to aid developers in overcoming it.
They're members of the OpenMP group for the same reason.
&lt;/p&gt;
&lt;p&gt;
Rogue Wave's software pipelines programming model is another case where real benefits
have accrued, backed by case studies. (Disclaimer: I know this because I ghost-wrote
an article for them on their Software Pipelines implementation.) Let's not knock something
that's actually delivered value. Pipelines aren't going to be the solution to every
problem, granted, but they're a useful way of structuring a design, one that's curiously
similar to what I see in functional programming languages.
&lt;/p&gt;
&lt;p&gt;
But simply defending Intel's generosity or the validity of an alternative programming
model doesn't support the idea that concurrency is still a hot topic. No, for that,
I need real evidence, something with actual concrete numbers and verifiable fact to
it. 
&lt;/p&gt;
&lt;p&gt;
Thus, I point to Brian Goetz’s &lt;em&gt;Java Concurrency in Practice&lt;/em&gt;, one of those
“books, rushed out while the temperature soared”, which also turned out to be the
best-selling book at Java One 2007, &lt;em&gt;and&lt;/em&gt; the second-best-selling book (behind
only Joshua Bloch’s unbelievably good &lt;em&gt;Effective Java (2nd Ed) &lt;/em&gt;) at Java One
2008. Clearly, yes, bestselling concurrency books are just a myth, alongside the magical
device that will receive messages from all over the world and play them into your
brain (by way of your ears) on demand, or the magical silver bird that can wing its
way through the air with no visible means of support as it does so. Myths, clearly,
all of them.
&lt;/p&gt;
&lt;p&gt;
To continue...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
The truth is that it's simply not a big issue for the majority of people. Writing
truly &amp;quot;concurrent&amp;quot; applications in languages such as C# is difficult, as
you get very little help from the language. It means getting involved with low-level
concurrency primitives, such as lock statements and so on. 
&lt;/p&gt;
&lt;p&gt;
Many programmers lack the skills to do this, but more pertinently lack the need. Increasingly,
programmers work in a web environment. As long as these web applications are deployed
to a load-balanced web farm, then page requests can be handled in parallel so all
available cores will be used efficiently without the need for the programmer to be
concerned with fine-grained parallelism.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
He’s right when he says you get very little help from the language, be it C# or Java
or C++. And getting involved with low-level concurrency primitives is clearly not
in anybody’s best interests, particularly if you’re not a concurrency guru like Brian.
(And let’s be honest, even low-level concurrency gurus like Brian, or Joe Duffy, who
wrote &lt;em&gt;Concurrent Programming on Windows&lt;/em&gt;, or Mike Woodring, who co-authored &lt;em&gt;Win32
Multithreaded Programming&lt;/em&gt;, have better things to do.) But to say that they “pertinently
lack the need” is a rather impertinent statement. “As long as these web applications
are deployed to a load-balanced web farm&amp;quot;, which is very likely to continue to
happen, “then page requests can be handled in parallel so all available cores will
be used …”
&lt;/p&gt;
&lt;p&gt;
Um... excuse me?
&lt;/p&gt;
&lt;p&gt;
Didn’t you &lt;em&gt;just&lt;/em&gt; say that programmers &lt;em&gt;didn’t&lt;/em&gt; need to learn concurrency
constructs? It would strike me that if their page requests are being handled &lt;em&gt;in
parallel&lt;/em&gt; that they have to learn how to write code that won’t break when it’s
accessed &lt;em&gt;in parallel&lt;/em&gt; or lead to data-corruption problems or race conditions
when their pages are accessed &lt;em&gt;in parallel.&lt;/em&gt; If parallelism is a fundamental
part of the Web, don’t you think it’s important for them to learn how to write programs
that can behave correctly &lt;em&gt;in parallel&lt;/em&gt;?
&lt;/p&gt;
&lt;p&gt;
Look for just a moment at the average web application: if data is stored in a per-user
collection, and two simultaneous requests come in from a given user (perhaps because
the page has AJAX requests being generated by the user on the page, or perhaps because
there’s a frameset that’s generating requests for each sub-frame, or ...), what happens
if the code is written to read a value from the session, increment it, and store it
back? ASP.NET can save you here, a little, in that it used to establish a per-user
lock on the entirety of the page request (I don’t know if it still does this—I really
have lost any desire to build web apps ever again), but that essentially puts an artificial
throttle on the scalability of your system, and makes the end-users’ experience that
much slower. Load-balancer going to spray the request all over the farm? So long as
the user session state is stored on every machine in the farm, that’ll work... But
of course if you store the user’s state in the SQL instance behind each of those machines
on the farm, then you take the performance hit of an &lt;em&gt;extra&lt;/em&gt; network round-trip
(at which point we’re back to concurrency in the database) ...
&lt;/p&gt;
&lt;p&gt;
... all because the programmer couldn’t figure out how to make “lock” work? This is
progress?
&lt;/p&gt;
&lt;p&gt;
The Java Servlet specification specifically backed away from this &amp;quot;lock on every
request&amp;quot; approach because of the performance implications. I heard a fair amount
of wailing and gnashing during the early ASP.NET days over this. I heard the ASP.NET
dev team say they made their decision because the average developer can't figure out
concurrency correctly anyway.
&lt;/p&gt;
&lt;p&gt;
And, by the way folks, this editorial completely ignores XML services. I guess &amp;quot;real&amp;quot;
applications don't write services much, either.
&lt;/p&gt;
&lt;p&gt;
The next part is even better:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Furthermore, the SQL Server engine behind these web applications is intrinsically
&amp;quot;parallel&amp;quot;, and can handle and use effectively about as many cores as you
care to throw at it. SQL itself is a declarative rather than procedural language,
so it is fundamentally concurrent.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
True… and false. SQL is fundamentally “parallel” (largely because SQL is a non-strict
functional language, not just a “declarative” one), but T-SQL isn’t. And how many
developers actually know where the line is drawn between SQL and T-SQL? More importantly,
though, how many &lt;em&gt;effective&lt;/em&gt; applications can be written with a complete ignorance
of the underlying locking model? Why do DBAs spend hours tuning the database’s physical
constructs, establishing where isolation levels can be turned down, establishing where
the scope of a transaction is too large, putting in indexed columns where necessary,
and figuring out where page, row, or table locking will be most efficient? Because
despite the view that a relational database presents, these queries are being executed&lt;em&gt; in
parallel&lt;/em&gt;, and if a developer wants to avoid writing an application that requires
a new server for each and every new user added to the system, they need to learn how
to maximize their use of the database’s parallelism. So even if the &lt;em&gt;language&lt;/em&gt; is
&amp;quot;fundamentally concurrent&amp;quot; and can thus be relied upon to do the right thing
on behalf of the developer, the &lt;em&gt;implementation&lt;/em&gt; isn't, and needs to be understood
in order to be implemented efficiently.
&lt;/p&gt;
&lt;p&gt;
He finishes:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
For most programmers and for most web applications, however, the multi-core furore
is a storm in a teacup; it's just not relevant. The web and database platforms already
cope with concurrency requirements. We are already doing it.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
This is one of those times I wish I had a time machine handy—I'd love to step forward
five years, have a look around, then come back and report the findings. I'm tempted
to close with the challenge to just let’s come back in five years and see what the
programming language landscape and hardware landscape looks like. But that's too easy
an &amp;quot;out&amp;quot;, and frankly, doesn't do much to really instill confidence, in
my opinion.
&lt;/p&gt;
&lt;p&gt;
To ignore the developers building &amp;quot;rich&amp;quot; applications (be they being done
in Flex/Flash, Cocoa/iPhone, WinForms, Swing, WPF, or what-have-you) is to also ignore
a relatively large segment of the market. Not every application is being built on
the web and is backed by a relational database—to simply brush those off and not even
consider them as part of the editorial reveals a dangerous bias on the editor's part.
And those applications aren't hosted in an &amp;quot;intrinsically 'parallel'&amp;quot; container
that developers can just bury their head inside.
&lt;/p&gt;
&lt;p&gt;
Like it or not, folks, the path forward isn't one that you get to choose. Intel, AMD,
and other chip manufacturers have already made that clear. They're &lt;em&gt;not&lt;/em&gt; going
to abandon the multicore approach now, not when doing so would mean trying to wrestle
with so many problems (including trying to change the speed of light) that simply
aren't there when using a multicore foundation. That isn't up for debate anymore.
Multicore has won for the forseeable future. And, as a result, multicore is going
to be a fact of the developer's life for the forseeable future. Concurrency is thus
also a fact of the developer's life for the forseeable future. 
&lt;/p&gt;
&lt;p&gt;
The web and database platforms “cope” with concurrency requirements by either making
&amp;quot;one-size-fits-all&amp;quot; decisions that almost always end up being the wrong
decision for high-scale systems (but I'm sure your new startup-based idea, like a
system that allows people to push &amp;quot;micro-entries&amp;quot; of no more than 140 characters
in length to a publicly-trackable feed would never actually take off and start carrying
millions and millions of messages every day, right?), or by punting entirely and forcing
developers to dig deeper beneath the covers to see the concurrency there. So if you're
happy with your applications running no faster than 2GHz for the rest of the forseeable
future, then sure, you don't need to worry about learning concurrency-friendly kinds
of programming techniques. Bear in mind, by the way, that this essentially locks you
in to small-scale, web-plus-database systems for the forseeable future, and clearly
nothing with any sort of CPU intensiveness to it whatsoever. Be happy in your niche,
and wave to the other COBOL programmers who made the same decision.
&lt;/p&gt;
&lt;p&gt;
This is a leaky abstraction, full stop, end of story. Anyone who tells you otherwise
is either trolling for hits, trying to sell you something, or striving to persuade
developers that ignorance isn't such a bad place to be.
&lt;/p&gt;
&lt;p&gt;
All you ignorant developers, this is the phrase you will be forced to learn before
you start your next job: &amp;quot;Would you like fries with that?&amp;quot;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=f3062e21-fcf4-40f0-ac1f-8e212c931667" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,f3062e21-fcf4-40f0-ac1f-8e212c931667.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Parrot</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Scala</category>
      <category>Visual Basic</category>
      <category>WCF</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=26339b71-fc6b-406a-860b-193d7fe79307</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,26339b71-fc6b-406a-860b-193d7fe79307.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,26339b71-fc6b-406a-860b-193d7fe79307.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=26339b71-fc6b-406a-860b-193d7fe79307</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/14/fun-with-folds.aspx">Matt
Podwysocki makes it all clear</a>:
</p>
        <p>
          <a href="http://blogs.tedneward.com/content/binary/WindowsLiveWriter/NOWyouknowwhyyouwanttolearnHaskell_984/foldleft_beer_2.png">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="112" alt="foldleft_beer" src="http://blogs.tedneward.com/content/binary/WindowsLiveWriter/NOWyouknowwhyyouwanttolearnHaskell_984/foldleft_beer_thumb.png" width="469" border="0" />
          </a>
        </p>
        <p>
Hey, I'd have learned Haskell a LONG time ago if I'd known it could yield up a beer!
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=26339b71-fc6b-406a-860b-193d7fe79307" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>NOW you know why you want to learn Haskell</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,26339b71-fc6b-406a-860b-193d7fe79307.aspx</guid>
      <link>http://blogs.tedneward.com/2009/02/14/NOW+You+Know+Why+You+Want+To+Learn+Haskell.aspx</link>
      <pubDate>Sat, 14 Feb 2009 08:41:48 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2009/02/14/fun-with-folds.aspx"&gt;Matt
Podwysocki makes it all clear&lt;/a&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.tedneward.com/content/binary/WindowsLiveWriter/NOWyouknowwhyyouwanttolearnHaskell_984/foldleft_beer_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="112" alt="foldleft_beer" src="http://blogs.tedneward.com/content/binary/WindowsLiveWriter/NOWyouknowwhyyouwanttolearnHaskell_984/foldleft_beer_thumb.png" width="469" border="0"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Hey, I'd have learned Haskell a LONG time ago if I'd known it could yield up a beer!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=26339b71-fc6b-406a-860b-193d7fe79307" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,26339b71-fc6b-406a-860b-193d7fe79307.aspx</comments>
      <category>F#</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Social</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=69fae69d-1261-4cb0-929a-54f23624d2a3</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,69fae69d-1261-4cb0-929a-54f23624d2a3.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,69fae69d-1261-4cb0-929a-54f23624d2a3.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=69fae69d-1261-4cb0-929a-54f23624d2a3</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Because I’m about to start my third part in the WCF/F# series, I realized that I’ve
now hit the “rule of three” mark: in this particular case, this will mark the third
project I’m creating that unifies WCF and F#, and frankly, it’s a pain in the *ss
to do it all by hand each time: create an F# Library, add the System.ServiceModel
and System.Runtime.Serialization assemblies, go create an App.config file and add
it to the project as an Existing Item…. Painful.
</p>
        <p>
So… as a brief interlude, I decided to go re-acquaint myself with the Visual Studio
project template system, and sure enough, it’s basically what I remember: a collection
of files with some template-style functionality, bundled into a .zip file and stored
in the Visual Studio directory, under &lt;VSDir&gt;\Common7\IDE\ProjectTemplates.
What was new to me, however, was the highly useful “File | Export Template…” menu
option, allowing me to take an existing F#/WCF project and use it as a template to
create the .zip bundle. (Naturally, I didn’t discover this until I’d built the silly
thing by hand.)
</p>
        <p>
Sara Ford has more on creating a VS template on <a href="http://blogs.msdn.com/saraford/">her
Visual Studio Tools blog/column</a>, <a href="http://blogs.msdn.com/saraford/archive/2008/10/16/did-you-know-you-can-create-project-templates-336.aspx">number
336</a> to be precise. (You should read all of them, by the way—start with #1 and
work your way there. When you’re done, you’ll have a <em>much</em> better appreciation
of everything Visual Studio can do, and you’ll be able to find a ton of ways to save
yourself and your team some time and effort.)
</p>
        <p>
You can always take a .zip bundle like this and drop it into the Visual Studio 2008
“My Exported Templates” directory, but quite frankly, I didn’t want that. I wanted
my template to appear in a subcategory of Visual F# in the New Project dialog box,
under “WCF”, just as the C# versions do. The easiest way to do this is to manually
create the “WCF” directory (full path thus being &lt;VSDir&gt;\Common7\IDE\ProjectTemplates\FSharp\WCF),
and drop the .zip file there. Note that if you restart Visual Studio at this point,
you won’t see the new template; it builds a cache of the .zip templates in a sister
directory (ProjectTemplatesCache), so instead, you have to tell Visual Studio to reset
that cache by firing “devenv /setup” from the command-line. (This will require admin
privileges, by the way.)
</p>
        <p>
After that, you have an F#/WCF project template, and you’re good to go.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=69fae69d-1261-4cb0-929a-54f23624d2a3" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Building WCF services with F#, Interlude</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,69fae69d-1261-4cb0-929a-54f23624d2a3.aspx</guid>
      <link>http://blogs.tedneward.com/2009/01/24/Building+WCF+Services+With+F+Interlude.aspx</link>
      <pubDate>Sat, 24 Jan 2009 08:15:53 GMT</pubDate>
      <description>&lt;p&gt;
Because I’m about to start my third part in the WCF/F# series, I realized that I’ve
now hit the “rule of three” mark: in this particular case, this will mark the third
project I’m creating that unifies WCF and F#, and frankly, it’s a pain in the *ss
to do it all by hand each time: create an F# Library, add the System.ServiceModel
and System.Runtime.Serialization assemblies, go create an App.config file and add
it to the project as an Existing Item…. Painful.
&lt;/p&gt;
&lt;p&gt;
So… as a brief interlude, I decided to go re-acquaint myself with the Visual Studio
project template system, and sure enough, it’s basically what I remember: a collection
of files with some template-style functionality, bundled into a .zip file and stored
in the Visual Studio directory, under &amp;lt;VSDir&amp;gt;\Common7\IDE\ProjectTemplates.
What was new to me, however, was the highly useful “File | Export Template…” menu
option, allowing me to take an existing F#/WCF project and use it as a template to
create the .zip bundle. (Naturally, I didn’t discover this until I’d built the silly
thing by hand.)
&lt;/p&gt;
&lt;p&gt;
Sara Ford has more on creating a VS template on &lt;a href="http://blogs.msdn.com/saraford/"&gt;her
Visual Studio Tools blog/column&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/saraford/archive/2008/10/16/did-you-know-you-can-create-project-templates-336.aspx"&gt;number
336&lt;/a&gt; to be precise. (You should read all of them, by the way—start with #1 and
work your way there. When you’re done, you’ll have a &lt;em&gt;much&lt;/em&gt; better appreciation
of everything Visual Studio can do, and you’ll be able to find a ton of ways to save
yourself and your team some time and effort.)
&lt;/p&gt;
&lt;p&gt;
You can always take a .zip bundle like this and drop it into the Visual Studio 2008
“My Exported Templates” directory, but quite frankly, I didn’t want that. I wanted
my template to appear in a subcategory of Visual F# in the New Project dialog box,
under “WCF”, just as the C# versions do. The easiest way to do this is to manually
create the “WCF” directory (full path thus being &amp;lt;VSDir&amp;gt;\Common7\IDE\ProjectTemplates\FSharp\WCF),
and drop the .zip file there. Note that if you restart Visual Studio at this point,
you won’t see the new template; it builds a cache of the .zip templates in a sister
directory (ProjectTemplatesCache), so instead, you have to tell Visual Studio to reset
that cache by firing “devenv /setup” from the command-line. (This will require admin
privileges, by the way.)
&lt;/p&gt;
&lt;p&gt;
After that, you have an F#/WCF project template, and you’re good to go.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=69fae69d-1261-4cb0-929a-54f23624d2a3" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,69fae69d-1261-4cb0-929a-54f23624d2a3.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>F#</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>Building WCF services with F#, Part 2</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9.aspx</guid>
      <link>http://blogs.tedneward.com/2009/01/24/Building+WCF+Services+With+F+Part+2.aspx</link>
      <pubDate>Sat, 24 Jan 2009 03:11:15 GMT</pubDate>
      <description>&lt;p&gt;
If you’ve not read &lt;a href="http://blogs.tedneward.com/2009/01/18/Building+WCF+Services+With+F+Part+1.aspx"&gt;the
first part in the series&lt;/a&gt;, take a look there first.
&lt;/p&gt;
&lt;p&gt;
While it’s always easier to build WCF services with nothing but primitive types understood
by all the platforms to which you’re communicating (be it Java through XML services
or other .NET systems via WCF’s more efficient binding types), this gets old and limiting
very quickly. The WCF service author will want to develop whole composite types that
can be exchanged across the wire, and this is most often done via the DataContract
attribute applied to the types that will be exchanged.
&lt;/p&gt;
&lt;p&gt;
In Michele Leroux Bustamente’s &lt;em&gt;Learning WCF&lt;/em&gt; examples, this is covered in
Chapter #2, and the corresponding code I’m using as a basis for conversion to F# is
in Labs\Chapter2\DataContracts_Part1.
&lt;/p&gt;
&lt;p&gt;
One notable difference between this example and the previous one is that the type
definitions are stored in a separate assembly, ContentTypes.dll. There’s two basic
choices to use here: one, to use the C# types as defined, from a service written in
F#, or two, to define the types in F# and use them from the service. A third choice,
defining the types in F# and using them from C#, also presents itself, but is uninteresting
to us from a purely instructional standpoint—if you know how to write C#, then you
can take the types defined in F# and use them just as you would have the C# types.
&lt;/p&gt;
&lt;p&gt;
For instructional purposes, I’m going to take the second approach: I’m first going
to convert the ContentTypes.dll assembly over to F#, again to show how to create types
in F# that are structurally equivalent to the types defined in C#, since that’s something
that has changed since Nick Holmes blogged about this last year), then I’m going to
flip the service over to F# as well.
&lt;/p&gt;
&lt;h4&gt;Defining the Data Types
&lt;/h4&gt;
&lt;p&gt;
The first step, for many service authors, is to define the interfaces for the service(s)
and the types that will be exchanged; in this case, since I’m building from Michele’s
example, these have already been defined as:
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; ContentTypes&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; [DataContract(Namespace=&lt;span style="color: #006080"&gt;&amp;quot;http://schemas.thatindigogirl.com/samples/2006/06&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; LinkItem&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 0)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; m_id;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 1)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_title;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 2)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_description;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;DateStart&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 3)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DateTime
m_dateStart;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;DateEnd&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 4)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DateTime
m_dateEnd;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Url&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 5)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_url;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DateTime
DateStart&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; get
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_dateStart; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; set
{ m_dateStart = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 29:&lt;/span&gt; } &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 30:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DateTime
DateEnd&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 32:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 33:&lt;/span&gt; get
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_dateEnd; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 34:&lt;/span&gt; set
{ m_dateEnd = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 35:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 36:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Url&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 38:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 39:&lt;/span&gt; get
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_url; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 40:&lt;/span&gt; set
{ m_url = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 41:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 42:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 43:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; Id&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 44:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 45:&lt;/span&gt; get
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_id; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 46:&lt;/span&gt; set
{ m_id = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 47:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 48:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 49:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Title&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 50:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 51:&lt;/span&gt; get
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_title; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 52:&lt;/span&gt; set
{ m_title = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 53:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 54:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 55:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Description&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 56:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 57:&lt;/span&gt; get
{ &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_description; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 58:&lt;/span&gt; set
{ m_description = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 59:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 60:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 61:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Note that now, in a C#3-friendly world, we can slim the definition of the LinkItem
down to a much smaller level thanks to the power of automatic properties:
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Runtime.Serialization;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; ContentTypes&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; { &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; [DataContract(Namespace=&lt;span style="color: #006080"&gt;&amp;quot;http://schemas.thatindigogirl.com/samples/2006/06&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; LinkItem&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 0)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; Id
{ get; set; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 1)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Title
{ get; set; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 2)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Description
{ get; set; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;DateStart&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 3)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DateTime
DateStart { get; set; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;DateEnd&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 4)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DateTime
DateEnd { get; set; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; [DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Url&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 5)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Url
{ get; set; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
… but either way, the type ends up looking the same. Converting this over to F# is
relatively easy, if not any shorter or more convenient than the C# 3.0 version, owing
to the fact that, by default, F# will &lt;em&gt;not &lt;/em&gt;generate mutable properties by
default:
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; #light&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; ContentTypes&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; open
System&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; open
System.Runtime.Serialization&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; open
System.ServiceModel&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; [&amp;lt;DataContract(Namespace=&lt;span style="color: #006080"&gt;&amp;quot;http://schemas.thatindigogirl.com/samples/2006/06&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; type
LinkItem() =&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; let
mutable id : int64 = 0L&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; let
mutable title : &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; = String.Empty&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; let
mutable description : &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; = String.Empty&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; let
mutable dateStart : DateTime = DateTime.Now&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; let
mutable dateEnd : DateTime = DateTime.Now&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; let
mutable url : &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; = String.Empty&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; [&amp;lt;DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Id&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 0)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; member &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; l.Id&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; with
get() = id&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; and
set(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) = id &amp;lt;- &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; [&amp;lt;DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Title&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 1)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; member &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; l.Title&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; with
get() = title&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; and
set(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) = title &amp;lt;- &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; [&amp;lt;DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Description&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 2)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; member &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; l.Description&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; with
get() = description&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 29:&lt;/span&gt; and
set(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) = description &amp;lt;- &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 30:&lt;/span&gt; [&amp;lt;DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;DateStart&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,
Order = 3)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 31:&lt;/span&gt; member &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; l.DateStart&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 32:&lt;/span&gt; with
get() = dateStart&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 33:&lt;/span&gt; and
set(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) = dateStart &amp;lt;- &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 34:&lt;/span&gt; [&amp;lt;DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;DateEnd&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 4)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 35:&lt;/span&gt; member &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; l.DateEnd&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 36:&lt;/span&gt; with
get() = dateEnd&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 37:&lt;/span&gt; and
set(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) = dateEnd &amp;lt;- &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 38:&lt;/span&gt; [&amp;lt;DataMember(Name
= &lt;span style="color: #006080"&gt;&amp;quot;Url&amp;quot;&lt;/span&gt;, IsRequired = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;,
Order = 5)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 39:&lt;/span&gt; member &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; l.Url&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 40:&lt;/span&gt; with
get() = url&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 41:&lt;/span&gt; and
set(&lt;span style="color: #0000ff"&gt;value&lt;/span&gt;) = url &amp;lt;- &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Notice that I have to create a mutable backing field, and define the properties in
the F# LinkItem type to explicitly access and mutate those values. This is a bit frustrating,
because it seems like F# should be able to infer what I want from a simple property
declaration, in the same way that C# can, but perhaps that’s asking too much from
the language right now, considering the silly thing hasn’t even shipped yet. 
&lt;/p&gt;
&lt;p&gt;
(Psssst, Luke, Don, if you’re listening, automatic property generation in F# would
be a nifty feature to add between now and then, if you guys can ninja it in there
before the next CTP…)
&lt;/p&gt;
&lt;p&gt;
Notice, by the way, the namespace directive at the top of the F# code; this is necessary
to set the prefix around the LinkItem type. Without it, remember, the F# code is going
to be slipped inside an outer class declaration matching the filename, effectively
naming the class Module1+LinkItem, which would not be structurally equivalent to the
C# type.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Lesson #4: Always put a namespace or module declaration around the types exported
from a service.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Notice that LinkItem also has a default constructor, as per Lesson #2; this is necessary
because the DataContract-related code inside of WCF is going to need to be able to
construct one of these and set its properties. If we want to set any reasonable defaults,
that’s easily done in the mutable member definitions.
&lt;/p&gt;
&lt;p&gt;
One principal difference between the F# version and the C# version is that the DataMember
attributes are applied to the properties, instead of the fields, largely because the
F# language wants to keep a layer of encapsulation between the code you write as an
F# programmer, and the actual code generated. So, for example, the “field” id, above,
doesn’t actually get generated exactly as described—in truth, it turns into a field
called &lt;a href="mailto:&amp;ldquo;id@11"&gt;“id@11&lt;/a&gt;”. This is a marked difference from
C# (or even VB), which deliberately gives us more control over how the physical structure
of classes looks. This is even more obvious in a basic F# program where a top-level
declaration reads, “let x = 12”; where it might be tempting to assume that x will
be a static field on the class surrounding the declaration, the F# compiler actually
generates a property.
&lt;/p&gt;
&lt;p&gt;
In this particular case, whether the attribute applies to the fields or the property
declarations isn’t going to make a large difference, but in more sophisticated classes,
it might, so it’s better to apply the attribute to the property and not the field,
at least, from what I’ve found so far.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Lesson #5: Put DataMember attributes on the properties of the DataContract,
not the fields.&lt;/strong&gt;
&lt;/p&gt;
&lt;h4&gt;Defining the Service
&lt;/h4&gt;
&lt;p&gt;
The definition of the service is actually pretty straightforward. Add either the C#
ContentTypes.dll or the F# ContentTypes.dll as an assembly reference, and where the
C# code (GigManagerService.cs) reads:
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ServiceModel;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; ContentTypes;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; GigManager&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; [ServiceContract(Name
= &lt;span style="color: #006080"&gt;&amp;quot;GigManagerServiceContract&amp;quot;&lt;/span&gt;, Namespace
= &lt;span style="color: #006080"&gt;&amp;quot;http://www.thatindigogirl.com/samples/2006/06&amp;quot;&lt;/span&gt;,
SessionMode = SessionMode.Required)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IGigManagerService&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; [OperationContract]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SaveGig(LinkItem
item);&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; [OperationContract]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; LinkItem
GetGig();&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; [ServiceBehavior(InstanceContextMode
= InstanceContextMode.PerSession)]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; GigManagerService
: IGigManagerService&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; LinkItem
m_linkItem;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; SaveGig(LinkItem
item)&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; m_linkItem
= item;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 29:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 30:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; LinkItem
GetGig()&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 31:&lt;/span&gt; {&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 32:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_linkItem;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 33:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 34:&lt;/span&gt; }&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 35:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
… the corresponding F# code (Program.fs) reads like so:
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; #light&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; module
GigManager =&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; open
System&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; open
System.Runtime.Serialization&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; open
System.ServiceModel&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; open
ContentTypes&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; [&amp;lt;ServiceContract(Name
= &lt;span style="color: #006080"&gt;&amp;quot;GigManagerServiceContract&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; ConfigurationName
= &lt;span style="color: #006080"&gt;&amp;quot;IGigManagerService&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; Namespace
= &lt;span style="color: #006080"&gt;&amp;quot;http://www.thatindigogirl.com/samples/2006/06&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; SessionMode
= SessionMode.Required)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; type
IGigManagerService =&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; [&amp;lt;OperationContract&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; SaveGig:
item : LinkItem -&amp;gt; unit&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; [&amp;lt;OperationContract&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt; GetGig:
unit -&amp;gt; LinkItem&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; [&amp;lt;ServiceBehavior(InstanceContextMode
= InstanceContextMode.PerSession)&amp;gt;]&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; type
GigManagerService() =&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; let
mutable li : LinkItem = LinkItem()&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IGigManagerService
with&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; member
gms.SaveGig(item) = li &amp;lt;- item &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; member
gms.GetGig() = li&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Careful readers will notice that there’s one additional element in the F# version
that isn’t in the C# version; specifically, on line 11, I’ve added a “ConfigurationName”
element to the IGigManagerService’s ServiceContract attribute. I do this because,
again, the F# compiler is doing some interesting things to the code under the hood.
In particular, the interface IGigManagerService is actually exposed under a slightly
different name—remember, F# likes to use nested classes, not namespaces, so where
the C# version of IGigManagerService is formally known as “GigManager::IGigManagerService”,
the F# version is “Program/GigManager/GigManagerService”, where Program is the name
of the .fs file. This seems to cause WCF some heartache when it starts looking through
the App.config file and matching it up against the names exported from the actual
class—it won’t match up correctly. So, by giving it a ConfigurationName that matches
the human-readable interface name, WCF is happy again.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Lesson #5: Use ConfigurationName on ServiceContract to avoid having to learn
F#’s naming bindings to the CLR.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The rest of the code in Program.fs is the hosting code, which structurally is no different
than that of the previous post.
&lt;/p&gt;
&lt;p&gt;
One key thing to remember, however, is that the host “service” element will also be
looking at type names, so if you forget to set the name of the service, you’ll need
to use a type-investigation tool (ILDasm or Reflector) to figure out what the host
class name is; in the case above, it would be “Program+GigManager+GigManagerService”,
forcing the App.config file to read as follows:
&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #800000"&gt;xml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;encoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;services&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;service&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Program+GigManager+GigManagerService&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;behaviorConfiguration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;serviceBehavior&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;host&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;baseAddresses&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;baseAddress&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;http://localhost:8000&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;baseAddress&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;net.tcp://localhost:9000&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;baseAddresses&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;host&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;endpoint&lt;/span&gt; &lt;span style="color: #ff0000"&gt;address&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;GigManagerService&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 14:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;binding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;netTcpBinding&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 15:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;contract&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;IGigManagerService&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 16:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;endpoint&lt;/span&gt; &lt;span style="color: #ff0000"&gt;address&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;mex&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 17:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;binding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;mexHttpBinding&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 18:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;contract&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;IMetadataExchange&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;service&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 20:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;services&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;behavior&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;serviceBehavior&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 24:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceMetadata&lt;/span&gt; &lt;span style="color: #ff0000"&gt;httpGetEnabled&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 25:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;behavior&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 26:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;serviceBehaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;behaviors&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 28:&lt;/span&gt; &lt;span style="color: #008000"&gt;&amp;lt;!--
This &amp;lt;diagnostics&amp;gt; section should be placed inside the &amp;lt;system.serviceModel&amp;gt;
section. In addition, you'll need to add the &amp;lt;system.diagnostics&amp;gt; snippet to
specify service model trace listeners and a file for output. --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 29:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;diagnostics&lt;/span&gt; &lt;span style="color: #ff0000"&gt;performanceCounters&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;All&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;wmiProviderEnabled&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 30:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;messageLogging&lt;/span&gt; &lt;span style="color: #ff0000"&gt;logEntireMessage&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;logMalformedMessages&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;logMessagesAtServiceLevel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;logMessagesAtTransportLevel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;maxMessagesToLog&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;100000&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;diagnostics&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 32:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 33:&lt;/span&gt; &lt;span style="color: #008000"&gt;&amp;lt;!--
This &amp;lt;system.diagnostics&amp;gt; section illustrates the use of a shared listener for
service model output. It requires you to also add the &amp;lt;diagnostics&amp;gt; snippet
for the &amp;lt;system.serviceModel&amp;gt; section. --&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 34:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.diagnostics&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 35:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sharedListeners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 36:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;sharedListener&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 37:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;System.Diagnostics.XmlWriterTraceListener&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 38:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;initializeData&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;c:\logs\servicetrace.svclog&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 39:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sharedListeners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 40:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 41:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;System.ServiceModel&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;switchValue&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Verbose,
ActivityTracing&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 42:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;listeners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 43:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;sharedListener&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 44:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;listeners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 45:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 46:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;System.ServiceModel.MessageLogging&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;switchValue&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Verbose&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 47:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;listeners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 48:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;sharedListener&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 49:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;listeners&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 50:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;source&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 51:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 52:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.diagnostics&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 53:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;em&gt;Caveat emptor.&lt;/em&gt; In all honesty, despite the motivation of Lesson #5, I don’t
think there’s any way around learning at least a &lt;em&gt;little&lt;/em&gt; bit of F#’s name-mapping
scheme, but at least we can be selective about where and when we apply it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,ce6f58aa-5bc0-4a22-a35e-d94dd0c2fed9.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>F#</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>WCF</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=89bed821-27ee-4770-bb38-065b40cea3d7</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,89bed821-27ee-4770-bb38-065b40cea3d7.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,89bed821-27ee-4770-bb38-065b40cea3d7.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=89bed821-27ee-4770-bb38-065b40cea3d7</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For a couple of years now, I've been going around the world and giving a talk entitled
"Pragmatic Architecture", talking both about what architecture is (and what architects
really do), and ending the talk with my own "catalog" of architectural elements and
ideas, in an attempt to take some of the mystery and "cloud" nature of architecture
out of the discussion. If you've read <em>Effective Enterprise Java</em>, then you've
read the first version of that discussion, where Pragmatic Architecture was a second-generation
thought process.
</p>
        <p>
Recently, the patterns &amp; practices group at Microsoft went back and refined their <a href="http://www.codeplex.com/AppArchGuide">Application
Architecture Guide</a>, and while there's a lot about it that I wish they'd done differently
(less of a Microsoft-centric focus, for one), I think it's a great book for Microsoft-centric
architects to pick up and have nearby. In a lot of ways, this is something similar
to what I had in mind when I thought about the architectural catalog, though I'll
admit that I'd prefer to go one level "deeper" and find more of the "atoms" that make
up an architecture.
</p>
        <p>
Nevertheless, I think this is a good PDF to pull down and put somewhere on your reference
list.
</p>
        <p>
Notes and caveats: Firstly, this is a book for solution architects; if you're the
VP or CTO, don't bother with it, just hand it to somebody further on down the food
chain. Secondly, if you're not an architect, this is <em>not</em> the book to pick
up to learn how to be one. It's more in the way of a reference guide for existing
architects. In fact, my vision is that an architect faced with a new project (that
is, a new architecture to create) will think about the problem, sketch out a rough
solution in his head, then look at the book to find both potential alternatives (to
see if they fit better or worse than the one s/he has in her/his head), and potential
consequences (to the one s/he has in her/his head). Thirdly, even if you're a Java
or Ruby architect, <em>most</em> of the book is pretty technology-neutral. Just take
a black Sharpie to the parts that have the Microsoft trademark around them, and you'll
find it a pretty decent reference, too. Fourthly, in the spirit of full disclosure,
the p&amp;p guys brought me in for a day of discussion on the Guide, so I can't say
that I'm completely unbiased, but I can honestly say that I didn't write any of it,
just offered critique (in case that matters to any potential readers).
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=89bed821-27ee-4770-bb38-065b40cea3d7" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>&amp;quot;Pragmatic Architecture&amp;quot;, in book form</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,89bed821-27ee-4770-bb38-065b40cea3d7.aspx</guid>
      <link>http://blogs.tedneward.com/2009/01/05/quotPragmatic+Architecturequot+In+Book+Form.aspx</link>
      <pubDate>Mon, 05 Jan 2009 02:30:53 GMT</pubDate>
      <description>&lt;p&gt;
For a couple of years now, I've been going around the world and giving a talk entitled
"Pragmatic Architecture", talking both about what architecture is (and what architects
really do), and ending the talk with my own "catalog" of architectural elements and
ideas, in an attempt to take some of the mystery and "cloud" nature of architecture
out of the discussion. If you've read &lt;em&gt;Effective Enterprise Java&lt;/em&gt;, then you've
read the first version of that discussion, where Pragmatic Architecture was a second-generation
thought process.
&lt;/p&gt;
&lt;p&gt;
Recently, the patterns &amp;amp; practices group at Microsoft went back and refined their &lt;a href="http://www.codeplex.com/AppArchGuide"&gt;Application
Architecture Guide&lt;/a&gt;, and while there's a lot about it that I wish they'd done differently
(less of a Microsoft-centric focus, for one), I think it's a great book for Microsoft-centric
architects to pick up and have nearby. In a lot of ways, this is something similar
to what I had in mind when I thought about the architectural catalog, though I'll
admit that I'd prefer to go one level "deeper" and find more of the "atoms" that make
up an architecture.
&lt;/p&gt;
&lt;p&gt;
Nevertheless, I think this is a good PDF to pull down and put somewhere on your reference
list.
&lt;/p&gt;
&lt;p&gt;
Notes and caveats: Firstly, this is a book for solution architects; if you're the
VP or CTO, don't bother with it, just hand it to somebody further on down the food
chain. Secondly, if you're not an architect, this is &lt;em&gt;not&lt;/em&gt; the book to pick
up to learn how to be one. It's more in the way of a reference guide for existing
architects. In fact, my vision is that an architect faced with a new project (that
is, a new architecture to create) will think about the problem, sketch out a rough
solution in his head, then look at the book to find both potential alternatives (to
see if they fit better or worse than the one s/he has in her/his head), and potential
consequences (to the one s/he has in her/his head). Thirdly, even if you're a Java
or Ruby architect, &lt;em&gt;most&lt;/em&gt; of the book is pretty technology-neutral. Just take
a black Sharpie to the parts that have the Microsoft trademark around them, and you'll
find it a pretty decent reference, too. Fourthly, in the spirit of full disclosure,
the p&amp;amp;p guys brought me in for a day of discussion on the Guide, so I can't say
that I'm completely unbiased, but I can honestly say that I didn't write any of it,
just offered critique (in case that matters to any potential readers).
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=89bed821-27ee-4770-bb38-065b40cea3d7" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,89bed821-27ee-4770-bb38-065b40cea3d7.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Visual Basic</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=502a7f84-98f0-40d6-95aa-87513a7c35c6</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,502a7f84-98f0-40d6-95aa-87513a7c35c6.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,502a7f84-98f0-40d6-95aa-87513a7c35c6.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=502a7f84-98f0-40d6-95aa-87513a7c35c6</wfw:commentRss>
      <slash:comments>8</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It amazes me how insular and inward-facing the software industry is. And how the "agile"
movement is reaping the benefits of a very simple characteristic.
</p>
        <p>
For example, consider Jeff Palermo's essay on <a href="http://jeffreypalermo.com/blog/the-myth-of-self-organizing-teams/">"The
Myth of Self-Organizing Teams"</a>. Now, nothing against Jeff, or his post, <em>per
se</em>, but it amazes me how our industry believes that they are somehow inventing
new concepts, such as, in this case the "self-organizing team". Team dynamics have
been a subject of study for decades, and anyone with a background in psychology, business,
or sales has probably already been through much of the material on it. The best teams
are those that find their own sense of identity, that grow from within, but still
accept some leadership from the outside--the classic example here being the championship
sports team. Most often, that sense of identity is born of a string of successes,
which is why teams without a winning tradition have such a hard time creating the <em>esprit
de corps</em> that so often defines the difference between success and failure. 
</p>
        <blockquote>
          <p>
            <em>(Editor's note: Here's a free lesson to all of you out there who want to help
your team grow its own sense of identity: give them a chance to win a few successes,
and they'll start coming together pretty quickly. It's not always that easy, but it
works more often than not.)</em>
          </p>
        </blockquote>
        <p>
How many software development managers--much less technical leads or project managers--have
actually gone and looked through the management aisle at the local bookstore?
</p>
        <p>
Tom and Mary Poppendieck have been spending years now talking about "lean" software
development, which itself (at a casual glance) seems to be a refinement of the concepts
Toyota and other Japanese manufacturers were pursuing close to two decades ago. "Total
quality management" was a concept introduced in those days, the idea that anyone on
the production line was empowered to stop the line if they found something that wasn't
right. (My father was one of those "lean" manufacturing advocates back in the 80's,
in fact, and has some great stories he can tell to its successes, and failures.)
</p>
        <p>
How many software development managers or project leads give their developers the
chance to say, "No, it's not right yet, we can't ship", and back them on it? Wouldn't
you, as a developer, feel far more involved in the project if you knew you had that
power--and that responsibility?
</p>
        <p>
Or consider the "agile" notion of customer involvement, the classic XP "On-Site Customer"
principle. Sales people have known for years, even decades (if not centuries), that
if you involve the customer in the process, they are much more likely to feel an ownership
stake sooner than if they just take what's on the lot or the shelf. Skilled salespeople
have done the "let's walk through what you <em>might</em> buy, if you were buying,
of course" trick countless numbers of times, and ended up with a sale where the customer
didn't even intend to buy.
</p>
        <p>
How many software development managers or project leads have read a book on basic
salesmanship? And yet, isn't that notion of extracting what the customer wants endemic
to both software development and basic sales (of anything)?
</p>
        <p>
What is it about the software industry that just collectively refuses to accept that
there might be lots of interesting research on topics that aren't technical yet still
something that we can use? Why do we feel so compelled to trumpet our own "innovations"
to ourselves, when in fact, they've been long-known in dozens of other contexts? When
will we wake up and realize that we can learn a lot more if we cross-train in other
areas... like, for example, getting your MBA?
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=502a7f84-98f0-40d6-95aa-87513a7c35c6" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>The Myth of Discovery</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,502a7f84-98f0-40d6-95aa-87513a7c35c6.aspx</guid>
      <link>http://blogs.tedneward.com/2008/12/10/The+Myth+Of+Discovery.aspx</link>
      <pubDate>Wed, 10 Dec 2008 15:48:45 GMT</pubDate>
      <description>&lt;p&gt;
It amazes me how insular and inward-facing the software industry is. And how the "agile"
movement is reaping the benefits of a very simple characteristic.
&lt;/p&gt;
&lt;p&gt;
For example, consider Jeff Palermo's essay on &lt;a href="http://jeffreypalermo.com/blog/the-myth-of-self-organizing-teams/"&gt;"The
Myth of Self-Organizing Teams"&lt;/a&gt;. Now, nothing against Jeff, or his post, &lt;em&gt;per
se&lt;/em&gt;, but it amazes me how our industry believes that they are somehow inventing
new concepts, such as, in this case the "self-organizing team". Team dynamics have
been a subject of study for decades, and anyone with a background in psychology, business,
or sales has probably already been through much of the material on it. The best teams
are those that find their own sense of identity, that grow from within, but still
accept some leadership from the outside--the classic example here being the championship
sports team. Most often, that sense of identity is born of a string of successes,
which is why teams without a winning tradition have such a hard time creating the &lt;em&gt;esprit
de corps&lt;/em&gt; that so often defines the difference between success and failure. 
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;(Editor's note: Here's a free lesson to all of you out there who want to help
your team grow its own sense of identity: give them a chance to win a few successes,
and they'll start coming together pretty quickly. It's not always that easy, but it
works more often than not.)&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
How many software development managers--much less technical leads or project managers--have
actually gone and looked through the management aisle at the local bookstore?
&lt;/p&gt;
&lt;p&gt;
Tom and Mary Poppendieck have been spending years now talking about "lean" software
development, which itself (at a casual glance) seems to be a refinement of the concepts
Toyota and other Japanese manufacturers were pursuing close to two decades ago. "Total
quality management" was a concept introduced in those days, the idea that anyone on
the production line was empowered to stop the line if they found something that wasn't
right. (My father was one of those "lean" manufacturing advocates back in the 80's,
in fact, and has some great stories he can tell to its successes, and failures.)
&lt;/p&gt;
&lt;p&gt;
How many software development managers or project leads give their developers the
chance to say, "No, it's not right yet, we can't ship", and back them on it? Wouldn't
you, as a developer, feel far more involved in the project if you knew you had that
power--and that responsibility?
&lt;/p&gt;
&lt;p&gt;
Or consider the "agile" notion of customer involvement, the classic XP "On-Site Customer"
principle. Sales people have known for years, even decades (if not centuries), that
if you involve the customer in the process, they are much more likely to feel an ownership
stake sooner than if they just take what's on the lot or the shelf. Skilled salespeople
have done the "let's walk through what you &lt;em&gt;might&lt;/em&gt; buy, if you were buying,
of course" trick countless numbers of times, and ended up with a sale where the customer
didn't even intend to buy.
&lt;/p&gt;
&lt;p&gt;
How many software development managers or project leads have read a book on basic
salesmanship? And yet, isn't that notion of extracting what the customer wants endemic
to both software development and basic sales (of anything)?
&lt;/p&gt;
&lt;p&gt;
What is it about the software industry that just collectively refuses to accept that
there might be lots of interesting research on topics that aren't technical yet still
something that we can use? Why do we feel so compelled to trumpet our own "innovations"
to ourselves, when in fact, they've been long-known in dozens of other contexts? When
will we wake up and realize that we can learn a lot more if we cross-train in other
areas... like, for example, getting your MBA?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=502a7f84-98f0-40d6-95aa-87513a7c35c6" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,502a7f84-98f0-40d6-95aa-87513a7c35c6.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>C++</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>VMWare</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=44481f40-dbca-438c-9398-2ed93a3d62d8</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,44481f40-dbca-438c-9398-2ed93a3d62d8.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,44481f40-dbca-438c-9398-2ed93a3d62d8.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=44481f40-dbca-438c-9398-2ed93a3d62d8</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">Roy
Fielding has weighed in</a> on the recent "buzzwordiness" (hey, if Colbert can make
up "truthiness", then I can make up "buzzwordiness") of calling everything a "REST
API", a tactic that has become more <em>en vogue</em> of late as vendors discover
that the general programming population is finding the WSDL-based XML services stack
too complex to navigate successfully for all but the simplest of projects. Contrary
to what many RESTafarians may be hoping, Roy doesn't gather all these wayward children
to his breast and praise their anti-vendor/anti-corporate/anti-proprietary efforts,
but instead, blasts them pretty seriously for mangling his term:
</p>
        <blockquote>
          <p>
I am getting frustrated by the number of people calling any HTTP-based interface a
REST API. Today’s example is the <a href="http://wikis.glassfish.org/socialsite/Wiki.jsp?page=FinalizeRESTAPI">SocialSite
REST API</a>. That is RPC. It screams RPC. There is so much coupling on display that
it should be given an X rating.
</p>
        </blockquote>
        <p>
Ouch. "So much coupling on display that it should be given an X rating." I have to
remember that phrase--that's a keeper. And I'm shocked that Roy even knows what an
X rating is; he's such a mellow guy with such an innocent-looking face, I would've
bet money he'd never run into one before. <em>(Yes, people, that's a joke.)</em></p>
        <blockquote>
          <p>
What needs to be done to make the REST architectural style clear on the notion that
hypertext is a constraint? In other words, if the engine of application state (and
hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot
be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?
</p>
        </blockquote>
        <p>
Go Roy!
</p>
        <p>
For those of you who've <em>not</em> read Roy's thesis, and are thinking that this
is some kind of betrayal or trick, let's first of all point out that at no point is
Roy saying that your nifty HTTP-based API is not <em>useful</em> or <em>simple</em>.
He's simply saying that it isn't <em>RESTful</em>. That's a key differentiation. REST
has a specific set of goals and constraints it was trying to meet, and as such prescribes
a particular kind of architectural style to fit within those constraints. (Yes, REST
is essentially an architectural pattern: a solution to a problem within a certain
context that yields certain consequences.)
</p>
        <p>
Assuming you haven't tuned me out completely already, allow me to elucidate. In Chapter
5 of <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">Roy's
thesis</a>, Roy begins to build up the style that will ultimately be considered REST.
I'm not going to quote each and every step here--that's what the hyperlink above is
for--but simply call out certain parts. For example, in section 5.1.3, "Stateless",
he suggests that this architectural style should be stateless in nature, and explains
why; the emphasis/italics are mine:
</p>
        <blockquote>
          <p>
We next add a constraint to the client-server interaction: communication must be stateless
in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure
5-3), such that <em>each request from client to server must contain all of the information
necessary to understand the request</em>, and cannot take advantage of any stored
context on the server. <em>Session state is therefore kept entirely on the client</em>. 
</p>
          <p>
This constraint induces the properties of visibility, reliability, and scalability.
Visibility is improved because a monitoring system does not have to look beyond a
single request datum in order to determine the full nature of the request. Reliability
is improved because it eases the task of recovering from partial failures [133]. Scalability
is improved because not having to store state between requests allows the server component
to quickly free resources, and further simplifies implementation because the server
doesn't have to manage resource usage across requests. 
</p>
          <p>
Like most architectural choices, the stateless constraint reflects a design trade-off.
The disadvantage is that it may decrease network performance by increasing the repetitive
data (per-interaction overhead) sent in a series of requests, since that data cannot
be left on the server in a shared context. In addition, placing the application state
on the client-side reduces the server's control over consistent application behavior,
since the application becomes dependent on the correct implementation of semantics
across multiple client versions.
</p>
        </blockquote>
        <p>
In the HTTP case, the state is contained entirely in the document itself, the hypertext.
This has a couple of implications for those of us building "distributed applications",
such as the very real consideration that there's a <em>lot</em> of state we don't
necessarily want to be sending back to the client, such as voluminous information
(the user's e-commerce shopping cart contents) or sensitive information (the user's
credentials or single-signon authentication/authorization token). This is a bitter
pill to swallow for the application development world, because much of the applications
we develop have some pretty hefty notions of server-based state management that we
want or need to preserve, either for legacy support reasons, for legitimate concerns
(network bandwidth or security), or just for ease-of-understanding. Fielding isn't
apologetic about it, though--look at the third paragraph above. "[T]he stateless constraint
reflects a design trade-off."
</p>
        <p>
In other words, if you don't like it, fine, don't follow it, but understand that if
you're not leaving all the application state on the client, you're not doing REST.
</p>
        <p>
By the way, note that technically, HTTP is not tied to HTML, since the document sent
back and forth could easily be a PDF document, too, particularly since PDF supports
hyperlinks to other PDF documents. Nowhere in the thesis do we see the idea that it <em>has</em> to
be HTML flying back and forth.
</p>
        <p>
Roy's thesis continues on in the same vein; in section 5.1.4 he describes how "client-cache-stateless-server"
provides some additional reliability and performance, but only if the data in the
cache is consistent and not stale, which was fine for static documents, but not for
dynamic content such as image maps. Extensions were necessary in order to accomodate
the new ideas.
</p>
        <p>
In section 5.1.5 ("Uniform Interface") we get to another stinging rebuke of REST as
a generalized distributed application scheme; again, the emphasis is mine:
</p>
        <blockquote>
          <p>
The central feature that distinguishes the REST architectural style from other network-based
styles is its emphasis on a uniform interface between components (Figure 5-6). By
applying the software engineering principle of generality to the component interface,
the overall system architecture is simplified and the visibility of interactions is
improved. Implementations are decoupled from the services they provide, which encourages
independent evolvability. The trade-off, though, is that a uniform interface degrades
efficiency, since information is transferred in a standardized form rather than one
which is specific to an application's needs. The REST interface is designed to be
efficient for large-grain hypermedia data transfer, optimizing for the common case
of the Web, but resulting in an interface that is not optimal for other forms of architectural
interaction. 
</p>
          <p>
In order to obtain a uniform interface, multiple architectural constraints are needed
to guide the behavior of components. <em>REST is defined by four interface constraints</em>:
identification of resources; manipulation of resources through representations; self-descriptive
messages; and, <em>hypermedia as the engine of application state</em>. These constraints
will be discussed in Section 5.2.
</p>
        </blockquote>
        <p>
In other words, in order to be doing something that Fielding considers RESTful, you
have to be using hypermedia (that is to say, hypertext documents of some form) as
the core of your application state. It might seem like this implies that you have
to be building a Web application in order to be considered building something RESTful,
so therefore all Web apps are RESTful by nature, but pay close attention to the wording:
hypermedia must be the <em>core</em> of your application state. The way most Web apps
are built today, HTML is clearly not the core of the state, but merely a way to render
it. This is the accidental consequence of treating Web applications and desktop client
applications as just pale reflections of one another.
</p>
        <p>
The next section, 5.1.6 ("Layered System") again builds on the notion of stateless-server
architecture to provide additional flexibility and power:
</p>
        <blockquote>
          <p>
In order to further improve behavior for Internet-scale requirements, we add layered
system constraints (Figure 5-7). As described in Section 3.4.2, the layered system
style allows an architecture to be composed of hierarchical layers by constraining
component behavior such that each component cannot "see" beyond the immediate layer
with which they are interacting. By restricting knowledge of the system to a single
layer, we place a bound on the overall system complexity and promote substrate independence.
Layers can be used to encapsulate legacy services and to protect new services from
legacy clients, simplifying components by moving infrequently used functionality to
a shared intermediary. Intermediaries can also be used to improve system scalability
by enabling load balancing of services across multiple networks and processors. 
</p>
          <p>
The primary disadvantage of layered systems is that they add overhead and latency
to the processing of data, reducing user-perceived performance [32].<em> For a network-based
system that supports cache constraints, this can be offset by the benefits of shared
caching at intermediaries.</em> Placing shared caches at the boundaries of an organizational
domain can result in significant performance benefits [136]. Such layers also allow
security policies to be enforced on data crossing the organizational boundary, as
is required by firewalls [79]. 
</p>
          <p>
The combination of layered system and uniform interface constraints induces architectural
properties similar to those of the uniform pipe-and-filter style (Section 3.2.2).
Although REST interaction is two-way, the large-grain data flows of hypermedia interaction
can each be processed like a data-flow network, with filter components selectively
applied to the data stream in order to transform the content as it passes [26]. <em>Within
REST, intermediary components can actively transform the content of messages because
the messages are self-descriptive and their semantics are visible to intermediaries.</em></p>
        </blockquote>
        <p>
The potential of layered systems (itself not something that people building RESTful
approaches seem to think much about) is only realized if the entirety of the state
being transferred is self-descriptive and visible to the intermediaries--in other
words, intermediaries can only be helpful and/or non-performance-inhibitive if they
have free reign to make decisions based on the state they see being transferred. If
something isn't present in the state being transferred, usually because there is server-side
state being maintained, then they have to be concerned about silently changing the
semantics of what is happening in the interaction, and intermediaries--and layers
as a whole--become a liability. (Which is probably why so few systems seem to do it.)
</p>
        <p>
And if the notion of visible, transported state is not yet made clear in his dissertation,
Fielding dissects the discussion even further in section 5.2.1, "Data Elements". It's
too long to reprint here in its entirety, and frankly, reading the whole thing is
necessary to see the point of hypermedia and its place in the whole system. (The same
could be said of the entire chapter, in fact.) But it's pretty clear, once you read
the dissertation, that hypermedia/hypertext is a core, critical piece to the whole
REST construction. Clients are expected, in a RESTful system, to have <em>no</em> preconceived
notions of structure or relationship between resources, and discover all of that through
the state of the hypertext documents that are sent back to them. In the HTML case,
that discovery occurs inside the human brain; in the SOA/services case, that discovery
is much harder to define and describe. RDF and Semantic Web ideas may be of some help
here, but JSON can't, and simple XML can't, unless the client has some preconceived
notion of what the XML structure looks like, which violates Fielding's rules:
</p>
        <blockquote>
          <p>
A REST API should be entered with no prior knowledge beyond the initial URI (bookmark)
and set of standardized media types that are appropriate for the intended audience
(i.e., expected to be understood by any client that might use the API). From that
point on, all application state transitions must be driven by client selection of
server-provided choices that are present in the received representations or implied
by the user’s manipulation of those representations. The transitions may be determined
(or limited by) the client’s knowledge of media types and resource communication mechanisms,
both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies
that out-of-band information is driving interaction instead of hypertext.]
</p>
        </blockquote>
        <p>
An interesting "fuzzy gray area" here is whether or not the client's knowledge of
a variant or schematic structure of XML could be considered to be a "standardized
media type", but I'm willing to bet that Fielding will argue against it on the grounds
that your application's XML schema is not "standardized" (unless, of course, it is,
through a national/international/industry standardization effort).
</p>
        <p>
But in case you'd missed it, let me summarize the past twenty or so paragraphs: <em>hypermedia
is a core requirement to being RESTful.</em> If you ain't slinging all of your application
state back and forth in hypertext, you ain't REST. Period. Fielding said it, he defined
it, and that settles it.
</p>
        <p>
 
</p>
        <p>
Before the hate mail comes a-flyin', let me reiterate one vitally important point: <em>if
you're not doing REST, it doesn't mean that your API sucks.</em> Fielding may have
his definition of what REST is, and the idealist in me wants to remain true to his
definitions of it (after all, if we can't agree on a common set of definitions, a
common lexicon, then we can't really make much progress as an industry), but...
</p>
        <p>
... the pragmatist in me keeps saying, "so what"?
</p>
        <p>
Look, at the end of the day, if your system wants to misuse HTTP, abuse HTML, and
carnally violate the principles of loose coupling and resource representation that
underlie REST, who cares? Do you get special bonus points from the Apache Foundation
if you use HTTP in the way Fielding intended? Will Microsoft and Oracle and Sun and
IBM offer you discounts on your next software purchases if you create a REST-faithful
system? Will the partisan politics in Washington, or the tribal conflicts in the Middle
East, or even the widely-misnamed "REST-vs-SOAP" debates come to an end if you only
figure out a way to make hypermedia the core engine of your application state?
</p>
        <p>
Yeah, I didn't think so, either.
</p>
        <p>
Point is, REST is <em>just</em> an architectural style. It is nothing more than another
entry alongside such things as client-server, <em>n</em>-tier, distributed objects,
service-oriented, and embedded systems. REST is just a tool for thinking about how
to build an application, and it's high time we kick it off the pedastal on which we've
placed it and let it come back down to earth with the rest of us mortals. HTTP is
useful, but not sufficient, so solve our problems. REST is as well.
</p>
        <p>
And at the end of the day, when we put one tool from our tool belt "above all others",
we end up building some truly horrendous crap.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=44481f40-dbca-438c-9398-2ed93a3d62d8" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>REST != HTTP</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,44481f40-dbca-438c-9398-2ed93a3d62d8.aspx</guid>
      <link>http://blogs.tedneward.com/2008/11/07/REST+HTTP.aspx</link>
      <pubDate>Fri, 07 Nov 2008 05:34:23 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven"&gt;Roy
Fielding has weighed in&lt;/a&gt; on the recent "buzzwordiness" (hey, if Colbert can make
up "truthiness", then I can make up "buzzwordiness") of calling everything a "REST
API", a tactic that has become more &lt;em&gt;en vogue&lt;/em&gt; of late as vendors discover
that the general programming population is finding the WSDL-based XML services stack
too complex to navigate successfully for all but the simplest of projects. Contrary
to what many RESTafarians may be hoping, Roy doesn't gather all these wayward children
to his breast and praise their anti-vendor/anti-corporate/anti-proprietary efforts,
but instead, blasts them pretty seriously for mangling his term:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
I am getting frustrated by the number of people calling any HTTP-based interface a
REST API. Today’s example is the &lt;a href="http://wikis.glassfish.org/socialsite/Wiki.jsp?page=FinalizeRESTAPI"&gt;SocialSite
REST API&lt;/a&gt;. That is RPC. It screams RPC. There is so much coupling on display that
it should be given an X rating.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Ouch. "So much coupling on display that it should be given an X rating." I have to
remember that phrase--that's a keeper. And I'm shocked that Roy even knows what an
X rating is; he's such a mellow guy with such an innocent-looking face, I would've
bet money he'd never run into one before. &lt;em&gt;(Yes, people, that's a joke.)&lt;/em&gt; &lt;blockquote&gt; 
&lt;p&gt;
What needs to be done to make the REST architectural style clear on the notion that
hypertext is a constraint? In other words, if the engine of application state (and
hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot
be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Go Roy!
&lt;/p&gt;
&lt;p&gt;
For those of you who've &lt;em&gt;not&lt;/em&gt; read Roy's thesis, and are thinking that this
is some kind of betrayal or trick, let's first of all point out that at no point is
Roy saying that your nifty HTTP-based API is not &lt;em&gt;useful&lt;/em&gt; or &lt;em&gt;simple&lt;/em&gt;.
He's simply saying that it isn't &lt;em&gt;RESTful&lt;/em&gt;. That's a key differentiation. REST
has a specific set of goals and constraints it was trying to meet, and as such prescribes
a particular kind of architectural style to fit within those constraints. (Yes, REST
is essentially an architectural pattern: a solution to a problem within a certain
context that yields certain consequences.)
&lt;/p&gt;
&lt;p&gt;
Assuming you haven't tuned me out completely already, allow me to elucidate. In Chapter
5 of &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm"&gt;Roy's
thesis&lt;/a&gt;, Roy begins to build up the style that will ultimately be considered REST.
I'm not going to quote each and every step here--that's what the hyperlink above is
for--but simply call out certain parts. For example, in section 5.1.3, "Stateless",
he suggests that this architectural style should be stateless in nature, and explains
why; the emphasis/italics are mine:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
We next add a constraint to the client-server interaction: communication must be stateless
in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure
5-3), such that &lt;em&gt;each request from client to server must contain all of the information
necessary to understand the request&lt;/em&gt;, and cannot take advantage of any stored
context on the server. &lt;em&gt;Session state is therefore kept entirely on the client&lt;/em&gt;. 
&lt;p&gt;
This constraint induces the properties of visibility, reliability, and scalability.
Visibility is improved because a monitoring system does not have to look beyond a
single request datum in order to determine the full nature of the request. Reliability
is improved because it eases the task of recovering from partial failures [133]. Scalability
is improved because not having to store state between requests allows the server component
to quickly free resources, and further simplifies implementation because the server
doesn't have to manage resource usage across requests. 
&lt;p&gt;
Like most architectural choices, the stateless constraint reflects a design trade-off.
The disadvantage is that it may decrease network performance by increasing the repetitive
data (per-interaction overhead) sent in a series of requests, since that data cannot
be left on the server in a shared context. In addition, placing the application state
on the client-side reduces the server's control over consistent application behavior,
since the application becomes dependent on the correct implementation of semantics
across multiple client versions.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
In the HTTP case, the state is contained entirely in the document itself, the hypertext.
This has a couple of implications for those of us building "distributed applications",
such as the very real consideration that there's a &lt;em&gt;lot&lt;/em&gt; of state we don't
necessarily want to be sending back to the client, such as voluminous information
(the user's e-commerce shopping cart contents) or sensitive information (the user's
credentials or single-signon authentication/authorization token). This is a bitter
pill to swallow for the application development world, because much of the applications
we develop have some pretty hefty notions of server-based state management that we
want or need to preserve, either for legacy support reasons, for legitimate concerns
(network bandwidth or security), or just for ease-of-understanding. Fielding isn't
apologetic about it, though--look at the third paragraph above. "[T]he stateless constraint
reflects a design trade-off."
&lt;/p&gt;
&lt;p&gt;
In other words, if you don't like it, fine, don't follow it, but understand that if
you're not leaving all the application state on the client, you're not doing REST.
&lt;/p&gt;
&lt;p&gt;
By the way, note that technically, HTTP is not tied to HTML, since the document sent
back and forth could easily be a PDF document, too, particularly since PDF supports
hyperlinks to other PDF documents. Nowhere in the thesis do we see the idea that it &lt;em&gt;has&lt;/em&gt; to
be HTML flying back and forth.
&lt;/p&gt;
&lt;p&gt;
Roy's thesis continues on in the same vein; in section 5.1.4 he describes how "client-cache-stateless-server"
provides some additional reliability and performance, but only if the data in the
cache is consistent and not stale, which was fine for static documents, but not for
dynamic content such as image maps. Extensions were necessary in order to accomodate
the new ideas.
&lt;/p&gt;
&lt;p&gt;
In section 5.1.5 ("Uniform Interface") we get to another stinging rebuke of REST as
a generalized distributed application scheme; again, the emphasis is mine:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
The central feature that distinguishes the REST architectural style from other network-based
styles is its emphasis on a uniform interface between components (Figure 5-6). By
applying the software engineering principle of generality to the component interface,
the overall system architecture is simplified and the visibility of interactions is
improved. Implementations are decoupled from the services they provide, which encourages
independent evolvability. The trade-off, though, is that a uniform interface degrades
efficiency, since information is transferred in a standardized form rather than one
which is specific to an application's needs. The REST interface is designed to be
efficient for large-grain hypermedia data transfer, optimizing for the common case
of the Web, but resulting in an interface that is not optimal for other forms of architectural
interaction. 
&lt;p&gt;
In order to obtain a uniform interface, multiple architectural constraints are needed
to guide the behavior of components. &lt;em&gt;REST is defined by four interface constraints&lt;/em&gt;:
identification of resources; manipulation of resources through representations; self-descriptive
messages; and, &lt;em&gt;hypermedia as the engine of application state&lt;/em&gt;. These constraints
will be discussed in Section 5.2.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
In other words, in order to be doing something that Fielding considers RESTful, you
have to be using hypermedia (that is to say, hypertext documents of some form) as
the core of your application state. It might seem like this implies that you have
to be building a Web application in order to be considered building something RESTful,
so therefore all Web apps are RESTful by nature, but pay close attention to the wording:
hypermedia must be the &lt;em&gt;core&lt;/em&gt; of your application state. The way most Web apps
are built today, HTML is clearly not the core of the state, but merely a way to render
it. This is the accidental consequence of treating Web applications and desktop client
applications as just pale reflections of one another.
&lt;/p&gt;
&lt;p&gt;
The next section, 5.1.6 ("Layered System") again builds on the notion of stateless-server
architecture to provide additional flexibility and power:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
In order to further improve behavior for Internet-scale requirements, we add layered
system constraints (Figure 5-7). As described in Section 3.4.2, the layered system
style allows an architecture to be composed of hierarchical layers by constraining
component behavior such that each component cannot "see" beyond the immediate layer
with which they are interacting. By restricting knowledge of the system to a single
layer, we place a bound on the overall system complexity and promote substrate independence.
Layers can be used to encapsulate legacy services and to protect new services from
legacy clients, simplifying components by moving infrequently used functionality to
a shared intermediary. Intermediaries can also be used to improve system scalability
by enabling load balancing of services across multiple networks and processors. 
&lt;p&gt;
The primary disadvantage of layered systems is that they add overhead and latency
to the processing of data, reducing user-perceived performance [32].&lt;em&gt; For a network-based
system that supports cache constraints, this can be offset by the benefits of shared
caching at intermediaries.&lt;/em&gt; Placing shared caches at the boundaries of an organizational
domain can result in significant performance benefits [136]. Such layers also allow
security policies to be enforced on data crossing the organizational boundary, as
is required by firewalls [79]. 
&lt;p&gt;
The combination of layered system and uniform interface constraints induces architectural
properties similar to those of the uniform pipe-and-filter style (Section 3.2.2).
Although REST interaction is two-way, the large-grain data flows of hypermedia interaction
can each be processed like a data-flow network, with filter components selectively
applied to the data stream in order to transform the content as it passes [26]. &lt;em&gt;Within
REST, intermediary components can actively transform the content of messages because
the messages are self-descriptive and their semantics are visible to intermediaries.&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The potential of layered systems (itself not something that people building RESTful
approaches seem to think much about) is only realized if the entirety of the state
being transferred is self-descriptive and visible to the intermediaries--in other
words, intermediaries can only be helpful and/or non-performance-inhibitive if they
have free reign to make decisions based on the state they see being transferred. If
something isn't present in the state being transferred, usually because there is server-side
state being maintained, then they have to be concerned about silently changing the
semantics of what is happening in the interaction, and intermediaries--and layers
as a whole--become a liability. (Which is probably why so few systems seem to do it.)
&lt;/p&gt;
&lt;p&gt;
And if the notion of visible, transported state is not yet made clear in his dissertation,
Fielding dissects the discussion even further in section 5.2.1, "Data Elements". It's
too long to reprint here in its entirety, and frankly, reading the whole thing is
necessary to see the point of hypermedia and its place in the whole system. (The same
could be said of the entire chapter, in fact.) But it's pretty clear, once you read
the dissertation, that hypermedia/hypertext is a core, critical piece to the whole
REST construction. Clients are expected, in a RESTful system, to have &lt;em&gt;no&lt;/em&gt; preconceived
notions of structure or relationship between resources, and discover all of that through
the state of the hypertext documents that are sent back to them. In the HTML case,
that discovery occurs inside the human brain; in the SOA/services case, that discovery
is much harder to define and describe. RDF and Semantic Web ideas may be of some help
here, but JSON can't, and simple XML can't, unless the client has some preconceived
notion of what the XML structure looks like, which violates Fielding's rules:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
A REST API should be entered with no prior knowledge beyond the initial URI (bookmark)
and set of standardized media types that are appropriate for the intended audience
(i.e., expected to be understood by any client that might use the API). From that
point on, all application state transitions must be driven by client selection of
server-provided choices that are present in the received representations or implied
by the user’s manipulation of those representations. The transitions may be determined
(or limited by) the client’s knowledge of media types and resource communication mechanisms,
both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies
that out-of-band information is driving interaction instead of hypertext.]
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
An interesting "fuzzy gray area" here is whether or not the client's knowledge of
a variant or schematic structure of XML could be considered to be a "standardized
media type", but I'm willing to bet that Fielding will argue against it on the grounds
that your application's XML schema is not "standardized" (unless, of course, it is,
through a national/international/industry standardization effort).
&lt;/p&gt;
&lt;p&gt;
But in case you'd missed it, let me summarize the past twenty or so paragraphs: &lt;em&gt;hypermedia
is a core requirement to being RESTful.&lt;/em&gt; If you ain't slinging all of your application
state back and forth in hypertext, you ain't REST. Period. Fielding said it, he defined
it, and that settles it.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Before the hate mail comes a-flyin', let me reiterate one vitally important point: &lt;em&gt;if
you're not doing REST, it doesn't mean that your API sucks.&lt;/em&gt; Fielding may have
his definition of what REST is, and the idealist in me wants to remain true to his
definitions of it (after all, if we can't agree on a common set of definitions, a
common lexicon, then we can't really make much progress as an industry), but...
&lt;/p&gt;
&lt;p&gt;
... the pragmatist in me keeps saying, "so what"?
&lt;/p&gt;
&lt;p&gt;
Look, at the end of the day, if your system wants to misuse HTTP, abuse HTML, and
carnally violate the principles of loose coupling and resource representation that
underlie REST, who cares? Do you get special bonus points from the Apache Foundation
if you use HTTP in the way Fielding intended? Will Microsoft and Oracle and Sun and
IBM offer you discounts on your next software purchases if you create a REST-faithful
system? Will the partisan politics in Washington, or the tribal conflicts in the Middle
East, or even the widely-misnamed "REST-vs-SOAP" debates come to an end if you only
figure out a way to make hypermedia the core engine of your application state?
&lt;/p&gt;
&lt;p&gt;
Yeah, I didn't think so, either.
&lt;/p&gt;
&lt;p&gt;
Point is, REST is &lt;em&gt;just&lt;/em&gt; an architectural style. It is nothing more than another
entry alongside such things as client-server, &lt;em&gt;n&lt;/em&gt;-tier, distributed objects,
service-oriented, and embedded systems. REST is just a tool for thinking about how
to build an application, and it's high time we kick it off the pedastal on which we've
placed it and let it come back down to earth with the rest of us mortals. HTTP is
useful, but not sufficient, so solve our problems. REST is as well.
&lt;/p&gt;
&lt;p&gt;
And at the end of the day, when we put one tool from our tool belt "above all others",
we end up building some truly horrendous crap.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=44481f40-dbca-438c-9398-2ed93a3d62d8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,44481f40-dbca-438c-9398-2ed93a3d62d8.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Security</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=277a29cb-c011-45a3-82f9-6e702d5ad5df</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,277a29cb-c011-45a3-82f9-6e702d5ad5df.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,277a29cb-c011-45a3-82f9-6e702d5ad5df.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=277a29cb-c011-45a3-82f9-6e702d5ad5df</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The full list is <a href="http://www.noop.nl/2008/09/top-100-blogs-for-development-managers-q3-2008.html">here</a>.
It's a pretty prestigious group--and I'm totally floored that I'm there next to some
pretty big names.
</p>
        <p>
In homage to Ms. Sally Fields, of so many years ago... "You like me, you really like
me". Having somebody come up to me at a conference and tell me how much they like
my blog is second on my list of "fun things to happen to me at a conference", right
behind having somebody come up to me at a conference and tell me how much they like
my blog, except for that one entry, where I said something <em>totally</em> ridiculous
(and here's why) ....
</p>
        <p>
What I find most fascinating about the list was the means by which it was constructed--the
various calculations behind page rank, technorati rating, and so on. Very cool stuff.
</p>
        <p>
Perhaps it's trite to say it, but it's still true: readers are what make writing blogs
worthwhile. Thanks to all of you.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=277a29cb-c011-45a3-82f9-6e702d5ad5df" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Apparently I'm #25 on the Top 100 Blogs for Development Managers</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,277a29cb-c011-45a3-82f9-6e702d5ad5df.aspx</guid>
      <link>http://blogs.tedneward.com/2008/09/15/Apparently+Im+25+On+The+Top+100+Blogs+For+Development+Managers.aspx</link>
      <pubDate>Mon, 15 Sep 2008 11:29:19 GMT</pubDate>
      <description>&lt;p&gt;
The full list is &lt;a href="http://www.noop.nl/2008/09/top-100-blogs-for-development-managers-q3-2008.html"&gt;here&lt;/a&gt;.
It's a pretty prestigious group--and I'm totally floored that I'm there next to some
pretty big names.
&lt;/p&gt;
&lt;p&gt;
In homage to Ms. Sally Fields, of so many years ago... "You like me, you really like
me". Having somebody come up to me at a conference and tell me how much they like
my blog is second on my list of "fun things to happen to me at a conference", right
behind having somebody come up to me at a conference and tell me how much they like
my blog, except for that one entry, where I said something &lt;em&gt;totally&lt;/em&gt; ridiculous
(and here's why) ....
&lt;/p&gt;
&lt;p&gt;
What I find most fascinating about the list was the means by which it was constructed--the
various calculations behind page rank, technorati rating, and so on. Very cool stuff.
&lt;/p&gt;
&lt;p&gt;
Perhaps it's trite to say it, but it's still true: readers are what make writing blogs
worthwhile. Thanks to all of you.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=277a29cb-c011-45a3-82f9-6e702d5ad5df" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,277a29cb-c011-45a3-82f9-6e702d5ad5df.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Security</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>VMWare</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=b63b60d2-4c68-4bc4-8d7a-d4c82cde958d</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,b63b60d2-4c68-4bc4-8d7a-d4c82cde958d.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,b63b60d2-4c68-4bc4-8d7a-d4c82cde958d.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b63b60d2-4c68-4bc4-8d7a-d4c82cde958d</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Another DZone newsletter crosses my Inbox, and again I feel compelled to comment.
Not so much in the uber-aggressive style of my previous attempt, since I find myself
more on the fence on this one, but because I think it's a worthwhile debate and worth
calling out.
</p>
        <p>
The article in question is "5 Reasons Why You Don't Want A Jack-of-all-Trades Developer",
by Rebecca Murphey. In it, she talks about the all-too-common want-ad description
that appears on job sites and mailing lists:
</p>
        <blockquote>
          <p>
I've spent the last couple of weeks trolling Craigslist and have been shocked at the
number of ads I've found that seem to be looking for an entire engineering team rolled
up into a single person. Descriptions like this aren't at all uncommon: 
</p>
          <blockquote>
            <p>
Candidates must have 5 years experience defining and developing data driven web sites
and have solid experience with ASP.NET, HTML, XML, JavaScript, CSS, Flash, SQL, and
optimizing graphics for web use. The candidate must also have project management skills
and be able to balance multiple, dynamic, and sometimes conflicting priorities. This
position is an integral part of executing our web strategy and must have excellent
interpersonal and communication skills.
</p>
          </blockquote>
        </blockquote>
        <p>
Her disdain for this practice is the focus of the rest of the article:
</p>
        <blockquote>
          <p>
Now I don't know about you, but if I were building a house, I wouldn't want an architect
doing the work of a carpenter, or the foundation guy doing the work of an electrician.
But ads like the one above are suggesting that a single person can actually do all
of these things, and the simple fact is that these are fundamentally different skills.
The foundation guy may build a solid base, but put him in charge of wiring the house
and the whole thing could, well, burn down. When it comes to staffing a web project
or product, the principle isn't all that different -- nor is the consequence.
</p>
        </blockquote>
        <p>
I'll admit, when I got to this point in the article, I was fully ready to start the
argument right here and now--developers <em>have</em> to have a well-rounded collection
of skills, since anecdotal evidence suggests that trying to go the route of programming
specialization (along the lines of medical specialization) isn't going to work out,
particularly given the shortage of programmers in the industry right now to begin
with. But she goes on to make an interesting point:
</p>
        <blockquote>
          <p>
The thing is, the more you know, the more you find out you don't know. A year ago
I'd have told you I could write PHP/MySQL applications, and do the front-end too;
now that I've seen what it means to be truly skilled at the back-end side of things,
I realize the most accurate thing I can say is that I understand PHP applications
and how they relate to my front-end development efforts. To say that I can write them
myself is to diminish the good work that truly skilled PHP/MySQL developers are doing,
just as I get a little bent when a back-end developer thinks they can do my job.
</p>
        </blockquote>
        <p>
She really caught me eye (and interest) with that first statement, because it echoes
something Bjarne Stroustrup told me almost 15 years ago, in an email reply sent back
to me (in response to my rather audacious cold-contact email inquiry about the costs
and benefits of writing a book): "The more you know, the more you know you don't know".
What I think also caught my eye--and, I admit it, earned respect--was her admission
that she maybe isn't as good at something as she thought she was before. This kind
of reflective admission is a good thing (and missing far too much from our industry,
IMHO), because it leads not only to better job placements for us as well as the companies
that want to hire us, but also because the more honest we can be about our own skills,
the more we can focus efforts on learning what needs to be learned in order to grow.
</p>
        <p>
She then turns to her list of 5 reasons, phrased more as a list of suggestions to
companies seeking to hire programming talent; my comments are in italics:
</p>
        <blockquote>
          <p>
So to all of those companies who are writing ads seeking one magical person to fill
all of their needs, I offer a few caveats before you post your next Craigslist ad: 
</p>
          <p>
1. If you're seeking a single person with all of these skills, make sure you have
the technical expertise to determine whether a person's skills match their resume.
Outsource a tech interview if you need to. Any developer can tell horror stories about
inept predecessors, but when a front-end developer like myself can read PHP and think
it's appalling, that tells me someone didn't do a very good job of vetting and got
stuck with a programmer who couldn't deliver on his stated skills. 
</p>
          <p>
            <em>(T: I cannot stress this enough--the technical interview process practiced at
most companies is a complete sham and travesty, and usually only succeeds in making
sure the company doesn't hire a serial killer, would-be terrorist, or financially
destitute freeway-underpass resident. I seriously think most companies should outsource
the technical interview process entirely.)</em>
          </p>
          <p>
2. A single source for all of these skills is a single point of failure on multiple
fronts. Think long and hard about what it will mean to your project if the person
you hire falls short in some aspect(s), and about the mistakes that will have to be
cleaned up when you get around to hiring specialized people. I have spent countless
days cleaning up after back-end developers who didn't understand the nuances and power
of CSS, or the difference between a div, a paragraph, a list item, and a span. Really. 
</p>
          <p>
            <em>(T: I'm not as much concerned about the single point of failure argument here,
to be honest. Developers will always have "edges" to what they know, and companies
will constantly push developers to that edge for various reasons, most of which seem
to be financial--"Why pay two people to do what one person can do?" is a really compelling
argument to the CFO, particularly when measured against an unquantifiable, namely
the quality of the project.)</em>
          </p>
          <p>
3. Writing efficient SQL is different from efficiently producing web-optimized graphics.
Administering a server is different from troubleshooting cross-browser issues. Trust
me. All are integral to the performance and growth of your site, and so you're right
to want them all -- just not from the same person. Expecting quality results in every
area from the same person goes back to the foundation guy doing the wiring. You're
playing with fire. 
</p>
          <p>
            <em>(T: True, but let's be honest about something here. It's not so much that the
company wants to play with fire, or that the company has a manual entitled "Running
a Dilbert Company" that says somewhere inside it, "Thou shouldst never hire more than
one person to run the IT department", but that the company is dealing with limited
budgets and headcount. If you only have room for one head under the budget, you want
the maximum for that one head. And please don't tell me how wrong that practice of
headcount really is--you're preaching to the choir on that one. The people you want
to preach to are the Jack Welches of the world, who apparently aren't listening to
us very much.)</em>
          </p>
          <p>
4. Asking for a laundry list of skills may end up deterring the candidates who will
be best able to fill your actual need. Be precise in your ad: about the position's
title and description, about the level of skill you're expecting in the various areas,
about what's nice to have and what's imperative. If you're looking to fill more than
one position, write more than one ad; if you don't know exactly what you want, try
harder to figure it out before you click the publish button. 
</p>
          <p>
            <em>(T: Asking people to think before publishing? Heresy! Truthfully, I don't think
it's a question of not knowing what they want, it's more trying to find what they
want. I've seen how some of these same job ads get generated, and it's usually because
a programmer on the team has left, and they had some degree of skill in all of those
areas. What the company wants, then, is somebody who can step into exactly what that
individual was doing before they handed in their resignation, but ads like, "Candidate
should look at Joe Smith's resume on Dice.com (http://...) and have exactly that same
skill set. Being named Joe Smith a desirable 'plus', since then we won't have to have
the sysadmins create a new login handle for you." won't attract much attention. Frankly,
what I've found most companies want is to just not lose the programmer in the first
place.)</em>
          </p>
          <p>
5. If you really do think you want one person to do the task of an entire engineering
team, prepare yourself to get someone who is OK at a bunch of things and not particularly
good at any of them. Again: the more you know, the more you find out you don't know.
I regularly team with a talented back-end developer who knows better than to try to
do my job, and I know better than to try to do his. Anyone who represents themselves
as being a master of front-to-back web development may very well have no idea just
how much they don't know, and could end up imperiling your product or project -- front
to back -- as a result. 
</p>
          <p>
            <em>(T: Or be prepared to pay a lot of money for somebody who is an expert at all
of those things, or be prepared to spend a lot of time and money growing somebody
into that role. Sometimes the exact right thing to do is have one person do it all,
but usually it's cheaper to have a small team work together.)</em>
          </p>
        </blockquote>
        <p>
(On a side note, I find it amusing that she seems to consider PHP a back-end skill,
but I don't want to sound harsh doing so--that's just a matter of perspective, I suppose.
(I can just imagine the guffaws from the mainframe guys when I talk about EJB, message-queue
and Spring systems being "back-end", too.) To me, the whole "web" thing is front-end
stuff, whether you're the one generating the HTML from your PHP or servlet/JSP or
ASP.NET server-side engine, or you're the one generating the CSS and graphics images
that are sent back to the browser by said server-side engine. If a user sees something
I did, it's probably because something bad happened and they're looking at a stack
trace on the screen.)
</p>
        <p>
The thing I find interesting is that HR hiring practices and job-writing skills haven't
gotten any better in the near-to-two-decades I've been in this industry. I can still
remember a fresh-faced wet-behind-the-ears Stroustrup-2nd-Edition-toting job candidate
named Neward looking at job placement listings and finding much the same kind of laundry
list of skills, including those with the impossible number of years of experience.
(In 1995, I saw an ad looking for somebody who had "10 years of C++ experience", and
wondering, "Gosh, I guess they're looking to hire Stroustrup or Lippmann", since those
two are the only people who could possibly have filled that requirement at the time.
This was right before reading the ad that was looking for 5 years of Java experience,
or the ad below it looking for 15 years of Delphi....)
</p>
        <p>
Given that it doesn't seem likely that HR departments are going to "get a clue" any
time soon, it leaves us with an interesting question: if you're a developer, and you're
looking at these laundry lists of requirements, how do you respond?
</p>
        <p>
Here's my own list of things for programmers/developers to consider over the next
five to ten years:
</p>
        <ol>
          <li>
            <em>These "laundry list" ads are not going away any time soon.</em> We can rant and
rail about the stupidity of HR departments and hiring managers all we want, but the
basic fact is, this is the way things are going to work for the forseeable future,
it seems. Changing this would require a "sea change" across the industry, and sea
change doesn't happen overnight, or even within the span of a few years. So, to me,
the right question to ask isn't, "How do I change the industry to make it easier for
me to find a job I can do?", but "How do I change what I do when looking for a job
to better respond to what the industry is doing?" 
</li>
          <li>
            <em>Exclusively focusing on a single area of technology is the Kiss of Death.</em> If
all you know is PHP, then your days are numbered. I mean no disrespect to the PHP
developers of the world--in fact, were it not too ambiguous to say it, I would rephrase
that as "If all you know is <em>X</em>, your days are numbered." There is no one technical
skill that will be as much in demand in ten years as it is now. Technologies age.
Industry evolves. Innovations come along that completely change the game and leave
our predictions of a few years ago in the dust. Bill Gates (he of the "640K comment")
has said, and I think he's spot on with this, "We routinely overestimate where we
will be in five years, and vastly underestimate where we will be in ten." If you put
all your eggs in the PHP basket, then when PHP gets phased out in favor of <em>(insert
new "hotness" here)</em>, you're screwed. Unless, of course, you want to wait until
you're the last man standing, which seems to have paid off well for the few COBOL
developers still alive.... but not so much for the Algol, Simula, or RPG folks.... 
</li>
          <li>
            <em>Assuming that you can stop learning is the Kiss of Death.</em> Look, if you want
to stop learning at some point and coast on what you know, be prepared to switch industries.
This one, for the forseeable future, is one that's predicated on radical innovation
and constant change. This means we have to accept that everything is in a constant
state of flux--you can either rant and rave against it, or roll with it. This doesn't
mean that you don't have to look back, though--anybody who's been in this industry
for more than 10 years has seen how we keep reinventing the wheel, particularly now
that the relationship between Ruby and Smalltalk has been put up on the big stage,
so to speak. Do yourself a favor: learn stuff that's already "done", too, because
it turns out there's a lot of lessons we can learn from those who came before us.
"Those who cannot remember the past are condemned to repeat it" (George Santanyana).
Case in point: if you're trying to get into XML services, spend some time learning
CORBA and DCOM, and compare how they do things against WSDL and SOAP. What's similar?
What's different? Do some Googling and see if you can find comparison articles between
the two, and what XML services were supposed to "fix" from the previous two. You don't
have to write a ton of CORBA or DCOM code to see those differences (though writing
at least a little CORBA/DCOM code will probably help.) 
</li>
          <li>
            <em>Find a collection of people smarter than you.</em> Chad Fowler calls this "Being
the worst player in any band you're in" (<em>My Job Went to India (and All I Got Was
This Lousy Book)</em>, Pragmatic Press<em>)</em>. The more you surround yourself with
smart people, the more of these kinds of things (tools, languages, etc) you will pick
up merely by osmosis, and find yourself more attractive to those kind of "laundry
list" job reqs. If nothing else, it speaks well to you as an employee/consultant if
you can say, "I don't know the answer to that question, but I know people who do,
and I can get them to help me". 
</li>
          <li>
            <em>Learn to be at least self-sufficient in related, complementary technologies.</em> We
see laundry list ads in "clusters". Case in point: if the company is looking for somebody
to work on their website, they're going to rattle off a list of five or so things
they want he/she to know--HTML, CSS, XML, JavaScript and sometimes Flash (or maybe
now Silverlight), in addition to whatever server-side technology they're using (ASP.NET,
servlets, PHP, whatever). This is a pretty reasonable request, depending on the depth
of each that they want you to know. Here's the thing: the company does <em>not</em> want
the guy who says he knows ASP.NET (and nothing but ASP.NET), when asked to make a
small HTML or CSS change, to turn to them and say, "I'm sorry, that's not in my job
description. I only know ASP.NET. You'll have to get your HTML guy to make that change."
You should at least be comfortable with the basic syntax of all of the above (again,
with possible exception for Flash, which is the odd man out in that job ad that started
this piece), so that you can at least make sure the site isn't going to break when
you push your changes live. In the case of the ad above, learn the things that "surround"
website development: HTML, CSS, JavaScript, Flash, Java applets, HTTP (!!), TCP/IP,
server operating systems, IIS or Apache or Tomcat or some other server engine (including
the necessary admin skills to get them installed and up and running), XML (since it's
so often used for configuration), and so on. These are all "complementary" skills
to being an ASP.NET developer (or a servlet/JSP developer). If you're a C# or Java
programmer, learn different programming languages, a la F# (.NET) or Scala (Java),
IronRuby (.NET) or JRuby (Java), and so on. If you're a Ruby developer, learn either
a JVM language or a CLR language, so you can "plug in" more easily to the large corporate
enterprise when that call comes. 
</li>
          <li>
            <em>Learn to "read" the ad at a higher level.</em> It's often possible to "read between
the lines" and get an idea of what they're looking for, even before talking to anybody
at the company about the job. For example, I read the ad that started this piece,
and the internal dialogue that went on went something like this: <blockquote>Candidates
must have 5 years experience <em>(No entry-level developers wanted, they want somebody
who can get stuff done without having their hand held through the process) </em>defining
and developing data driven <em>(they want somebody who's comfortable with SQL and
databases) </em>web sites <em>(wait for it, the "web cluster" list is coming) </em>and
have solid experience with ASP.NET <em>(OK, they're at least marginally a Microsoft
shop, that means they probably also want some Windows Server and IIS experience)</em>,
HTML, XML, JavaScript, CSS <em>(the "web cluster", knew that was coming)</em>, Flash <em>(OK,
I wonder if this is because they're building rich internet/intranet apps already,
or just flirting with the idea?)</em>, SQL <em>(knew that was coming)</em>, and optimizing
graphics for web use <em>(OK, this is another wrinkle--this smells of "we don't want
our graphics-heavy website to suck")</em>. The candidate must also have project management
skills <em>(in other words, "You're on your own, sucka!"--you're not part of a project
team) </em>and be able to balance multiple, dynamic, and sometimes conflicting priorities <em>(in
other words, "You're own your own trying to balance between the CTO's demands and
the CEO's demands, sucka!", since you're not part of a project team; this also probably
means you're not moving into an existing project, but doing more maintenance work
on an existing site)</em>. This position is an integral part of executing our web
strategy <em>(in other words, this project has public visibility and you can't let
stupid errors show up on the website and make us all look bad) </em>and must have
excellent interpersonal and communication skills <em>(what job </em>doesn't<em> need
excellent interpersonal and communication skills?)</em>.</blockquote>See what I mean?
They want an ASP.NET dev. My guess is that they're thinking a lot about Silverlight,
since Silverlight's closest competitor is Flash, and so theoretically an ASP.NET-and-Flash
dev would know how to use Silverlight well. Thus, I'm guessing that the HTML, CSS,
and JavaScript don't need to be "Adept" level, nor even "Master" level, but "Journeyman"
is probably necessary, and maybe you could get away with "Apprentice" at those levels,
if you're working as part of a team. The SQL part will probably have to be "Journeyman"
level, the XML could probably be just "Apprentice", since I'm guessing it's only necessary
for the web.config files to control the ASP.NET configuration, and the "optimizing
web graphics", push-come-to-shove, could probably be forgiven if you've had some experience
at doing some performance tuning of a website. 
</li>
          <li>
            <em>Be insightful.</em> I know, every interview book ever written says you should
"ask questions", but what they're really getting at is "Demonstrate that you've thought
about this company and this position". Demonstrating insight about the position and
the company and technology as a whole is a good way to prove that you're a neck above
the other candidates, and will help keep the job once you've got it. 
</li>
          <li>
            <em>Be honest about what you know.</em> Let's be honest--we've all met developers
who claimed they were "experts" in a particular tool or technology, and then painfully
demonstrated how far from "expert" status they really were. Be honest about yourself:
claim your skills on a simple four-point scale. "Apprentice" means "I read a book
on it" or "I've looked at it", but "there's no way I could do it on my own without
some serious help, and ideally with a Master looking over my shoulder". "Journeyman"
means "I'm competent at it, I know the tools/technology"; or, put another way, "I
can do 80% of what anybody can ask me to do, and I know how to find the other 20%
when those situations arise". "Master" means "I not only claim that I can do what
you ask me to do with it, I can optimize systems built with it, I can make it do things
others wouldn't attempt, and I can help others learn it better". Masters are routinely
paired with Apprentices as mentors or coaches, and should expect to have this as a
major part of their responsibilities. (Ideally, anybody claiming "architect" in their
title should be a Master at one or two of the core tools/technologies used in their
system; or, put another way, architects should be <em>very</em> dubious about architecting
with something they can't reasonably claim at least Journeyman status in.) "Adept",
shortly put, means you are not only fully capable of pulling off anything a Master
can do, but you routinely take the tool/technology way beyond what anybody else thinks
possible, or you know the depth of the system so well that you can fix bugs just by
thinking about them. With your eyes closed. While drinking a glass of water. Seriously,
Adept status is not something to claim lightly--not only had you better know the guys
who created the thing personally, but you should have offered up suggestions on how
to make it better and had one or more of them accepted. 
</li>
          <li>
            <em>Demonstrate that you have relevant skills beyond what they asked for.</em> Look
at the ad in question: they want an ASP.NET dev, so any familiarity with IIS, Windows
Server, SQL Server, MSMQ, COM/DCOM/COM+, WCF/Web services, SharePoint, the CLR, IronPython,
or IronRuby should be listed prominently on your resume, and brought up at least twice
during your interview. These are (again) complementary technologies, and even if the
company doesn't have a need for those things right now, it's probably because Joe
didn't know any of those, and so they couldn't use them without sending Joe to a training
class. If you bring it up during the interview, it can also show some insight on your
part: "So, any questions for us?" "Yes, are you guys using Windows Server 2008, or
2003, for your back end?" "Um, we're using 2003, why do you ask?" "Oh, well, when
I was working as an ASP.NET dev for my previous company, we moved up to 2008 because
it had the Froobinger Enhancement, which let us...., and I was just curious if you
guys had a similar need." Or something like that. Again, be entirely honest about
what you know--if you helped the server upgrade by just putting the CDs into the drive
and punching the power button, then say as much. 
</li>
          <li>
            <em>Demonstrate that you can talk to project stakeholders and users.</em> Communication
is huge. The era of the one-developer team is long since over--you have to be able
to meet with project champions, users, other developers, and so on. If you can't do
that without somebody being offended at your lack of tact and subtlety (or your lack
of personal hygiene), then don't expect to get hired too often. 
</li>
          <li>
            <em>Demonstrate that you understand the company, its business model, and what would
help it move forward.</em> Developers who actually understand business are surprisingly
and unfortunately rare. Be one of the rare ones, and you'll find companies highly
reluctant to let you go.</li>
        </ol>
        <p>
Is this an exhaustive list? Hardly. Is this list guaranteed to keep you employed forever?
Nope. But this seems to be working for a lot of the people I run into at conferences
and client consulting gigs, so I humbly submit it for your consideration.
</p>
        <p>
But in no way do I consider this conversation completely over, either--feel free to
post your own suggestions, or tell me why I'm full of crap on any (or all) of these.
:-)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=b63b60d2-4c68-4bc4-8d7a-d4c82cde958d" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>The Never-Ending Debate of Specialist v. Generalist</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,b63b60d2-4c68-4bc4-8d7a-d4c82cde958d.aspx</guid>
      <link>http://blogs.tedneward.com/2008/08/14/The+NeverEnding+Debate+Of+Specialist+V+Generalist.aspx</link>
      <pubDate>Thu, 14 Aug 2008 22:38:42 GMT</pubDate>
      <description>&lt;p&gt;
Another DZone newsletter crosses my Inbox, and again I feel compelled to comment.
Not so much in the uber-aggressive style of my previous attempt, since I find myself
more on the fence on this one, but because I think it's a worthwhile debate and worth
calling out.
&lt;/p&gt;
&lt;p&gt;
The article in question is "5 Reasons Why You Don't Want A Jack-of-all-Trades Developer",
by Rebecca Murphey. In it, she talks about the all-too-common want-ad description
that appears on job sites and mailing lists:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
I've spent the last couple of weeks trolling Craigslist and have been shocked at the
number of ads I've found that seem to be looking for an entire engineering team rolled
up into a single person. Descriptions like this aren't at all uncommon: &lt;blockquote&gt; 
&lt;p&gt;
Candidates must have 5 years experience defining and developing data driven web sites
and have solid experience with ASP.NET, HTML, XML, JavaScript, CSS, Flash, SQL, and
optimizing graphics for web use. The candidate must also have project management skills
and be able to balance multiple, dynamic, and sometimes conflicting priorities. This
position is an integral part of executing our web strategy and must have excellent
interpersonal and communication skills.
&lt;/p&gt;
&lt;/blockquote&gt;&lt;/blockquote&gt; 
&lt;p&gt;
Her disdain for this practice is the focus of the rest of the article:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Now I don't know about you, but if I were building a house, I wouldn't want an architect
doing the work of a carpenter, or the foundation guy doing the work of an electrician.
But ads like the one above are suggesting that a single person can actually do all
of these things, and the simple fact is that these are fundamentally different skills.
The foundation guy may build a solid base, but put him in charge of wiring the house
and the whole thing could, well, burn down. When it comes to staffing a web project
or product, the principle isn't all that different -- nor is the consequence.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I'll admit, when I got to this point in the article, I was fully ready to start the
argument right here and now--developers &lt;em&gt;have&lt;/em&gt; to have a well-rounded collection
of skills, since anecdotal evidence suggests that trying to go the route of programming
specialization (along the lines of medical specialization) isn't going to work out,
particularly given the shortage of programmers in the industry right now to begin
with. But she goes on to make an interesting point:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
The thing is, the more you know, the more you find out you don't know. A year ago
I'd have told you I could write PHP/MySQL applications, and do the front-end too;
now that I've seen what it means to be truly skilled at the back-end side of things,
I realize the most accurate thing I can say is that I understand PHP applications
and how they relate to my front-end development efforts. To say that I can write them
myself is to diminish the good work that truly skilled PHP/MySQL developers are doing,
just as I get a little bent when a back-end developer thinks they can do my job.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
She really caught me eye (and interest) with that first statement, because it echoes
something Bjarne Stroustrup told me almost 15 years ago, in an email reply sent back
to me (in response to my rather audacious cold-contact email inquiry about the costs
and benefits of writing a book): "The more you know, the more you know you don't know".
What I think also caught my eye--and, I admit it, earned respect--was her admission
that she maybe isn't as good at something as she thought she was before. This kind
of reflective admission is a good thing (and missing far too much from our industry,
IMHO), because it leads not only to better job placements for us as well as the companies
that want to hire us, but also because the more honest we can be about our own skills,
the more we can focus efforts on learning what needs to be learned in order to grow.
&lt;/p&gt;
&lt;p&gt;
She then turns to her list of 5 reasons, phrased more as a list of suggestions to
companies seeking to hire programming talent; my comments are in italics:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
So to all of those companies who are writing ads seeking one magical person to fill
all of their needs, I offer a few caveats before you post your next Craigslist ad: 
&lt;p&gt;
1. If you're seeking a single person with all of these skills, make sure you have
the technical expertise to determine whether a person's skills match their resume.
Outsource a tech interview if you need to. Any developer can tell horror stories about
inept predecessors, but when a front-end developer like myself can read PHP and think
it's appalling, that tells me someone didn't do a very good job of vetting and got
stuck with a programmer who couldn't deliver on his stated skills. 
&lt;p&gt;
&lt;em&gt;(T: I cannot stress this enough--the technical interview process practiced at
most companies is a complete sham and travesty, and usually only succeeds in making
sure the company doesn't hire a serial killer, would-be terrorist, or financially
destitute freeway-underpass resident. I seriously think most companies should outsource
the technical interview process entirely.)&lt;/em&gt; 
&lt;p&gt;
2. A single source for all of these skills is a single point of failure on multiple
fronts. Think long and hard about what it will mean to your project if the person
you hire falls short in some aspect(s), and about the mistakes that will have to be
cleaned up when you get around to hiring specialized people. I have spent countless
days cleaning up after back-end developers who didn't understand the nuances and power
of CSS, or the difference between a div, a paragraph, a list item, and a span. Really. 
&lt;p&gt;
&lt;em&gt;(T: I'm not as much concerned about the single point of failure argument here,
to be honest. Developers will always have "edges" to what they know, and companies
will constantly push developers to that edge for various reasons, most of which seem
to be financial--"Why pay two people to do what one person can do?" is a really compelling
argument to the CFO, particularly when measured against an unquantifiable, namely
the quality of the project.)&lt;/em&gt; 
&lt;p&gt;
3. Writing efficient SQL is different from efficiently producing web-optimized graphics.
Administering a server is different from troubleshooting cross-browser issues. Trust
me. All are integral to the performance and growth of your site, and so you're right
to want them all -- just not from the same person. Expecting quality results in every
area from the same person goes back to the foundation guy doing the wiring. You're
playing with fire. 
&lt;p&gt;
&lt;em&gt;(T: True, but let's be honest about something here. It's not so much that the
company wants to play with fire, or that the company has a manual entitled "Running
a Dilbert Company" that says somewhere inside it, "Thou shouldst never hire more than
one person to run the IT department", but that the company is dealing with limited
budgets and headcount. If you only have room for one head under the budget, you want
the maximum for that one head. And please don't tell me how wrong that practice of
headcount really is--you're preaching to the choir on that one. The people you want
to preach to are the Jack Welches of the world, who apparently aren't listening to
us very much.)&lt;/em&gt; 
&lt;p&gt;
4. Asking for a laundry list of skills may end up deterring the candidates who will
be best able to fill your actual need. Be precise in your ad: about the position's
title and description, about the level of skill you're expecting in the various areas,
about what's nice to have and what's imperative. If you're looking to fill more than
one position, write more than one ad; if you don't know exactly what you want, try
harder to figure it out before you click the publish button. 
&lt;p&gt;
&lt;em&gt;(T: Asking people to think before publishing? Heresy! Truthfully, I don't think
it's a question of not knowing what they want, it's more trying to find what they
want. I've seen how some of these same job ads get generated, and it's usually because
a programmer on the team has left, and they had some degree of skill in all of those
areas. What the company wants, then, is somebody who can step into exactly what that
individual was doing before they handed in their resignation, but ads like, "Candidate
should look at Joe Smith's resume on Dice.com (http://...) and have exactly that same
skill set. Being named Joe Smith a desirable 'plus', since then we won't have to have
the sysadmins create a new login handle for you." won't attract much attention. Frankly,
what I've found most companies want is to just not lose the programmer in the first
place.)&lt;/em&gt; 
&lt;p&gt;
5. If you really do think you want one person to do the task of an entire engineering
team, prepare yourself to get someone who is OK at a bunch of things and not particularly
good at any of them. Again: the more you know, the more you find out you don't know.
I regularly team with a talented back-end developer who knows better than to try to
do my job, and I know better than to try to do his. Anyone who represents themselves
as being a master of front-to-back web development may very well have no idea just
how much they don't know, and could end up imperiling your product or project -- front
to back -- as a result. 
&lt;p&gt;
&lt;em&gt;(T: Or be prepared to pay a lot of money for somebody who is an expert at all
of those things, or be prepared to spend a lot of time and money growing somebody
into that role. Sometimes the exact right thing to do is have one person do it all,
but usually it's cheaper to have a small team work together.)&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
(On a side note, I find it amusing that she seems to consider PHP a back-end skill,
but I don't want to sound harsh doing so--that's just a matter of perspective, I suppose.
(I can just imagine the guffaws from the mainframe guys when I talk about EJB, message-queue
and Spring systems being "back-end", too.) To me, the whole "web" thing is front-end
stuff, whether you're the one generating the HTML from your PHP or servlet/JSP or
ASP.NET server-side engine, or you're the one generating the CSS and graphics images
that are sent back to the browser by said server-side engine. If a user sees something
I did, it's probably because something bad happened and they're looking at a stack
trace on the screen.)
&lt;/p&gt;
&lt;p&gt;
The thing I find interesting is that HR hiring practices and job-writing skills haven't
gotten any better in the near-to-two-decades I've been in this industry. I can still
remember a fresh-faced wet-behind-the-ears Stroustrup-2nd-Edition-toting job candidate
named Neward looking at job placement listings and finding much the same kind of laundry
list of skills, including those with the impossible number of years of experience.
(In 1995, I saw an ad looking for somebody who had "10 years of C++ experience", and
wondering, "Gosh, I guess they're looking to hire Stroustrup or Lippmann", since those
two are the only people who could possibly have filled that requirement at the time.
This was right before reading the ad that was looking for 5 years of Java experience,
or the ad below it looking for 15 years of Delphi....)
&lt;/p&gt;
&lt;p&gt;
Given that it doesn't seem likely that HR departments are going to "get a clue" any
time soon, it leaves us with an interesting question: if you're a developer, and you're
looking at these laundry lists of requirements, how do you respond?
&lt;/p&gt;
&lt;p&gt;
Here's my own list of things for programmers/developers to consider over the next
five to ten years:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;These "laundry list" ads are not going away any time soon.&lt;/em&gt; We can rant and
rail about the stupidity of HR departments and hiring managers all we want, but the
basic fact is, this is the way things are going to work for the forseeable future,
it seems. Changing this would require a "sea change" across the industry, and sea
change doesn't happen overnight, or even within the span of a few years. So, to me,
the right question to ask isn't, "How do I change the industry to make it easier for
me to find a job I can do?", but "How do I change what I do when looking for a job
to better respond to what the industry is doing?" 
&lt;li&gt;
&lt;em&gt;Exclusively focusing on a single area of technology is the Kiss of Death.&lt;/em&gt; If
all you know is PHP, then your days are numbered. I mean no disrespect to the PHP
developers of the world--in fact, were it not too ambiguous to say it, I would rephrase
that as "If all you know is &lt;em&gt;X&lt;/em&gt;, your days are numbered." There is no one technical
skill that will be as much in demand in ten years as it is now. Technologies age.
Industry evolves. Innovations come along that completely change the game and leave
our predictions of a few years ago in the dust. Bill Gates (he of the "640K comment")
has said, and I think he's spot on with this, "We routinely overestimate where we
will be in five years, and vastly underestimate where we will be in ten." If you put
all your eggs in the PHP basket, then when PHP gets phased out in favor of &lt;em&gt;(insert
new "hotness" here)&lt;/em&gt;, you're screwed. Unless, of course, you want to wait until
you're the last man standing, which seems to have paid off well for the few COBOL
developers still alive.... but not so much for the Algol, Simula, or RPG folks.... 
&lt;li&gt;
&lt;em&gt;Assuming that you can stop learning is the Kiss of Death.&lt;/em&gt; Look, if you want
to stop learning at some point and coast on what you know, be prepared to switch industries.
This one, for the forseeable future, is one that's predicated on radical innovation
and constant change. This means we have to accept that everything is in a constant
state of flux--you can either rant and rave against it, or roll with it. This doesn't
mean that you don't have to look back, though--anybody who's been in this industry
for more than 10 years has seen how we keep reinventing the wheel, particularly now
that the relationship between Ruby and Smalltalk has been put up on the big stage,
so to speak. Do yourself a favor: learn stuff that's already "done", too, because
it turns out there's a lot of lessons we can learn from those who came before us.
"Those who cannot remember the past are condemned to repeat it" (George Santanyana).
Case in point: if you're trying to get into XML services, spend some time learning
CORBA and DCOM, and compare how they do things against WSDL and SOAP. What's similar?
What's different? Do some Googling and see if you can find comparison articles between
the two, and what XML services were supposed to "fix" from the previous two. You don't
have to write a ton of CORBA or DCOM code to see those differences (though writing
at least a little CORBA/DCOM code will probably help.) 
&lt;li&gt;
&lt;em&gt;Find a collection of people smarter than you.&lt;/em&gt; Chad Fowler calls this "Being
the worst player in any band you're in" (&lt;em&gt;My Job Went to India (and All I Got Was
This Lousy Book)&lt;/em&gt;, Pragmatic Press&lt;em&gt;)&lt;/em&gt;. The more you surround yourself with
smart people, the more of these kinds of things (tools, languages, etc) you will pick
up merely by osmosis, and find yourself more attractive to those kind of "laundry
list" job reqs. If nothing else, it speaks well to you as an employee/consultant if
you can say, "I don't know the answer to that question, but I know people who do,
and I can get them to help me". 
&lt;li&gt;
&lt;em&gt;Learn to be at least self-sufficient in related, complementary technologies.&lt;/em&gt; We
see laundry list ads in "clusters". Case in point: if the company is looking for somebody
to work on their website, they're going to rattle off a list of five or so things
they want he/she to know--HTML, CSS, XML, JavaScript and sometimes Flash (or maybe
now Silverlight), in addition to whatever server-side technology they're using (ASP.NET,
servlets, PHP, whatever). This is a pretty reasonable request, depending on the depth
of each that they want you to know. Here's the thing: the company does &lt;em&gt;not&lt;/em&gt; want
the guy who says he knows ASP.NET (and nothing but ASP.NET), when asked to make a
small HTML or CSS change, to turn to them and say, "I'm sorry, that's not in my job
description. I only know ASP.NET. You'll have to get your HTML guy to make that change."
You should at least be comfortable with the basic syntax of all of the above (again,
with possible exception for Flash, which is the odd man out in that job ad that started
this piece), so that you can at least make sure the site isn't going to break when
you push your changes live. In the case of the ad above, learn the things that "surround"
website development: HTML, CSS, JavaScript, Flash, Java applets, HTTP (!!), TCP/IP,
server operating systems, IIS or Apache or Tomcat or some other server engine (including
the necessary admin skills to get them installed and up and running), XML (since it's
so often used for configuration), and so on. These are all "complementary" skills
to being an ASP.NET developer (or a servlet/JSP developer). If you're a C# or Java
programmer, learn different programming languages, a la F# (.NET) or Scala (Java),
IronRuby (.NET) or JRuby (Java), and so on. If you're a Ruby developer, learn either
a JVM language or a CLR language, so you can "plug in" more easily to the large corporate
enterprise when that call comes. 
&lt;li&gt;
&lt;em&gt;Learn to "read" the ad at a higher level.&lt;/em&gt; It's often possible to "read between
the lines" and get an idea of what they're looking for, even before talking to anybody
at the company about the job. For example, I read the ad that started this piece,
and the internal dialogue that went on went something like this: &lt;blockquote&gt;Candidates
must have 5 years experience &lt;em&gt;(No entry-level developers wanted, they want somebody
who can get stuff done without having their hand held through the process) &lt;/em&gt;defining
and developing data driven &lt;em&gt;(they want somebody who's comfortable with SQL and
databases) &lt;/em&gt;web sites &lt;em&gt;(wait for it, the "web cluster" list is coming) &lt;/em&gt;and
have solid experience with ASP.NET &lt;em&gt;(OK, they're at least marginally a Microsoft
shop, that means they probably also want some Windows Server and IIS experience)&lt;/em&gt;,
HTML, XML, JavaScript, CSS &lt;em&gt;(the "web cluster", knew that was coming)&lt;/em&gt;, Flash &lt;em&gt;(OK,
I wonder if this is because they're building rich internet/intranet apps already,
or just flirting with the idea?)&lt;/em&gt;, SQL &lt;em&gt;(knew that was coming)&lt;/em&gt;, and optimizing
graphics for web use &lt;em&gt;(OK, this is another wrinkle--this smells of "we don't want
our graphics-heavy website to suck")&lt;/em&gt;. The candidate must also have project management
skills &lt;em&gt;(in other words, "You're on your own, sucka!"--you're not part of a project
team) &lt;/em&gt;and be able to balance multiple, dynamic, and sometimes conflicting priorities &lt;em&gt;(in
other words, "You're own your own trying to balance between the CTO's demands and
the CEO's demands, sucka!", since you're not part of a project team; this also probably
means you're not moving into an existing project, but doing more maintenance work
on an existing site)&lt;/em&gt;. This position is an integral part of executing our web
strategy &lt;em&gt;(in other words, this project has public visibility and you can't let
stupid errors show up on the website and make us all look bad) &lt;/em&gt;and must have
excellent interpersonal and communication skills &lt;em&gt;(what job &lt;/em&gt;doesn't&lt;em&gt; need
excellent interpersonal and communication skills?)&lt;/em&gt;.&lt;/blockquote&gt;See what I mean?
They want an ASP.NET dev. My guess is that they're thinking a lot about Silverlight,
since Silverlight's closest competitor is Flash, and so theoretically an ASP.NET-and-Flash
dev would know how to use Silverlight well. Thus, I'm guessing that the HTML, CSS,
and JavaScript don't need to be "Adept" level, nor even "Master" level, but "Journeyman"
is probably necessary, and maybe you could get away with "Apprentice" at those levels,
if you're working as part of a team. The SQL part will probably have to be "Journeyman"
level, the XML could probably be just "Apprentice", since I'm guessing it's only necessary
for the web.config files to control the ASP.NET configuration, and the "optimizing
web graphics", push-come-to-shove, could probably be forgiven if you've had some experience
at doing some performance tuning of a website. 
&lt;li&gt;
&lt;em&gt;Be insightful.&lt;/em&gt; I know, every interview book ever written says you should
"ask questions", but what they're really getting at is "Demonstrate that you've thought
about this company and this position". Demonstrating insight about the position and
the company and technology as a whole is a good way to prove that you're a neck above
the other candidates, and will help keep the job once you've got it. 
&lt;li&gt;
&lt;em&gt;Be honest about what you know.&lt;/em&gt; Let's be honest--we've all met developers
who claimed they were "experts" in a particular tool or technology, and then painfully
demonstrated how far from "expert" status they really were. Be honest about yourself:
claim your skills on a simple four-point scale. "Apprentice" means "I read a book
on it" or "I've looked at it", but "there's no way I could do it on my own without
some serious help, and ideally with a Master looking over my shoulder". "Journeyman"
means "I'm competent at it, I know the tools/technology"; or, put another way, "I
can do 80% of what anybody can ask me to do, and I know how to find the other 20%
when those situations arise". "Master" means "I not only claim that I can do what
you ask me to do with it, I can optimize systems built with it, I can make it do things
others wouldn't attempt, and I can help others learn it better". Masters are routinely
paired with Apprentices as mentors or coaches, and should expect to have this as a
major part of their responsibilities. (Ideally, anybody claiming "architect" in their
title should be a Master at one or two of the core tools/technologies used in their
system; or, put another way, architects should be &lt;em&gt;very&lt;/em&gt; dubious about architecting
with something they can't reasonably claim at least Journeyman status in.) "Adept",
shortly put, means you are not only fully capable of pulling off anything a Master
can do, but you routinely take the tool/technology way beyond what anybody else thinks
possible, or you know the depth of the system so well that you can fix bugs just by
thinking about them. With your eyes closed. While drinking a glass of water. Seriously,
Adept status is not something to claim lightly--not only had you better know the guys
who created the thing personally, but you should have offered up suggestions on how
to make it better and had one or more of them accepted. 
&lt;li&gt;
&lt;em&gt;Demonstrate that you have relevant skills beyond what they asked for.&lt;/em&gt; Look
at the ad in question: they want an ASP.NET dev, so any familiarity with IIS, Windows
Server, SQL Server, MSMQ, COM/DCOM/COM+, WCF/Web services, SharePoint, the CLR, IronPython,
or IronRuby should be listed prominently on your resume, and brought up at least twice
during your interview. These are (again) complementary technologies, and even if the
company doesn't have a need for those things right now, it's probably because Joe
didn't know any of those, and so they couldn't use them without sending Joe to a training
class. If you bring it up during the interview, it can also show some insight on your
part: "So, any questions for us?" "Yes, are you guys using Windows Server 2008, or
2003, for your back end?" "Um, we're using 2003, why do you ask?" "Oh, well, when
I was working as an ASP.NET dev for my previous company, we moved up to 2008 because
it had the Froobinger Enhancement, which let us...., and I was just curious if you
guys had a similar need." Or something like that. Again, be entirely honest about
what you know--if you helped the server upgrade by just putting the CDs into the drive
and punching the power button, then say as much. 
&lt;li&gt;
&lt;em&gt;Demonstrate that you can talk to project stakeholders and users.&lt;/em&gt; Communication
is huge. The era of the one-developer team is long since over--you have to be able
to meet with project champions, users, other developers, and so on. If you can't do
that without somebody being offended at your lack of tact and subtlety (or your lack
of personal hygiene), then don't expect to get hired too often. 
&lt;li&gt;
&lt;em&gt;Demonstrate that you understand the company, its business model, and what would
help it move forward.&lt;/em&gt; Developers who actually understand business are surprisingly
and unfortunately rare. Be one of the rare ones, and you'll find companies highly
reluctant to let you go.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Is this an exhaustive list? Hardly. Is this list guaranteed to keep you employed forever?
Nope. But this seems to be working for a lot of the people I run into at conferences
and client consulting gigs, so I humbly submit it for your consideration.
&lt;/p&gt;
&lt;p&gt;
But in no way do I consider this conversation completely over, either--feel free to
post your own suggestions, or tell me why I'm full of crap on any (or all) of these.
:-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=b63b60d2-4c68-4bc4-8d7a-d4c82cde958d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,b63b60d2-4c68-4bc4-8d7a-d4c82cde958d.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Development Processes</category>
      <category>F#</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Visual Basic</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=c917a24e-d656-4d7f-be58-1eb2ae816f82</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,c917a24e-d656-4d7f-be58-1eb2ae816f82.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,c917a24e-d656-4d7f-be58-1eb2ae816f82.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c917a24e-d656-4d7f-be58-1eb2ae816f82</wfw:commentRss>
      <slash:comments>9</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been asked to put together a list of the "best" Java resources that every up-and-coming
Java developer should have, and I'd like this list to be as comprehensive as possible
and, more importantly, reflect more than just my own opinion. So, either through comments
or <a href="mailto:tedATtednewardDOTcom">through email</a>, let me know what you think
the best Java resources are in the following categories:
</p>
        <ul>
          <li>
Websites and developer Web portals</li>
          <li>
Weblogs/RSS feeds. (Not all have to be hand-authored blogs--if you find an RSS feed
for news on java.net projects, for example, that would count as well.)</li>
          <li>
Java packages and/or libaries. (Either those within Java Standard Edition--a la Reflection
or the Scripting API--or from Enterprise Edition--a la JMS--or even third-party packages,
a la Spring.)</li>
          <li>
Conferences, even including those that I don't speak at. ;-)</li>
          <li>
Books.</li>
          <li>
Tools. (IDEs, build tools, static analysis tools, either commercial or open source.)</li>
          <li>
Future trends you think bear watching.</li>
        </ul>
        <p>
There is, of course, no prize to be won here, and I'd please ask the vendors (commercial
or open source) who watch my blog to avoid outright advertisements in comments (though
you are free to rattle off the various advantages of your product in an email to me),
in order to avoid turning this weblog into a gigantic row of billboards along the
freeway. I <em>am</em> interested in peoples' opinions, however, and more importantly,
why you think X should be on that list, or even why Y shouldn't. Keep it civil, though,
please--I'll delete any comments that get too vindictive or offensive. (That doesn't
mean that you have to agree with me--just avoid calling anybody names. Basic 'Netiquette.)
</p>
        <p>
Oh, and if you want to be mentioned in the article (which will be published on an
international developer site), please indicate how you'd like to be accredited. Or
not. Whatever you prefer.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=c917a24e-d656-4d7f-be58-1eb2ae816f82" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Best Java Resources: A Call</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,c917a24e-d656-4d7f-be58-1eb2ae816f82.aspx</guid>
      <link>http://blogs.tedneward.com/2008/06/02/Best+Java+Resources+A+Call.aspx</link>
      <pubDate>Mon, 02 Jun 2008 04:18:03 GMT</pubDate>
      <description>&lt;p&gt;
I've been asked to put together a list of the "best" Java resources that every up-and-coming
Java developer should have, and I'd like this list to be as comprehensive as possible
and, more importantly, reflect more than just my own opinion. So, either through comments
or &lt;a href="mailto:tedATtednewardDOTcom"&gt;through email&lt;/a&gt;, let me know what you think
the best Java resources are in the following categories:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Websites and developer Web portals&lt;/li&gt;
&lt;li&gt;
Weblogs/RSS feeds. (Not all have to be hand-authored blogs--if you find an RSS feed
for news on java.net projects, for example, that would count as well.)&lt;/li&gt;
&lt;li&gt;
Java packages and/or libaries. (Either those within Java Standard Edition--a la Reflection
or the Scripting API--or from Enterprise Edition--a la JMS--or even third-party packages,
a la Spring.)&lt;/li&gt;
&lt;li&gt;
Conferences, even including those that I don't speak at. ;-)&lt;/li&gt;
&lt;li&gt;
Books.&lt;/li&gt;
&lt;li&gt;
Tools. (IDEs, build tools, static analysis tools, either commercial or open source.)&lt;/li&gt;
&lt;li&gt;
Future trends you think bear watching.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There is, of course, no prize to be won here, and I'd please ask the vendors (commercial
or open source) who watch my blog to avoid outright advertisements in comments (though
you are free to rattle off the various advantages of your product in an email to me),
in order to avoid turning this weblog into a gigantic row of billboards along the
freeway. I &lt;em&gt;am&lt;/em&gt; interested in peoples' opinions, however, and more importantly,
why you think X should be on that list, or even why Y shouldn't. Keep it civil, though,
please--I'll delete any comments that get too vindictive or offensive. (That doesn't
mean that you have to agree with me--just avoid calling anybody names. Basic 'Netiquette.)
&lt;/p&gt;
&lt;p&gt;
Oh, and if you want to be mentioned in the article (which will be published on an
international developer site), please indicate how you'd like to be accredited. Or
not. Whatever you prefer.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=c917a24e-d656-4d7f-be58-1eb2ae816f82" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,c917a24e-d656-4d7f-be58-1eb2ae816f82.aspx</comments>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>Mac OS</category>
      <category>Reading</category>
      <category>Review</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=24603b37-5573-402d-bd85-2721f83ddb9d</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,24603b37-5573-402d-bd85-2721f83ddb9d.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,24603b37-5573-402d-bd85-2721f83ddb9d.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=24603b37-5573-402d-bd85-2721f83ddb9d</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Sometimes people ask me why I don't put more "personal" details in my blogs--those
who know me know that I'm generally pretty outspoken on a number of topics ranging
far beyond that of simple technology. While sometimes those opinions do manage to
leak their way here, for the most part, I try to avoid the taboo topics (politics/sex/religion,
among others) here in an effort to keep things technically focused. Or, at least,
as technically focused as I can, anyway.
</p>
        <p>
But there've been some other reasons I've avoided the public spotlight on my non-technical
details, too.
</p>
        <p>
          <a href="http://www.nytimes.com/2008/05/25/magazine/25internet-t.html">This essay</a> from
the New York Times (which may require registration, I'm not sure) captures, in some
ways, the things that anyone who blogs should consciously consider before blogging:
when you blog, you are putting yourself out into the public eye in a way that we as
a society have never had before. In prior generations, it was always possible to "hide"
from the world around us by simply not taking the paths that lead to public exposure--no
photos, no quotations in the newspaper, and so on. Now, thanks to Google, anybody
can find you with a few keystrokes.
</p>
        <p>
In some ways, it's funny--the Internet creates a layer of anonymity, and yet, takes
it away at the same time. (There <em>has</em> to be a sociology or psychology master's
thesis in there, waiting to be researched and written. Email me if you know of one?)
</p>
        <p>
Ah, right. The point. Must get back to the point.
</p>
        <p>
As you read peoples' blogs and consider commenting on what you've read, I implore
you, remember that on the other end of that blog is a real person, with feelings and
concerns and yes, in most cases, that same feeling of inadequacy that plagues us all.
What you say in your comments can and will, no matter how slight, either raise them
up, or else wound them. Sometimes, if you're particularly vitriolic about it, you
can even induce that "blogging burnout" Emily mentions in her essay.
</p>
        <p>
And, in case you were wondering: Yep, that goes for me, too. You, dear reader, can
make me feel like shit, if you put your mind to it strongly enough.
</p>
        <p>
That doesn't mean I don't want comments or am suddenly afraid of being rejected online--far
from it. I post here the thoughts and ideas that yes, I believe in, but also because
I want to see if others believe in them. In the event others don't, I want to hear
their criticism and hear their logic as they find the holes in the argument. Sometimes
I even agree with the contrary opinion, or find merit in going back to revisit my
thinking on the subject--case in point, right now I'm going back to look at Erlang
more deeply to see if <a href="http://steve.vinoski.net/blog/2008/05/09/thinking-in-language-but-not-clearly/">Steve
is right</a>. (Thus far, cruising through some Erlang code, looking at Erlang's behavior
in a debugger, and walking my way through various parts of the BEAM engine, I still
think Erlang's fabled support for robustness and correctness--none of which I disagreed
with, by the way--comes mostly from the language, not the execution engine, for whatever
that's worth. And apparently <a href="http://erlangdotnet.net/">I'm not the only one</a>.
But that's neither here nor there--Steve thinks he's right, and I doubt any words
of mine would change his opinion on that, judging from the tone of his posts on the
matter. *shrug* Fortunately, I'm far more concerned with correcting my own understanding
in the event of incorrectness than I am anybody else's. :-) )
</p>
        <p>
In any event, to those of you who are curious as to the more personal details, I'm
sorry, but they're not going to show up here any time soon. If you're that curious,
find me at a conference, introduce yourself, buy me a glass of red wine (Zinfandel's
always good) or Scotch, double neat (Macallan 18, or maybe a 25 if you're asking <em>really</em> personal
stuff), and let's settle into some comfy chairs and talk. 
</p>
        <p>
That's <em>always</em> a far more enjoyable experience than typing at the keyboard.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=24603b37-5573-402d-bd85-2721f83ddb9d" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>On Blogging, Technical, Personal and Intimate</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,24603b37-5573-402d-bd85-2721f83ddb9d.aspx</guid>
      <link>http://blogs.tedneward.com/2008/05/25/On+Blogging+Technical+Personal+And+Intimate.aspx</link>
      <pubDate>Sun, 25 May 2008 09:40:18 GMT</pubDate>
      <description>&lt;p&gt;
Sometimes people ask me why I don't put more "personal" details in my blogs--those
who know me know that I'm generally pretty outspoken on a number of topics ranging
far beyond that of simple technology. While sometimes those opinions do manage to
leak their way here, for the most part, I try to avoid the taboo topics (politics/sex/religion,
among others) here in an effort to keep things technically focused. Or, at least,
as technically focused as I can, anyway.
&lt;/p&gt;
&lt;p&gt;
But there've been some other reasons I've avoided the public spotlight on my non-technical
details, too.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nytimes.com/2008/05/25/magazine/25internet-t.html"&gt;This essay&lt;/a&gt; from
the New York Times (which may require registration, I'm not sure) captures, in some
ways, the things that anyone who blogs should consciously consider before blogging:
when you blog, you are putting yourself out into the public eye in a way that we as
a society have never had before. In prior generations, it was always possible to "hide"
from the world around us by simply not taking the paths that lead to public exposure--no
photos, no quotations in the newspaper, and so on. Now, thanks to Google, anybody
can find you with a few keystrokes.
&lt;/p&gt;
&lt;p&gt;
In some ways, it's funny--the Internet creates a layer of anonymity, and yet, takes
it away at the same time. (There &lt;em&gt;has&lt;/em&gt; to be a sociology or psychology master's
thesis in there, waiting to be researched and written. Email me if you know of one?)
&lt;/p&gt;
&lt;p&gt;
Ah, right. The point. Must get back to the point.
&lt;/p&gt;
&lt;p&gt;
As you read peoples' blogs and consider commenting on what you've read, I implore
you, remember that on the other end of that blog is a real person, with feelings and
concerns and yes, in most cases, that same feeling of inadequacy that plagues us all.
What you say in your comments can and will, no matter how slight, either raise them
up, or else wound them. Sometimes, if you're particularly vitriolic about it, you
can even induce that "blogging burnout" Emily mentions in her essay.
&lt;/p&gt;
&lt;p&gt;
And, in case you were wondering: Yep, that goes for me, too. You, dear reader, can
make me feel like shit, if you put your mind to it strongly enough.
&lt;/p&gt;
&lt;p&gt;
That doesn't mean I don't want comments or am suddenly afraid of being rejected online--far
from it. I post here the thoughts and ideas that yes, I believe in, but also because
I want to see if others believe in them. In the event others don't, I want to hear
their criticism and hear their logic as they find the holes in the argument. Sometimes
I even agree with the contrary opinion, or find merit in going back to revisit my
thinking on the subject--case in point, right now I'm going back to look at Erlang
more deeply to see if &lt;a href="http://steve.vinoski.net/blog/2008/05/09/thinking-in-language-but-not-clearly/"&gt;Steve
is right&lt;/a&gt;. (Thus far, cruising through some Erlang code, looking at Erlang's behavior
in a debugger, and walking my way through various parts of the BEAM engine, I still
think Erlang's fabled support for robustness and correctness--none of which I disagreed
with, by the way--comes mostly from the language, not the execution engine, for whatever
that's worth. And apparently &lt;a href="http://erlangdotnet.net/"&gt;I'm not the only one&lt;/a&gt;.
But that's neither here nor there--Steve thinks he's right, and I doubt any words
of mine would change his opinion on that, judging from the tone of his posts on the
matter. *shrug* Fortunately, I'm far more concerned with correcting my own understanding
in the event of incorrectness than I am anybody else's. :-) )
&lt;/p&gt;
&lt;p&gt;
In any event, to those of you who are curious as to the more personal details, I'm
sorry, but they're not going to show up here any time soon. If you're that curious,
find me at a conference, introduce yourself, buy me a glass of red wine (Zinfandel's
always good) or Scotch, double neat (Macallan 18, or maybe a 25 if you're asking &lt;em&gt;really&lt;/em&gt; personal
stuff), and let's settle into some comfy chairs and talk. 
&lt;/p&gt;
&lt;p&gt;
That's &lt;em&gt;always&lt;/em&gt; a far more enjoyable experience than typing at the keyboard.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=24603b37-5573-402d-bd85-2721f83ddb9d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,24603b37-5573-402d-bd85-2721f83ddb9d.aspx</comments>
      <category>Conferences</category>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=94fda66c-4dda-438c-af27-a53a8e0692c8</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,94fda66c-4dda-438c-af27-a53a8e0692c8.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,94fda66c-4dda-438c-af27-a53a8e0692c8.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=94fda66c-4dda-438c-af27-a53a8e0692c8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently, a former student asked me,
</p>
        <blockquote>
          <p>
I was in a .NET web services training class that you gave probably 4 or so years ago
on-site at a <em>[company name]</em> office in <em>[city]</em>, north of Atlanta. 
At that time I asked you for a list of the technical blogs that you read, and I am
curious which blogs you are reading now.  I am now with a small company where
I have to be a jack of all trades, in the last year I have worked in C++ and Perl
backend type projects and web frontend projects with Java, C#, and RoR, so I find
your perspective interesting since you also work with various technologies and aren't
a zealot for a specific one.
</p>
          <p>
Any way, please either respond by email or in your blog, because I think that others
may be interested in the list also.
</p>
        </blockquote>
        <p>
As one might expect, my blog list is a bit eclectic, but I suppose that's part of
the charm of somebody looking to study Java, .NET, C++, Smalltalk, Ruby, Parrot, LLVM,
and other languages and environments. So, without further ado, I've pasted in the
contents of my OPML file for cut&amp;paste and easy import.
</p>
        <p>
Having said that, though, I would strongly suggest <em>not</em> just blindly importing
the whole set of feeds into your nearest RSS reader, but take a moment and go visit
each one before you add it. It takes longer, granted, but the time spent is a worthy
investment--you don't want to have to declare "blog bankruptcy".
</p>
        <blockquote>
          <p>
            <em>Editor's note: We pause here as readers look at each other and go... "WTF?!?"</em>
          </p>
        </blockquote>
        <p>
"Blog bankruptcy" is a condition similar to "email bankruptcy", when otherwise perfectly
high-functioning people give up on trying to catch up to the flood of messages in
their email client's Inbox and delete the whole mess (usually with some kind of public
apology explaining why and asking those who've emailed them in the past to resend
something if it was really important), effectively trying to "start over" with their
email in much the same way that Chapter Seven or Chapter Eleven allows companies to
"start over" with their creditors, or declaring bankruptcy allows private citizens
to do the same with theirs. "Blog bankruptcy" is a similar kind of condition: your
RSS reader becomes so full of stuff that you can't keep up, and you can't even remember
which blogs were the interesting ones, so you nuke the whole thing and get away from
the blog-reading thing for a while.
</p>
        <p>
This happened to me, in fact: a few years ago, when I became the editor-in-chief of
TheServerSide.NET, I asked a few folks for their OPML lists, so that I could quickly
and easily build a list of blogs that would "tune me in" to the software industry
around me, and many of them quite agreeably complied. I took my RSS reader (Newsgator,
at the time) and dutifully imported all of them, and ended up with a collection of
blogs that was easily into the hundreds of feeds long. And, over time, I found myself
reading fewer and fewer blogs, mostly because the whole set was so... <em>intimidating</em>.
I mean, I would pick at the list of blogs and their entries in the same way that I
picked at vegetables on my plate as a child--half-heartedly, with no real enthusiasm,
as if this was something my parents were forcing me to do. That just ruined the experience
of blog-reading for me, and eventually (after I left TSS.NET for other pastures),
I nuked the whole thing--even going so far as to uninstall my copy of Newsgator--and
gave up.
</p>
        <p>
Naturally, I missed it, and slowly over time began to rebuild the list, this time,
taking each feed one at a time, carefully weighing what value the feed was to me and
selecting only those that I thought had a high signal-to-noise ratio. (This is partly
why I don't include much "personal" info in this blog--I found myself routinely stripping
away those blogs that had more personal content and less technical content, and I
figured if I didn't want to read it, others probably felt the same way.) Over the
last year or two, I've rebuilt the list to the point where I probably need to prune
a bit and close a few of them back down, but for now, I'm happy with the list I've
got.
</p>
        <p>
And speaking of which....
</p>
        <div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: 'Courier New', courier, monospace; background-color: #f4f4f4">
          <div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum1" style="color: #606060"> 1:</span>
              <span style="color: #0000ff">&lt;?</span>
              <span style="color: #800000">xml</span>
              <span style="color: #ff0000">version</span>
              <span style="color: #0000ff">="1.0"</span>?<span style="color: #0000ff">&gt;</span></pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum2" style="color: #606060"> 2:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">opml</span>
              <span style="color: #ff0000">version</span>
              <span style="color: #0000ff">="1.0"</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum3" style="color: #606060"> 3:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">head</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum4" style="color: #606060"> 4:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">title</span>
              <span style="color: #0000ff">&gt;</span>OPML
exported from Outlook<span style="color: #0000ff">&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;</span></pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum5" style="color: #606060"> 5:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">dateCreated</span>
              <span style="color: #0000ff">&gt;</span>Thu,
15 May 2008 20:55:19 -0700<span style="color: #0000ff">&lt;/</span><span style="color: #800000">dateCreated</span><span style="color: #0000ff">&gt;</span></pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum6" style="color: #606060"> 6:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">dateModified</span>
              <span style="color: #0000ff">&gt;</span>Thu,
15 May 2008 20:55:19 -0700<span style="color: #0000ff">&lt;/</span><span style="color: #800000">dateModified</span><span style="color: #0000ff">&gt;</span></pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum7" style="color: #606060"> 7:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">head</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum8" style="color: #606060"> 8:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">body</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum9" style="color: #606060"> 9:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="If
broken it is, fix it you should"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum10" style="color: #606060"> 10:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/tess/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum11" style="color: #606060"> 11:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Artima
Developer Buzz"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum12" style="color: #606060"> 12:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://www.artima.com/news/feeds/news.rss"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum13" style="color: #606060"> 13:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Artima
Weblogs"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum14" style="color: #606060"> 14:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://www.artima.com/weblogs/feeds/weblogs.rss"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum15" style="color: #606060"> 15:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Artima
Chapters Library"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum16" style="color: #606060"> 16:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://www.artima.com/chapters/feeds/chapters.rss"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum17" style="color: #606060"> 17:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Neal
Gafter's blog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum18" style="color: #606060"> 18:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://gafter.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum19" style="color: #606060"> 19:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Room
101"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum20" style="color: #606060"> 20:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://gbracha.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum21" style="color: #606060"> 21:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Kelly
O'Hair's Blog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum22" style="color: #606060"> 22:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://weblogs.java.net/blog/kellyohair/index.rdf"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum23" style="color: #606060"> 23:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="John
Rose @ Sun"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum24" style="color: #606060"> 24:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.sun.com/jrose/feed/entries/atom"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum25" style="color: #606060"> 25:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="The
Daily WTF"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum26" style="color: #606060"> 26:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://syndication.thedailywtf.com/TheDailyWtf"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum27" style="color: #606060"> 27:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Brad
Wilson"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum28" style="color: #606060"> 28:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://feeds.feedburner.com/BradWilson"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum29" style="color: #606060"> 29:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Mike
Stall's .NET Debugging Blog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum30" style="color: #606060"> 30:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/jmstall/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum31" style="color: #606060"> 31:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Stevey's
Blog Rants"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum32" style="color: #606060"> 32:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://steve-yegge.blogspot.com/atom.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum33" style="color: #606060"> 33:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Brendan's
Roadmap Updates"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum34" style="color: #606060"> 34:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://weblogs.mozillazine.org/roadmap/index.rdf"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum35" style="color: #606060"> 35:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="pl
patterns"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum36" style="color: #606060"> 36:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://plpatterns.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum37" style="color: #606060"> 37:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Joel
Pobar's weblog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum38" style="color: #606060"> 38:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://feeds.feedburner.com/callvirt"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum39" style="color: #606060"> 39:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Let&amp;amp;#39;s
Kill Dave!"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum40" style="color: #606060"> 40:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://letskilldave.com/rss.aspx"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum41" style="color: #606060"> 41:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Why
does everything suck?"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum42" style="color: #606060"> 42:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://whydoeseverythingsuck.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum43" style="color: #606060"> 43:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="cdiggins.com"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://cdiggins.com/feed"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum44" style="color: #606060"> 44:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="LukeH's
WebLog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum45" style="color: #606060"> 45:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/lukeh/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum46" style="color: #606060"> 46:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Jomo
Fisher -- Sharp Things"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum47" style="color: #606060"> 47:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/jomo_fisher/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum48" style="color: #606060"> 48:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Chance
Coble"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum49" style="color: #606060"> 49:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://leibnizdream.wordpress.com/feed/"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum50" style="color: #606060"> 50:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Don
Syme's WebLog on F# and Other Research Projects"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum51" style="color: #606060"> 51:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/dsyme/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum52" style="color: #606060"> 52:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="David
Broman's CLR Profiling API Blog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum53" style="color: #606060"> 53:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/davbr/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum54" style="color: #606060"> 54:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="JScript
Blog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum55" style="color: #606060"> 55:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/jscript/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum56" style="color: #606060"> 56:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Yet
Another Language Geek"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum57" style="color: #606060"> 57:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://blogs.msdn.com/wesdyer/rss.xml"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum58" style="color: #606060"> 58:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">=".NET
Languages Weblog"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum59" style="color: #606060"> 59:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://www.dotnetlanguages.net/DNL/Rss.aspx"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum60" style="color: #606060"> 60:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="DevHawk"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum61" style="color: #606060"> 61:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://feeds.feedburner.com/Devhawk"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum62" style="color: #606060"> 62:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="The
Cobra Programming Language"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum63" style="color: #606060"> 63:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://cobralang.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum64" style="color: #606060"> 64:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Code
Miscellany"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum65" style="color: #606060"> 65:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://codemiscellany.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum66" style="color: #606060"> 66:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Fred,
Let it go!"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum67" style="color: #606060"> 67:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://freddy33.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum68" style="color: #606060"> 68:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Codedependent"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum69" style="color: #606060"> 69:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://graphics-geek.blogspot.com/feeds/posts/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum70" style="color: #606060"> 70:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Presentation
Zen"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum71" style="color: #606060"> 71:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://www.presentationzen.com/presentationzen/index.rdf"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum72" style="color: #606060"> 72:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="The
Extreme Presentation(tm) Method"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum73" style="color: #606060"> 73:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://extremepresentation.typepad.com/blog/index.rdf"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum74" style="color: #606060"> 74:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="ZapThink"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum75" style="color: #606060"> 75:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://feeds.feedburner.com/zapthink"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum76" style="color: #606060"> 76:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Chris
Smith's completely unique view"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum77" style="color: #606060"> 77:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://feeds.feedburner.com/ChrisSmithsCompletelyUniqueView"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum78" style="color: #606060"> 78:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Code
Commit"</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum79" style="color: #606060"> 79:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://feeds.codecommit.com/codecommit"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum80" style="color: #606060"> 80:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">outline</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum81" style="color: #606060"> 81:</span>
              <span style="color: #ff0000">text</span>
              <span style="color: #0000ff">="Comments
on Ola Bini: Programming Language Synchronicity: A New Hope: Polyglotism"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum82" style="color: #606060"> 82:</span>
              <span style="color: #ff0000">type</span>
              <span style="color: #0000ff">="rss"</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum83" style="color: #606060"> 83:</span>
              <span style="color: #ff0000">xmlUrl</span>
              <span style="color: #0000ff">="http://ola-bini.blogspot.com/feeds/5778383724683099288/comments/default"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum84" style="color: #606060"> 84:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">body</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span id="lnum85" style="color: #606060"> 85:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">opml</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Happy reading.....
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=94fda66c-4dda-438c-af27-a53a8e0692c8" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Blogs I'm currently reading</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,94fda66c-4dda-438c-af27-a53a8e0692c8.aspx</guid>
      <link>http://blogs.tedneward.com/2008/05/16/Blogs+Im+Currently+Reading.aspx</link>
      <pubDate>Fri, 16 May 2008 07:08:07 GMT</pubDate>
      <description>&lt;p&gt;
Recently, a former student asked me,
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
I was in a .NET web services training class that you gave probably 4 or so years ago
on-site at a &lt;em&gt;[company name]&lt;/em&gt; office in &lt;em&gt;[city]&lt;/em&gt;, north of Atlanta.&amp;nbsp;
At that time I asked you for a list of the technical blogs that you read, and I am
curious which blogs you are reading now.&amp;nbsp; I am now with a small company where
I have to be a jack of all trades, in the last year I have worked in C++ and Perl
backend type projects and web frontend projects with Java, C#, and RoR, so I find
your perspective interesting since you also work with various technologies and aren't
a zealot for a specific one.
&lt;/p&gt;
&lt;p&gt;
Any way, please either respond by email or in your blog, because I think that others
may be interested in the list also.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
As one might expect, my blog list is a bit eclectic, but I suppose that's part of
the charm of somebody looking to study Java, .NET, C++, Smalltalk, Ruby, Parrot, LLVM,
and other languages and environments. So, without further ado, I've pasted in the
contents of my OPML file for cut&amp;amp;paste and easy import.
&lt;/p&gt;
&lt;p&gt;
Having said that, though, I would strongly suggest &lt;em&gt;not&lt;/em&gt; just blindly importing
the whole set of feeds into your nearest RSS reader, but take a moment and go visit
each one before you add it. It takes longer, granted, but the time spent is a worthy
investment--you don't want to have to declare "blog bankruptcy".
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;Editor's note: We pause here as readers look at each other and go... "WTF?!?"&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
"Blog bankruptcy" is a condition similar to "email bankruptcy", when otherwise perfectly
high-functioning people give up on trying to catch up to the flood of messages in
their email client's Inbox and delete the whole mess (usually with some kind of public
apology explaining why and asking those who've emailed them in the past to resend
something if it was really important), effectively trying to "start over" with their
email in much the same way that Chapter Seven or Chapter Eleven allows companies to
"start over" with their creditors, or declaring bankruptcy allows private citizens
to do the same with theirs. "Blog bankruptcy" is a similar kind of condition: your
RSS reader becomes so full of stuff that you can't keep up, and you can't even remember
which blogs were the interesting ones, so you nuke the whole thing and get away from
the blog-reading thing for a while.
&lt;/p&gt;
&lt;p&gt;
This happened to me, in fact: a few years ago, when I became the editor-in-chief of
TheServerSide.NET, I asked a few folks for their OPML lists, so that I could quickly
and easily build a list of blogs that would "tune me in" to the software industry
around me, and many of them quite agreeably complied. I took my RSS reader (Newsgator,
at the time) and dutifully imported all of them, and ended up with a collection of
blogs that was easily into the hundreds of feeds long. And, over time, I found myself
reading fewer and fewer blogs, mostly because the whole set was so... &lt;em&gt;intimidating&lt;/em&gt;.
I mean, I would pick at the list of blogs and their entries in the same way that I
picked at vegetables on my plate as a child--half-heartedly, with no real enthusiasm,
as if this was something my parents were forcing me to do. That just ruined the experience
of blog-reading for me, and eventually (after I left TSS.NET for other pastures),
I nuked the whole thing--even going so far as to uninstall my copy of Newsgator--and
gave up.
&lt;/p&gt;
&lt;p&gt;
Naturally, I missed it, and slowly over time began to rebuild the list, this time,
taking each feed one at a time, carefully weighing what value the feed was to me and
selecting only those that I thought had a high signal-to-noise ratio. (This is partly
why I don't include much "personal" info in this blog--I found myself routinely stripping
away those blogs that had more personal content and less technical content, and I
figured if I didn't want to read it, others probably felt the same way.) Over the
last year or two, I've rebuilt the list to the point where I probably need to prune
a bit and close a few of them back down, but for now, I'm happy with the list I've
got.
&lt;/p&gt;
&lt;p&gt;
And speaking of which....
&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="border-right: silver 1px solid; padding-right: 4px; border-top: silver 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: silver 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: silver 1px solid; font-family: 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div id="codeSnippet" style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum1" style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #800000"&gt;xml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.0"&lt;/span&gt;?&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum2" style="color: #606060"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;opml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum3" style="color: #606060"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum4" style="color: #606060"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;OPML
exported from Outlook&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;title&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum5" style="color: #606060"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;dateCreated&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Thu,
15 May 2008 20:55:19 -0700&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;dateCreated&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum6" style="color: #606060"&gt; 6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;dateModified&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Thu,
15 May 2008 20:55:19 -0700&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;dateModified&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum7" style="color: #606060"&gt; 7:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;head&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum8" style="color: #606060"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum9" style="color: #606060"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="If
broken it is, fix it you should"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum10" style="color: #606060"&gt; 10:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/tess/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum11" style="color: #606060"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Artima
Developer Buzz"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum12" style="color: #606060"&gt; 12:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://www.artima.com/news/feeds/news.rss"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum13" style="color: #606060"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Artima
Weblogs"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum14" style="color: #606060"&gt; 14:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://www.artima.com/weblogs/feeds/weblogs.rss"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum15" style="color: #606060"&gt; 15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Artima
Chapters Library"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum16" style="color: #606060"&gt; 16:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://www.artima.com/chapters/feeds/chapters.rss"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum17" style="color: #606060"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Neal
Gafter's blog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum18" style="color: #606060"&gt; 18:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://gafter.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum19" style="color: #606060"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Room
101"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum20" style="color: #606060"&gt; 20:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://gbracha.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum21" style="color: #606060"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Kelly
O'Hair's Blog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum22" style="color: #606060"&gt; 22:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://weblogs.java.net/blog/kellyohair/index.rdf"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum23" style="color: #606060"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="John
Rose @ Sun"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum24" style="color: #606060"&gt; 24:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.sun.com/jrose/feed/entries/atom"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum25" style="color: #606060"&gt; 25:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="The
Daily WTF"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum26" style="color: #606060"&gt; 26:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://syndication.thedailywtf.com/TheDailyWtf"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum27" style="color: #606060"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Brad
Wilson"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum28" style="color: #606060"&gt; 28:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://feeds.feedburner.com/BradWilson"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum29" style="color: #606060"&gt; 29:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Mike
Stall's .NET Debugging Blog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum30" style="color: #606060"&gt; 30:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/jmstall/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum31" style="color: #606060"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Stevey's
Blog Rants"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum32" style="color: #606060"&gt; 32:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://steve-yegge.blogspot.com/atom.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum33" style="color: #606060"&gt; 33:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Brendan's
Roadmap Updates"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum34" style="color: #606060"&gt; 34:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://weblogs.mozillazine.org/roadmap/index.rdf"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum35" style="color: #606060"&gt; 35:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="pl
patterns"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum36" style="color: #606060"&gt; 36:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://plpatterns.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum37" style="color: #606060"&gt; 37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Joel
Pobar's weblog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum38" style="color: #606060"&gt; 38:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://feeds.feedburner.com/callvirt"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum39" style="color: #606060"&gt; 39:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Let&amp;amp;amp;#39;s
Kill Dave!"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum40" style="color: #606060"&gt; 40:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://letskilldave.com/rss.aspx"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum41" style="color: #606060"&gt; 41:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Why
does everything suck?"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum42" style="color: #606060"&gt; 42:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://whydoeseverythingsuck.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum43" style="color: #606060"&gt; 43:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="cdiggins.com"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://cdiggins.com/feed"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum44" style="color: #606060"&gt; 44:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="LukeH's
WebLog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum45" style="color: #606060"&gt; 45:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/lukeh/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum46" style="color: #606060"&gt; 46:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Jomo
Fisher -- Sharp Things"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum47" style="color: #606060"&gt; 47:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/jomo_fisher/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum48" style="color: #606060"&gt; 48:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Chance
Coble"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum49" style="color: #606060"&gt; 49:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://leibnizdream.wordpress.com/feed/"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum50" style="color: #606060"&gt; 50:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Don
Syme's WebLog on F# and Other Research Projects"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum51" style="color: #606060"&gt; 51:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/dsyme/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum52" style="color: #606060"&gt; 52:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="David
Broman's CLR Profiling API Blog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum53" style="color: #606060"&gt; 53:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/davbr/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum54" style="color: #606060"&gt; 54:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="JScript
Blog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum55" style="color: #606060"&gt; 55:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/jscript/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum56" style="color: #606060"&gt; 56:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Yet
Another Language Geek"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum57" style="color: #606060"&gt; 57:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://blogs.msdn.com/wesdyer/rss.xml"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum58" style="color: #606060"&gt; 58:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=".NET
Languages Weblog"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum59" style="color: #606060"&gt; 59:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://www.dotnetlanguages.net/DNL/Rss.aspx"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum60" style="color: #606060"&gt; 60:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="DevHawk"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum61" style="color: #606060"&gt; 61:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://feeds.feedburner.com/Devhawk"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum62" style="color: #606060"&gt; 62:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="The
Cobra Programming Language"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum63" style="color: #606060"&gt; 63:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://cobralang.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum64" style="color: #606060"&gt; 64:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Code
Miscellany"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum65" style="color: #606060"&gt; 65:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://codemiscellany.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum66" style="color: #606060"&gt; 66:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Fred,
Let it go!"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum67" style="color: #606060"&gt; 67:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://freddy33.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum68" style="color: #606060"&gt; 68:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Codedependent"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum69" style="color: #606060"&gt; 69:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://graphics-geek.blogspot.com/feeds/posts/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum70" style="color: #606060"&gt; 70:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Presentation
Zen"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum71" style="color: #606060"&gt; 71:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://www.presentationzen.com/presentationzen/index.rdf"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum72" style="color: #606060"&gt; 72:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="The
Extreme Presentation(tm) Method"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum73" style="color: #606060"&gt; 73:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://extremepresentation.typepad.com/blog/index.rdf"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum74" style="color: #606060"&gt; 74:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ZapThink"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum75" style="color: #606060"&gt; 75:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://feeds.feedburner.com/zapthink"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum76" style="color: #606060"&gt; 76:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Chris
Smith's completely unique view"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum77" style="color: #606060"&gt; 77:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://feeds.feedburner.com/ChrisSmithsCompletelyUniqueView"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum78" style="color: #606060"&gt; 78:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Code
Commit"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum79" style="color: #606060"&gt; 79:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://feeds.codecommit.com/codecommit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum80" style="color: #606060"&gt; 80:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;outline&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum81" style="color: #606060"&gt; 81:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Comments
on Ola Bini: Programming Language Synchronicity: A New Hope: Polyglotism"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum82" style="color: #606060"&gt; 82:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="rss"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum83" style="color: #606060"&gt; 83:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlUrl&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://ola-bini.blogspot.com/feeds/5778383724683099288/comments/default"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum84" style="color: #606060"&gt; 84:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;body&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span id="lnum85" style="color: #606060"&gt; 85:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;opml&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Happy reading.....
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=94fda66c-4dda-438c-af27-a53a8e0692c8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,94fda66c-4dda-438c-af27-a53a8e0692c8.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>F#</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Security</category>
      <category>Solaris</category>
      <category>Visual Basic</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=c69ffbd1-5107-4a2a-aa34-6419dd855035</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,c69ffbd1-5107-4a2a-aa34-6419dd855035.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,c69ffbd1-5107-4a2a-aa34-6419dd855035.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c69ffbd1-5107-4a2a-aa34-6419dd855035</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Apparently, I'm drawing enough of an audience through this blog that various folks
have started to send me press releases and notifications and requests for... well,
I dunno exactly, but I'm assuming some blogging love of some kind. I'm always a little
leery about that particular subject, because it always has this dangerous potential
to turn the blog into a less-credible marketing device, but people at conferences
have suggested that they really are interested in what I think about various products
and tools, so perhaps it's time to amend my stance on this.
</p>
        <p>
With that in mind, if you are a vendor and have a product that you'd like me to take
a look at and (possibly) offer up a review here, here's the basic rules:
</p>
        <ol>
          <li>
No guarantees. Sending me something will in no way guarantee that I will review your
product, for several reasons, two of which being (a) I get really busy sometimes,
and (b) I may have no interest whatsoever in your product and I refuse to pretend
to do so. (Readers can usually tell when the reviewer isn't all that excited about
the subject, I've found.)</li>
          <li>
If you're not going to send me a "real" version (meaning not the time-locked or feature-crippled
demo), don't bother. I have no idea when I will get around to a review, and I have
no desire to review something that isn't "the real deal". I will in turn promise that
the licensed version you send me (if necessary) will not be used for any purpose other
than my own research and exploration (signing contract if necessary to give you that
"fresh-from-the-lawyer's-office" warm and fuzzy feeling).</li>
          <li>
I say what I think, pro and con. I will not edit my review to suit your marketing
purpose, and if you ask me to do so I will simply note in the review that you have
asked me to do so. I retain full editorial control over what I say about your product.</li>
          <li>
Having established #1, I will try to be as fair as I can about your product, and point
out things that I liked and things that I didn't. (Of course, if I hated it from top
to bottom, I may end up with the only positive thing being "It didn't set the atmosphere
on fire when I started the app", but hey, that's something positive, right?)</li>
          <li>
Also in the spirit of #1, if you send me mail answering questions or complaints in
my review, I will of course amend the review with your comments. You are always welcome
to post comments to the blog entry itself, too. Unless you insult my grandmother,
then I will have to get all DELETE-key on you.</li>
        </ol>
        <p>
The reason I'm posting this here is twofold: one, so my faithful audience of four
blog readers will know the rules under which I'm looking at these products and (hopefully)
realize that I'm not financially vested in any of these products, and two, so the
various vendor folks can read this and know what the rules are up front before even
asking.
</p>
        <p>
I know it sounds a little cheeky to lay this out. The image I get in my head is that
of the kid at Christmas declaring to his grandparents as they walk through the door,
presents in hand, "Make sure it's not a scratchy sweater, I hate scratchy sweaters.
And G.I. Joe was only popular when my Dad was a kid. And if you give me another lunchbox
I will scream until you buy me something cool, like a new GameBoy." Ugh. But I value
the trust that people seem to have in me, and so I risk the perception of cheekiness
for this tiny window in time in order to (hopefully) establish full disclosure over
the reviews that come to pass (which, by the way, will always have the category "review"
applied to them, so you know which is an official review and which is just me exploring,
like the LLVM and Parrot posts of recent time).
</p>
        <p>
We now return you to the regularly-scheduled blog.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=c69ffbd1-5107-4a2a-aa34-6419dd855035" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Rules for Review</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,c69ffbd1-5107-4a2a-aa34-6419dd855035.aspx</guid>
      <link>http://blogs.tedneward.com/2008/03/28/Rules+For+Review.aspx</link>
      <pubDate>Fri, 28 Mar 2008 11:18:12 GMT</pubDate>
      <description>&lt;p&gt;
Apparently, I'm drawing enough of an audience through this blog that various folks
have started to send me press releases and notifications and requests for... well,
I dunno exactly, but I'm assuming some blogging love of some kind. I'm always a little
leery about that particular subject, because it always has this dangerous potential
to turn the blog into a less-credible marketing device, but people at conferences
have suggested that they really are interested in what I think about various products
and tools, so perhaps it's time to amend my stance on this.
&lt;/p&gt;
&lt;p&gt;
With that in mind, if you are a vendor and have a product that you'd like me to take
a look at and (possibly) offer up a review here, here's the basic rules:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
No guarantees. Sending me something will in no way guarantee that I will review your
product, for several reasons, two of which being (a) I get really busy sometimes,
and (b) I may have no interest whatsoever in your product and I refuse to pretend
to do so. (Readers can usually tell when the reviewer isn't all that excited about
the subject, I've found.)&lt;/li&gt;
&lt;li&gt;
If you're not going to send me a "real" version (meaning not the time-locked or feature-crippled
demo), don't bother. I have no idea when I will get around to a review, and I have
no desire to review something that isn't "the real deal". I will in turn promise that
the licensed version you send me (if necessary) will not be used for any purpose other
than my own research and exploration (signing contract if necessary to give you that
"fresh-from-the-lawyer's-office" warm and fuzzy feeling).&lt;/li&gt;
&lt;li&gt;
I say what I think, pro and con. I will not edit my review to suit your marketing
purpose, and if you ask me to do so I will simply note in the review that you have
asked me to do so. I retain full editorial control over what I say about your product.&lt;/li&gt;
&lt;li&gt;
Having established #1, I will try to be as fair as I can about your product, and point
out things that I liked and things that I didn't. (Of course, if I hated it from top
to bottom, I may end up with the only positive thing being "It didn't set the atmosphere
on fire when I started the app", but hey, that's something positive, right?)&lt;/li&gt;
&lt;li&gt;
Also in the spirit of #1, if you send me mail answering questions or complaints in
my review, I will of course amend the review with your comments. You are always welcome
to post comments to the blog entry itself, too. Unless you insult my grandmother,
then I will have to get all DELETE-key on you.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The reason I'm posting this here is twofold: one, so my faithful audience of four
blog readers will know the rules under which I'm looking at these products and (hopefully)
realize that I'm not financially vested in any of these products, and two, so the
various vendor folks can read this and know what the rules are up front before even
asking.
&lt;/p&gt;
&lt;p&gt;
I know it sounds a little cheeky to lay this out. The image I get in my head is that
of the kid at Christmas declaring to his grandparents as they walk through the door,
presents in hand, "Make sure it's not a scratchy sweater, I hate scratchy sweaters.
And G.I. Joe was only popular when my Dad was a kid. And if you give me another lunchbox
I will scream until you buy me something cool, like a new GameBoy." Ugh. But I value
the trust that people seem to have in me, and so I risk the perception of cheekiness
for this tiny window in time in order to (hopefully) establish full disclosure over
the reviews that come to pass (which, by the way, will always have the category "review"
applied to them, so you know which is an official review and which is just me exploring,
like the LLVM and Parrot posts of recent time).
&lt;/p&gt;
&lt;p&gt;
We now return you to the regularly-scheduled blog.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=c69ffbd1-5107-4a2a-aa34-6419dd855035" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,c69ffbd1-5107-4a2a-aa34-6419dd855035.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Reading</category>
      <category>Review</category>
      <category>Ruby</category>
      <category>Security</category>
      <category>Solaris</category>
      <category>VMWare</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=a5152352-9d77-4bd5-8cc5-31c75443ea90</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,a5152352-9d77-4bd5-8cc5-31c75443ea90.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,a5152352-9d77-4bd5-8cc5-31c75443ea90.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=a5152352-9d77-4bd5-8cc5-31c75443ea90</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A couple of people have asked me over the last few weeks, so it's probably worth saying
out loud: 
</p>
        <p>
No, I don't work for a large company, so yes, I'm available for consulting and research
projects. If you've got one of those burning questions like, "How would our company/project/department/whatever
make use of JRuby-and-Rails, and what would the impact to the rest of the system be",
or "Could using F# help us write applications faster", or "How would we best integrate
Groovy into our application", or "How does the new Adobe Flex/AIR move help us build
richer client apps", or "How do we improve the performance of our Java/.NET app",
or other questions along those lines, drop me a line and let's talk. Not only will
I cook up a prototype describing the answer, but I'll meet with your management and
explain the consequences of the research, both pro and con, for them to evaluate.
</p>
        <p>
Shameless call for consulting complete, now back to the regularly-scheduled programming.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=a5152352-9d77-4bd5-8cc5-31c75443ea90" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Reminder</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,a5152352-9d77-4bd5-8cc5-31c75443ea90.aspx</guid>
      <link>http://blogs.tedneward.com/2008/03/22/Reminder.aspx</link>
      <pubDate>Sat, 22 Mar 2008 10:43:18 GMT</pubDate>
      <description>&lt;p&gt;
A couple of people have asked me over the last few weeks, so it's probably worth saying
out loud: 
&lt;/p&gt;
&lt;p&gt;
No, I don't work for a large company, so yes, I'm available for consulting and research
projects. If you've got one of those burning questions like, "How would our company/project/department/whatever
make use of JRuby-and-Rails, and what would the impact to the rest of the system be",
or "Could using F# help us write applications faster", or "How would we best integrate
Groovy into our application", or "How does the new Adobe Flex/AIR move help us build
richer client apps", or "How do we improve the performance of our Java/.NET app",
or other questions along those lines, drop me a line and let's talk. Not only will
I cook up a prototype describing the answer, but I'll meet with your management and
explain the consequences of the research, both pro and con, for them to evaluate.
&lt;/p&gt;
&lt;p&gt;
Shameless call for consulting complete, now back to the regularly-scheduled programming.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=a5152352-9d77-4bd5-8cc5-31c75443ea90" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,a5152352-9d77-4bd5-8cc5-31c75443ea90.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Flash</category>
      <category>Java/J2EE</category>
      <category>Languages</category>
      <category>LLVM</category>
      <category>Mac OS</category>
      <category>Parrot</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Security</category>
      <category>Solaris</category>
      <category>VMWare</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=07d87c26-f0e7-4129-901c-ce572d8e2d27</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,07d87c26-f0e7-4129-901c-ce572d8e2d27.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,07d87c26-f0e7-4129-901c-ce572d8e2d27.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=07d87c26-f0e7-4129-901c-ce572d8e2d27</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Some quotes I've found to be thought-provoking over the last week or so:
</p>
        <blockquote>
          <p>
"Some programming languages manage to absorb change, but withstand progress."
</p>
          <p>
"In a 5 year period we get one superb programming language. Only we can't control
when the 5 year period will begin."
</p>
          <p>
"Every program has (at least) two purposes: the one for which it was written and another
for which it wasn't."
</p>
          <p>
"If a listener nods his head when you're explaining your program, wake him up."
</p>
          <p>
"A language that doesn't affect the way you think about programming, is not worth
knowing."
</p>
          <p>
"Wherever there is modularity there is the potential for misunderstanding: Hiding
information implies a need to check communication."
</p>
          <p>
(All of the above, <a href="http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epigrams.html">Alan
Perlis</a>)
</p>
          <p>
 
</p>
          <p>
"Program testing can be used to show the presence of bugs, but never to show their
absence!"
</p>
          <p>
"The competent programmer is fully aware of the limited size of his own skull. He
therefore approaches his task with full humility, and avoids clever tricks like the
plague."
</p>
          <p>
"How do we convince people that in programming simplicity and clarity —in short: what
mathematicians call "elegance"— are not a dispensable luxury, but a crucial matter
that decides between success and failure?" 
</p>
          <p>
"Are you quite sure that all those bells and whistles, all those wonderful facilities
of your so called powerful programming languages, belong to the solution set rather
than the problem set?" 
</p>
          <p>
"Object-oriented programming is an exceptionally bad idea which could only have originated
in California." 
</p>
          <p>
"The prisoner falls in love with his chains." 
</p>
          <p>
"Write a paper promising salvation, make it a 'structured' something or a 'virtual'
something, or 'abstract', 'distributed' or 'higher-order' or 'applicative' and you
can almost be certain of having started a new cult." 
</p>
          <p>
"I remember from those days two design principles that have served me well ever since,
viz. 
</p>
          <ol>
            <li>
before really embarking on a sizable project, in particular before starting the large
investment of coding, try to kill the project first, and 
</li>
            <li>
start with the most difficult, most risky parts first."</li>
          </ol>
          <p>
(All of the above, <a href="http://en.wikiquote.org/wiki/Edsger_Dijkstra">Edsgar Dijkstra</a>)
</p>
        </blockquote>
        <p>
Make of them what you will....
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=07d87c26-f0e7-4129-901c-ce572d8e2d27" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Quotables</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,07d87c26-f0e7-4129-901c-ce572d8e2d27.aspx</guid>
      <link>http://blogs.tedneward.com/2008/02/24/Quotables.aspx</link>
      <pubDate>Sun, 24 Feb 2008 11:16:52 GMT</pubDate>
      <description>&lt;p&gt;
Some quotes I've found to be thought-provoking over the last week or so:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
"Some programming languages manage to absorb change, but withstand progress."
&lt;/p&gt;
&lt;p&gt;
"In a 5 year period we get one superb programming language. Only we can't control
when the 5 year period will begin."
&lt;/p&gt;
&lt;p&gt;
"Every program has (at least) two purposes: the one for which it was written and another
for which it wasn't."
&lt;/p&gt;
&lt;p&gt;
"If a listener nods his head when you're explaining your program, wake him up."
&lt;/p&gt;
&lt;p&gt;
"A language that doesn't affect the way you think about programming, is not worth
knowing."
&lt;/p&gt;
&lt;p&gt;
"Wherever there is modularity there is the potential for misunderstanding: Hiding
information implies a need to check communication."
&lt;/p&gt;
&lt;p&gt;
(All of the above, &lt;a href="http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epigrams.html"&gt;Alan
Perlis&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
"Program testing can be used to show the presence of bugs, but never to show their
absence!"
&lt;/p&gt;
&lt;p&gt;
"The competent programmer is fully aware of the limited size of his own skull. He
therefore approaches his task with full humility, and avoids clever tricks like the
plague."
&lt;/p&gt;
&lt;p&gt;
"How do we convince people that in programming simplicity and clarity —in short: what
mathematicians call "elegance"— are not a dispensable luxury, but a crucial matter
that decides between success and failure?" 
&lt;p&gt;
"Are you quite sure that all those bells and whistles, all those wonderful facilities
of your so called powerful programming languages, belong to the solution set rather
than the problem set?" 
&lt;p&gt;
"Object-oriented programming is an exceptionally bad idea which could only have originated
in California." 
&lt;p&gt;
"The prisoner falls in love with his chains." 
&lt;p&gt;
"Write a paper promising salvation, make it a 'structured' something or a 'virtual'
something, or 'abstract', 'distributed' or 'higher-order' or 'applicative' and you
can almost be certain of having started a new cult." 
&lt;p&gt;
"I remember from those days two design principles that have served me well ever since,
viz. 
&lt;ol&gt;
&lt;li&gt;
before really embarking on a sizable project, in particular before starting the large
investment of coding, try to kill the project first, and 
&lt;/li&gt;
&lt;li&gt;
start with the most difficult, most risky parts first."&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
(All of the above, &lt;a href="http://en.wikiquote.org/wiki/Edsger_Dijkstra"&gt;Edsgar Dijkstra&lt;/a&gt;)
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Make of them what you will....
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=07d87c26-f0e7-4129-901c-ce572d8e2d27" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,07d87c26-f0e7-4129-901c-ce572d8e2d27.aspx</comments>
      <category>Languages</category>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=8a1fb6e7-72b6-411f-86d2-209d13ee638f</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,8a1fb6e7-72b6-411f-86d2-209d13ee638f.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,8a1fb6e7-72b6-411f-86d2-209d13ee638f.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8a1fb6e7-72b6-411f-86d2-209d13ee638f</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is, without a doubt, the most accurate quote <em>ever</em> about the "fun" of
writing a book:
</p>
        <blockquote>
          <p>
Writing a book is an adventure. To begin with, it is a toy and an amusement; then
it becomes a mistress, and then it becomes a master, and then a tyrant. The last phase
is that just as you are about to be reconciled to your servitude, you kill the monster,
and fling him out to the public. (<a href="http://www.brainyquote.com/quotes/quotes/w/winstonchu136000.html">Source</a>:
Winston Churchill)
</p>
        </blockquote>
        <p>
Keep that in mind, all you who are considering authoring as a career or career supplement.
</p>
        <p>
Were I to offer my own, it would be like so:
</p>
        <blockquote>
          <p>
Writing a book is like having a child. 
</p>
          <p>
Trying is the best part, in some ways. You have this idea, this burning sensation
in your heart, that just <em>has</em> to get out into the world. But you need a partner,
a publisher who will help you bring your vision to life. You write proposals, you
write tables of contents, you imagine the book cover in your mind. Then, YES! You
get a publisher to agree. You sign the contract, fax it in, and you are on the way!
We are <em>authoring!</em></p>
          <p>
At first, it is wonderful and exciting and full of potential. You run into a few hangups,
a few periods of nausea as you realize the magnitude of what you're really doing.
You resolve to press on. As you continue, you begin to feel like you're in control
again, but you start to get this sense like it's an albatross, a weight around your
neck. Before long, you're dragging your feet, you can't seem to muster the energy
to do anything, just get this thing <em>done</em>. The deadline approaches, the sheer
horror of what's left to be done paralyzes you. You look your editor in the eye (literally
or figuratively) and say, "I can't do this." The editor says, "Push". You whimper,
"Don't make me do this, just cancel the contract." The editor says, "Push". You scream
at them, "This is YOUR fault, you MADE me do this!" The editor says, "Push". Then,
all of a sudden, it's done, it's out, it's on the shelf, and you take photos and show
it off to all the friends, neighbors and family, who look at you a little sympathetically,
and don't mention how awful you really look in that photo.
</p>
          <p>
As the book is out in the world, you feel a sense of pride an joy at it. You imagine
it profoundly changing the way people look at the world. You imagine it reaching bestseller
lists. You're already practicing the speech for the Nobel. You're sitting in your
study, you reach out and grab one of the free copies still sitting on your desk, and
you open to a random page. Uh, oh. There's a typo, or a mistake, or something that
clearly got past you and the technical reviewers and the copyeditors. Damn. Oh, well,
one mistake can't make that much difference.
</p>
          <p>
Then the reviews come in on Amazon. People like it. People post good reviews. One
of them is not positive. You get angry: this is your <em>baby</em> they are attacking.
How DARE they. You make plans to find large men with Italian names and track down
that reviewer. You suddenly realize your overprotectiveness. You laugh at yourself
weakly. You try to convince yourself that there's no pleasing some people.
</p>
          <p>
Then someone comes up to you at a conference or interview or other gathering, and
says, "Wow, you wrote that? I have that book on my shelf!" and suddenly it's all OK.
It may not be perfect, but it's yours, and you love it all the same, warts and all.
</p>
        </blockquote>
        <p>
Nearly a dozen books later, it's always the same.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=8a1fb6e7-72b6-411f-86d2-209d13ee638f" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Quotes on writing</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,8a1fb6e7-72b6-411f-86d2-209d13ee638f.aspx</guid>
      <link>http://blogs.tedneward.com/2007/12/08/Quotes+On+Writing.aspx</link>
      <pubDate>Sat, 08 Dec 2007 10:48:51 GMT</pubDate>
      <description>&lt;p&gt;
This is, without a doubt, the most accurate quote &lt;em&gt;ever&lt;/em&gt; about the "fun" of
writing a book:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Writing a book is an adventure. To begin with, it is a toy and an amusement; then
it becomes a mistress, and then it becomes a master, and then a tyrant. The last phase
is that just as you are about to be reconciled to your servitude, you kill the monster,
and fling him out to the public. (&lt;a href="http://www.brainyquote.com/quotes/quotes/w/winstonchu136000.html"&gt;Source&lt;/a&gt;:
Winston Churchill)
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Keep that in mind, all you who are considering authoring as a career or career supplement.
&lt;/p&gt;
&lt;p&gt;
Were I to offer my own, it would be like so:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Writing a book is like having a child. 
&lt;/p&gt;
&lt;p&gt;
Trying is the best part, in some ways. You have this idea, this burning sensation
in your heart, that just &lt;em&gt;has&lt;/em&gt; to get out into the world. But you need a partner,
a publisher who will help you bring your vision to life. You write proposals, you
write tables of contents, you imagine the book cover in your mind. Then, YES! You
get a publisher to agree. You sign the contract, fax it in, and you are on the way!
We are &lt;em&gt;authoring!&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
At first, it is wonderful and exciting and full of potential. You run into a few hangups,
a few periods of nausea&amp;nbsp;as you realize the magnitude of what you're really doing.
You resolve to press on. As you continue, you begin to feel like you're in control
again, but you start to get this sense like it's an albatross, a weight around your
neck. Before long, you're dragging your feet, you can't seem to muster the energy
to do anything, just get this thing &lt;em&gt;done&lt;/em&gt;. The deadline approaches, the sheer
horror of what's left to be done paralyzes you. You look your editor in the eye (literally
or figuratively) and say, "I can't do this." The editor says, "Push". You whimper,
"Don't make me do this, just cancel the contract." The editor says, "Push". You scream
at them, "This is YOUR fault, you MADE me do this!" The editor says, "Push". Then,
all of a sudden, it's done, it's out, it's on the shelf, and you take photos and show
it off to all the friends, neighbors and family, who look at you a little sympathetically,
and don't mention how awful you really look in that photo.
&lt;/p&gt;
&lt;p&gt;
As the book is out in the world, you feel a sense of pride an joy at it. You imagine
it profoundly changing the way people look at the world. You imagine it reaching bestseller
lists. You're already practicing the speech for the Nobel. You're sitting in your
study, you reach out and grab one of the free copies still sitting on your desk, and
you open to a random page. Uh, oh. There's a typo, or a mistake, or something that
clearly got past you and the technical reviewers and the copyeditors. Damn. Oh, well,
one mistake can't make that much difference.
&lt;/p&gt;
&lt;p&gt;
Then the reviews come in on Amazon. People like it. People post good reviews. One
of them is not positive. You get angry: this is your &lt;em&gt;baby&lt;/em&gt; they are attacking.
How DARE they. You make plans to find large men with Italian names and track down
that reviewer. You suddenly realize your overprotectiveness. You laugh at yourself
weakly. You try to convince yourself that there's no pleasing some people.
&lt;/p&gt;
&lt;p&gt;
Then someone comes up to you at a conference or interview or other gathering, and
says, "Wow, you wrote that? I have that book on my shelf!" and suddenly it's all OK.
It may not be perfect, but it's yours, and you love it all the same, warts and all.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Nearly a dozen books later, it's always the same.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=8a1fb6e7-72b6-411f-86d2-209d13ee638f" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,8a1fb6e7-72b6-411f-86d2-209d13ee638f.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=6d55141d-e920-4ef0-bb65-51d899521c0c</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,6d55141d-e920-4ef0-bb65-51d899521c0c.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,6d55141d-e920-4ef0-bb65-51d899521c0c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=6d55141d-e920-4ef0-bb65-51d899521c0c</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Michael Nygard (author of the <em>great</em> book <em>Release It!</em>), writes that
"<a href="http://www.michaelnygard.com/blog/2007/11/a_dozen_levels_of_done.html">[his]
definition of 'done' continues to expand</a>". Currently, his definition reads:
</p>
        <blockquote>
          <p>
A feature is not "done" until all of the following can be said about it: 
</p>
          <ol>
            <li>
All unit tests are green. 
</li>
            <li>
The code is as simple as it can be. 
</li>
            <li>
It communicates clearly. 
</li>
            <li>
It compiles in the automated build from a clean checkout. 
</li>
            <li>
It has passed unit, functional, integration, stress, longevity, load, and resilience
testing. 
</li>
            <li>
The customer has accepted the feature. 
</li>
            <li>
It is included in a release that has been branched in version control. 
</li>
            <li>
The feature's impact on capacity is well-understood. 
</li>
            <li>
Deployment instructions for the release are defined and do not include a "point of
no return". 
</li>
            <li>
Rollback instructions for the release are defined and tested. 
</li>
            <li>
It has been deployed and verified. 
</li>
            <li>
It is generating revenue.</li>
          </ol>
          <p>
Until all of these are true, the feature is just unfinished inventory.
</p>
        </blockquote>
        <p>
As much as I agree with the first 11, I'm not sure I agree with #12. Not because it's
not important--too many software features are added with no positive result--but because
it's too hard to measure the revenue a particular program, much less a particular
software <em>feature</em>, is generating. 
</p>
        <p>
My guess is that this is also conflating the differences between "features" and "releases",
since they aren't always one and the same, and that not all "features" will be ones
mandated by the customer (making #6 somewhat irrelevant). Still, this is an important
point to any and all development shops: 
</p>
        <p>
What do <em>you</em> call "done"?
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=6d55141d-e920-4ef0-bb65-51d899521c0c" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>A Dozen Levels of Done</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,6d55141d-e920-4ef0-bb65-51d899521c0c.aspx</guid>
      <link>http://blogs.tedneward.com/2007/12/05/A+Dozen+Levels+Of+Done.aspx</link>
      <pubDate>Wed, 05 Dec 2007 10:44:41 GMT</pubDate>
      <description>&lt;p&gt;
Michael Nygard (author of the &lt;em&gt;great&lt;/em&gt; book &lt;em&gt;Release It!&lt;/em&gt;), writes that
"&lt;a href="http://www.michaelnygard.com/blog/2007/11/a_dozen_levels_of_done.html"&gt;[his]
definition of 'done' continues to expand&lt;/a&gt;". Currently, his definition reads:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
A feature is not "done" until all of the following can be said about it: 
&lt;ol&gt;
&lt;li&gt;
All unit tests are green. 
&lt;li&gt;
The code is as simple as it can be. 
&lt;li&gt;
It communicates clearly. 
&lt;li&gt;
It compiles in the automated build from a clean checkout. 
&lt;li&gt;
It has passed unit, functional, integration, stress, longevity, load, and resilience
testing. 
&lt;li&gt;
The customer has accepted the feature. 
&lt;li&gt;
It is included in a release that has been branched in version control. 
&lt;li&gt;
The feature's impact on capacity is well-understood. 
&lt;li&gt;
Deployment instructions for the release are defined and do not include a "point of
no return". 
&lt;li&gt;
Rollback instructions for the release are defined and tested. 
&lt;li&gt;
It has been deployed and verified. 
&lt;li&gt;
It is generating revenue.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Until all of these are true, the feature is just unfinished inventory.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
As much as I agree with the first 11, I'm not sure I agree with #12. Not because it's
not important--too many software features are added with no positive result--but because
it's too hard to measure the revenue a particular program, much less a particular
software &lt;em&gt;feature&lt;/em&gt;, is generating. 
&lt;p&gt;
My guess is that this is also conflating the differences between "features" and "releases",
since they aren't always one and the same, and that not all "features" will be ones
mandated by the customer (making #6 somewhat irrelevant). Still, this is an important
point to any and all development shops: 
&lt;p&gt;
What do &lt;em&gt;you&lt;/em&gt; call "done"?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=6d55141d-e920-4ef0-bb65-51d899521c0c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,6d55141d-e920-4ef0-bb65-51d899521c0c.aspx</comments>
      <category>Development Processes</category>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=5809b25c-d912-47d7-8b59-963c9c7ad0a0</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,5809b25c-d912-47d7-8b59-963c9c7ad0a0.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,5809b25c-d912-47d7-8b59-963c9c7ad0a0.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=5809b25c-d912-47d7-8b59-963c9c7ad0a0</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This is not a title I convey lightly, but Michael Nygard's <em>Release It!</em> deserves
the honor. It's the first book I've ever seen that addresses the issues of building
software that's Production-friendly and sysadmin-approachable. He describes a series
of antipatterns describing a variety of software failures, and offers up a series
of solutions (patterns, if you will) to building software systems designed to combat
said failures.
</p>
        <p>
From the back cover:
</p>
        <blockquote>
          <p>
Every website project is really an enterprise integration project: the stakes are
high and the projects complex. In this world where good marketing can be fatal to
yor website, where networks are unreliable, and where astronomically unlikely coincidences
happen daily, you need all the help you can get.
</p>
          <p>
...
</p>
        </blockquote>
        <blockquote>
          <p>
You're a whiz at development. But 80% of typical project lifecyle cost can occur in
production--not in development.
</p>
        </blockquote>
        <p>
Although Michael's personal experience stems mostly from the Java space, the lessons
and stories he offers up are equally relevant to Java, .NET, C++, Ruby, PHP, and any
other language or platform you can imagine. Michael Nygard not only knows the Ten
Fallacies of Enterprise Development, he <em>breathes</em> them.
</p>
        <p>
Go. Now. Buy. Read. Don't write another line of code until you do.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=5809b25c-d912-47d7-8b59-963c9c7ad0a0" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>A Book Every Developer Must Read</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,5809b25c-d912-47d7-8b59-963c9c7ad0a0.aspx</guid>
      <link>http://blogs.tedneward.com/2007/10/08/A+Book+Every+Developer+Must+Read.aspx</link>
      <pubDate>Mon, 08 Oct 2007 00:41:29 GMT</pubDate>
      <description>&lt;p&gt;
This is not a title I convey lightly, but Michael Nygard's &lt;em&gt;Release It!&lt;/em&gt; deserves
the honor. It's the first book I've ever seen that addresses the issues of building
software that's Production-friendly and sysadmin-approachable. He describes a series
of antipatterns describing a variety of software failures, and offers up a series
of solutions (patterns, if you will) to building software systems designed to combat
said failures.
&lt;/p&gt;
&lt;p&gt;
From the back cover:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Every website project is really an enterprise integration project: the stakes are
high and the projects complex. In this world where good marketing can be fatal to
yor website, where networks are unreliable, and where astronomically unlikely coincidences
happen daily, you need all the help you can get.
&lt;/p&gt;
&lt;p&gt;
...
&lt;/p&gt;
&lt;/blockquote&gt; &lt;blockquote&gt; 
&lt;p&gt;
You're a whiz at development. But 80% of typical project lifecyle cost can occur in
production--not in development.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Although Michael's personal experience stems mostly from the Java space, the lessons
and stories he offers up are equally relevant to Java, .NET, C++, Ruby, PHP, and any
other language or platform you can imagine. Michael Nygard not only knows the Ten
Fallacies of Enterprise Development, he &lt;em&gt;breathes&lt;/em&gt; them.
&lt;/p&gt;
&lt;p&gt;
Go. Now. Buy. Read. Don't write another line of code until you do.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=5809b25c-d912-47d7-8b59-963c9c7ad0a0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,5809b25c-d912-47d7-8b59-963c9c7ad0a0.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=1870dd5b-737b-4cca-9247-934d4e42918c</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,1870dd5b-737b-4cca-9247-934d4e42918c.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,1870dd5b-737b-4cca-9247-934d4e42918c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=1870dd5b-737b-4cca-9247-934d4e42918c</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For those who aren't familiar with the term, "yellow journalism" was a moniker
applied to journalism (newspapers, at the time) articles that were written with little
attention to the facts, and maximum attention to gathering attention and selling newspapers.
Articles were sensationalist, highly incorrect or unvalidated, seeking to draw at
the emotional strings the readers would fear or want pulled. Popular at the turn of
the last century, perhaps the most notable example of yellow journalism was the sinking
of the <em>Maine</em>, a US battleship that exploded in harbor while visiting Cuba
(then, ironically, a very US-friendly place). Papers at the time attributed the explosion
to sabotage work by Spain, despite the fact that no cause or proof of sabotage was
ever produced, leading the US to declare war on the Spanish, seize several Spanish
colonies (including the Phillipines in the Pacific, which would turn out to be important
to US Pacific Naval interests during World War Two), and in general pronouce anything
Spanish to be "enemies of the state" and all that.
</p>
        <p>
Vaguely reminiscent of Fox News, now that I think of it.
</p>
        <p>
In this case, however, yellow journalism meets the Web in two recent "IT magazine"
pieces that have come to my attention: <a href="http://www.pcworld.com/article/id,134570-page,1/article.html">this
one</a>, which blasts Sun for not rolling out updates in a more timely fashion to
its consumers, despite the many issues that constant update rollouts pose for those
same consumers, but more flagrantly, <a href="http://www.zdnetasia.com/news/security/0,39044215,62028389,00.htm">this
one</a>, which states that Google researchers have found a vulnerability in the Java
Runtime Environment that "threatens the security of all platforms, browsers,
and even mobile devices". As if that wasn't enough, check out these "sky-is-falling"
quotes:
</p>
        <blockquote>
          <p>
" 'It’s a pretty significant weakness, which will have a considerable impact if the
exploit codes come to fruition quickly. It could affect a lot of organizations and
users.'
</p>
          <p>
"... anyone using the Java Runtime Environment or Java Development Kit is at
risk.
</p>
          <p>
" 'Delivery of exploits in this manner is attractive to attackers because even though
the browser may be fully patched, some people neglect to also patch programs invoked
by browsers to render specific types of content.'
</p>
          <p>
"... the bugs threaten pretty much every modern device.
</p>
          <p>
" '... this exploit is browser independent, as long as it invokes a vulnerable Java
Runtime Environment.'
</p>
          <p>
"... the problem is compounded by the slim chance of an enterprise patching Java Runtime
vulnerabilities.
</p>
        </blockquote>
        <p>
Now, I have no problems with the media reporting security vulnerabilities; in fact,
I encourage it (as any security professional should), because consumers and administrators
can only take action to protect against vulnerabilities when we know about them. But
here's the thing: <em>nowhere</em>, not one place in the article, describes what the
vulnerability actually <em>is</em>. Is this a class verifier problem? Is this a buffer
overflow attack? A luring attack? A flaw in the platform security model? A flaw in
how Java parses and consumes image formats (a la the infamous "picture attachment
attack" that bedevils Outlook every so often)? 
</p>
        <p>
No details are given in this article, just fear, uncertainty and doubt. No quote,
no vague description of how the vulnerability can be exploited, not even a link to the
original report from Google's Security team.
</p>
        <p>
Folks, that is sensationalist journalism at its best. Or worst, if you prefer.
</p>
        <p>
Mr. Tung, who authored the article, should have titled it "The Sky is Falling! The
Sky is Falling!" instead. Frankly, if I were Mr. Tung's editor, this drivel would
never have been published. If I were given the editor's job tomorrow, I'd thank Mr.
Tung for his efforts and send him over to a competitor's publication. Blatant, irresponsible,
and reckless.
</p>
        <p>
Now, if you'll excuse me, I'm going to try and find some hard data on this vulnerability.
Any vulnerability that can somehow strike across every JVM ever written (according
to the article above) must be some kinda doozy. After all, I need to learn how to
defend myself before al Qaeda gets hold of this and takes over "pretty much every
modern device" and uses them to take over the world, which surely must be next....
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=1870dd5b-737b-4cca-9247-934d4e42918c" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Yellow Journalism Meets The Web... again...</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,1870dd5b-737b-4cca-9247-934d4e42918c.aspx</guid>
      <link>http://blogs.tedneward.com/2007/07/15/Yellow+Journalism+Meets+The+Web+Again.aspx</link>
      <pubDate>Sun, 15 Jul 2007 06:07:48 GMT</pubDate>
      <description>&lt;p&gt;
For those who aren't familiar with the term, "yellow journalism" was&amp;nbsp;a moniker
applied to journalism (newspapers, at the time) articles that were written with little
attention to the facts, and maximum attention to gathering attention and selling newspapers.
Articles were sensationalist, highly incorrect or unvalidated, seeking to draw at
the emotional strings the readers would fear or want pulled. Popular at the turn of
the last century, perhaps the most notable example of yellow journalism was the sinking
of the &lt;em&gt;Maine&lt;/em&gt;, a US battleship that exploded in harbor while visiting Cuba
(then, ironically, a very US-friendly place). Papers at the time attributed the explosion
to sabotage work by Spain, despite the fact that no cause or proof of sabotage was
ever produced, leading the US to declare war on the Spanish, seize several Spanish
colonies (including the Phillipines in the Pacific, which would turn out to be important
to US Pacific Naval interests during World War Two), and in general pronouce anything
Spanish to be "enemies of the state" and all that.
&lt;/p&gt;
&lt;p&gt;
Vaguely reminiscent of Fox News, now that I think of it.
&lt;/p&gt;
&lt;p&gt;
In this case, however, yellow journalism meets the Web in two recent "IT magazine"
pieces that have come to my attention: &lt;a href="http://www.pcworld.com/article/id,134570-page,1/article.html"&gt;this
one&lt;/a&gt;, which blasts Sun for not rolling out updates in a more timely fashion to
its consumers, despite the many issues that constant update rollouts pose for those
same consumers, but more flagrantly, &lt;a href="http://www.zdnetasia.com/news/security/0,39044215,62028389,00.htm"&gt;this
one&lt;/a&gt;, which states that Google researchers have found a vulnerability in the Java
Runtime Environment that&amp;nbsp;"threatens the security of all platforms, browsers,
and even mobile devices". As if that wasn't enough, check out these "sky-is-falling"
quotes:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
" 'It’s a pretty significant weakness, which will have a considerable impact if the
exploit codes come to fruition quickly. It could affect a lot of organizations and
users.'
&lt;/p&gt;
&lt;p&gt;
"...&amp;nbsp;anyone using the Java Runtime Environment or Java Development Kit is at
risk.
&lt;/p&gt;
&lt;p&gt;
" 'Delivery of exploits in this manner is attractive to attackers because even though
the browser may be fully patched, some people neglect to also patch programs invoked
by browsers to render specific types of content.'
&lt;/p&gt;
&lt;p&gt;
"... the bugs threaten pretty much every modern device.
&lt;/p&gt;
&lt;p&gt;
" '... this exploit is browser independent, as long as it invokes a vulnerable Java
Runtime Environment.'
&lt;/p&gt;
&lt;p&gt;
"... the problem is compounded by the slim chance of an enterprise patching Java Runtime
vulnerabilities.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Now, I have no problems with the media reporting security vulnerabilities; in fact,
I encourage it (as any security professional should), because consumers and administrators
can only take action to protect against vulnerabilities when we know about them. But
here's the thing: &lt;em&gt;nowhere&lt;/em&gt;, not one place in the article, describes what the
vulnerability actually &lt;em&gt;is&lt;/em&gt;. Is this a class verifier problem? Is this a buffer
overflow attack? A luring attack? A flaw in the platform security model? A flaw in
how Java parses and consumes image formats (a la the infamous "picture attachment
attack" that bedevils Outlook every so often)? 
&lt;/p&gt;
&lt;p&gt;
No details are given in this article, just fear, uncertainty and doubt. No quote,
no vague description of how the vulnerability can be exploited, not even a link to&amp;nbsp;the
original&amp;nbsp;report from Google's Security team.
&lt;/p&gt;
&lt;p&gt;
Folks, that is sensationalist journalism at its best. Or worst, if you prefer.
&lt;/p&gt;
&lt;p&gt;
Mr. Tung, who authored the article, should have titled it "The Sky is Falling! The
Sky is Falling!" instead. Frankly, if I were Mr. Tung's editor, this drivel would
never have been published. If I were given the editor's job tomorrow, I'd thank Mr.
Tung for his efforts and send him over to a competitor's publication. Blatant, irresponsible,
and reckless.
&lt;/p&gt;
&lt;p&gt;
Now, if you'll excuse me, I'm going to try and find some hard data on this vulnerability.
Any vulnerability that can somehow strike across every JVM ever written (according
to the article above) must be some kinda doozy. After all, I need to learn how to
defend myself before al Qaeda gets hold of this and takes over "pretty much every
modern device" and uses them to take over the world, which surely must be next....
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=1870dd5b-737b-4cca-9247-934d4e42918c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,1870dd5b-737b-4cca-9247-934d4e42918c.aspx</comments>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=f03c0ea3-6c5e-48a1-884e-6e1f616290d6</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,f03c0ea3-6c5e-48a1-884e-6e1f616290d6.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,f03c0ea3-6c5e-48a1-884e-6e1f616290d6.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=f03c0ea3-6c5e-48a1-884e-6e1f616290d6</wfw:commentRss>
      <slash:comments>8</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
At a software conference not too long ago, I was asked what book I was currently reading
that I'd recommend, and I responded, "Robert Greene's <em>The 33 Strategies of War"</em>.
When asked why I'd recommend this, the response was pretty simple: "Because I believe
that there's more parallels to what we do in military history than in constructing
buildings."
</p>
        <p>
Greene's book is an attempt at a distillation of what all the most successful generals
and military leaders throughout history used to make them so successful. A lot of
these concepts and ideas are just generally good practices, but a fair amount of them
actually apply pretty directly to software development (whether you call it "agile"
or not). Consider this excerpt from the Preface, for example:
</p>
        <blockquote>
          <p>
The war [that exists in the real world] exists on several levels. Most obviously,
we have our rivals on the other side. The world has become increasingly competitive
and nasty. In politics, business, even the arts, we face opponents who will do almost
anything to gain an edge. More troubling and complex, however, are the battles we
face with those who are supposedly on our side. There are those who outwardly play
the team game, who act very friendly and agreeable, but who sabotage us behind the
scenes, ues the group to promote their own agenda. Others, more difficult to spot,
play subtle games of passive aggression, offering help that never comes, instilling
guilt as a secret weapon. On the surface everything seems peaceful enough, but just
below it, it is every man and woman for him- or herself, this dynamic infecting even
families and relationships. The culture may deny this reality and promote a gentler
picture, but we know it and feel it, in our battle scars.
</p>
        </blockquote>
        <p>
Without trying to paint a paranoid picture, this "dynamic of war" frequently infects
software development teams and organizations; developers vs. management, developers
vs. system adminstrators, developers vs. DBAs, even developers vs. architects or developers
vs. developers. His book, then, suggests that we need to face this reality and learn
how to deal with it:
</p>
        <blockquote>
          <p>
What we need are not impossible and inhuman ideals of peace and cooperation to live
up to, and the confusion that brings us, but rather practical knowledge on how to
deal with conflict and the daily battles we face. And this knowledge is not about
how to be more forceful in getting what we want or defending ourselves but rather
how to be more rational and strategic when it comes to conflict, channeling our aggressive
impulses instead of denying or repressing them. If there is an ideal to aim for, it
should be that of the strategic warrior, the man or woman who manages difficult situations
and people through deft and intelligent maneuver.
</p>
        </blockquote>
        <p>
... and I want that man or woman heading up my project team.
</p>
        <p>
It may seem incongruous to draw parallels between war and software development, because
in war there is an obvious "enemy", an obvious target for our aggression and intentions
and strategies and tactics. It turns out, however, that the "enemy" in software development
is far more nebulous and amorphous, that of "failure", which can be just as tenacious
and subversive. This enemy won't ever try to storm your cubicles and kill you or try
to hold you for ransom, but a lot of the strategies that Greene talks about aren't
so much about how to kill people, but how to think strategically, which is, to my
mind, something we all of us have to do more of.
</p>
        <p>
Consider this, for example; Greene suggests "six fundamental ideals you should aim
for in transforming yourself into a strategic warrior in daily life":
</p>
        <ul>
          <li>
            <em>Look at things as they are, not as your emotions color them</em>. Too often, it's
easy to "lose your head" and see the situation in emotional terms, rather than rational
ones. "Fear will make you overestimate the enemy and act too defensively"; in other
words, fear will cause you to act too conservatively and resist taking the necessary
gamble on a technology or idea that will lead to success. "Anger and impatience will
draw you into rash actions that will cut off your options"; or, anger and impatience
will cause you to act rashly with respect to co-workers (such as DBAs and sysadmins)
or technology decisions that may leave you with no clear path forward. "The only remedy
is to be aware that the pull of emotion is inevitable, to notice it when it is happening,
and to compensate for it."</li>
          <li>
            <em>Judge people by their actions</em>. "What people say about themselves [on resumes,
in meetings, during conversations] does not matter; people will say anything. Look
at what they have done; deeds do not lie." Which means, you have to have a way by
which to measure those deeds, meaning you have to have a good "feel" for what's going
on in your department--simply listening to reports in meetings is often not enough.
"In looking back at a defeat [failed project], you must identify the things you could
have done differently. It is your own bad strategies, not the unfair opponent [or
management decisions or unhelpful IT department, or whatever], that are to blame for
your failures. You are responsible for the good and bad in your life."</li>
          <li>
            <em>Depend on your own arms</em>. "... people tend to rely on things that seem simple
and easy or that have worked before. ... But true strategy is psychological--a matter
of intelligence, not material force. ... But if your mind is armed with the art of
war, there is no power that can take that away. In the middle of a crisis, your mind
will find its way to the right solution. ... As Sun-tzu says, 'Being unconquerable
lies with yourself.' "</li>
          <li>
            <em>Worship Athena, not Ares</em>. This one probably doesn't translate directly; Athena
was the goddess of war in its form seen in guile, wisdom, and cleverness, whereas
Ares was the god of war in its direct and brutal form. Athena always fought with the
utmost intelligence and subtlety; Ares fought for the sheer joy of blood. Probably
the closest parallel here would be to suggest that we seek subtle solutions, not brute
force ones, meaning look for answers that don't require hiring thousands of consultants
and developers. But that's a stretch.</li>
          <li>
            <em>Elevate yourself above the battlefield</em>. "In war, strategy is the art of commanding
the entire miliary operation. Tactics, on the other hand, is the skill of forming
up the army for battle [project] itself and dealing with the immediate needs of the
battlefield. Most of us in life are tacticians, not strategists." Too many project
managers (and team members) never look beyond the immediate project in front of them
to consider the wider implications of their actions. "To have the power that only
strategy can bring, you must be able to elevate yourself above the battlefield, to
focus on your long-term objectives, to craft an entire campaign, to get out of the
reactive mode that so many battles in life lock you into. Keeping your overall goals
in mind, it becomes much easier to decide when to fight [or accept a job or accept
a project] and when to walk away."</li>
          <li>
            <em>Spiritualize your warfare</em>. "... the greatest battle is with yourself--your
weaknesses, your emotions, your lack of resolution in seeing things through to the
end. You must declare unceasing war on yourself. As a warrior in life, you welcome
combat and conflict as ways to prove yourself, to better your skills, to gain courage,
confidence and experience." That means we should never let fear or doubt stop us from
tackling a new challenge (but, similarly, we shouldn't risk others' welfare on wild
risks). "You want more challenges, and you invite more war [or projects]."</li>
        </ul>
        <p>
Granted, it's not a complete 1-to-1 match, but there's a lot that the average developer
can learn from the likes of Sun-Tzu, MacArthur, Julies Caesar, Genghis Khan, Miyamoto
Musashi, Erwin Rommel, or Carl von Clausewitz.
</p>
        <p>
Just for reference purposes, the original 33 strategies (some of which may not be
easy or even possible to adapt) are:
</p>
        <ol>
          <li>
Declare war on your enemies: The Polarity Strategy</li>
          <li>
Do not fight the last war: The Guerilla-War-of-the-Mind Strategy</li>
          <li>
Amidst the turmoil of events, do not lose your presence of mind: The Counterbalance
Strategy</li>
          <li>
Create a sense of urgency and desperation: The Death-Ground Strategy</li>
          <li>
Avoid the snares of groupthink: The Command-and-Control Strategy</li>
          <li>
Segment your forces: The Controlled-Chaos Strategy</li>
          <li>
Transform your war into a crusade: Morale Strategies</li>
          <li>
Pick your battles carefully: The Perfect-Economy Strategy</li>
          <li>
Turn the Tables: The Counterattack Strategy</li>
          <li>
Create a threatening presence: Deterrence Strategies</li>
          <li>
Trade space for time: The Nonengagement Strategy</li>
          <li>
Lose battles but win the war: Grand Strategy</li>
          <li>
Know your enemy: The Intelligence Strategy</li>
          <li>
Overwhelm resistance with speed and suddenness: The Blitzkrieg Strategy</li>
          <li>
Control the dynamic: Forcing Strategies</li>
          <li>
Hit them where it hurts: The Center-of-Gravity Strategy</li>
          <li>
Defeat them in detail: The Divide-and-Conquer Strategy</li>
          <li>
Expose and attack your opponent's soft flank: The Turning Strategy</li>
          <li>
Envelop the enemy: The Annihiliation Strategy</li>
          <li>
Maneuver them into weakness: The Ripening-for-the-sickle Strategy</li>
          <li>
Negotiate while advancing: The Diplomatic-War Strategy</li>
          <li>
Know how to end things: The Exit Strategy</li>
          <li>
Weave a seamless blend of fact and fiction: Misperception Strategies</li>
          <li>
Take the line of least expectation: The Ordinary Extraordinary Strategy</li>
          <li>
Occupy the moral high ground: The Righteous Strategy</li>
          <li>
Deny them targets: The Strategy of the Void</li>
          <li>
Seem to work for the interests of others while furthering your own: The Alliance Strategy</li>
          <li>
Give your rivals enough rope to hang themselves: The One-Upmanship Strategy</li>
          <li>
Take small bites: The Fait Accompli Strategy</li>
          <li>
Penetrate their minds: Communication Strategies</li>
          <li>
Destroy them from within: The Inner-Front Strategy</li>
          <li>
Dominate while seeming to submit: The Passive-Aggression Strategy</li>
          <li>
Sow uncertainty and panic through acts of terror: The Chain-Reaction Strategy</li>
        </ol>
        <p>
What I'm planning to do, then, is go through the 33 strategies of war, analogize as
necessary/possible, and publishthe results. Hopefully people find it useful, but even
if you don't think it's going to help, it'll help me internalize the elements I want
to through the process just for my own use. And, in the end, that's the point of "spiritualize
your warfare": trying to continuously enhance yourself.
</p>
        <p>
Naturally, I invite comment and debate; in fact, I'd really encourage it, because
I'm not going to promise that these are 100%-polished ideas or concepts, at least
as how they apply to software. So please, feel free to comment, either publicly on
the blog or privately through email, whether you agree or not. (Particularly
if you don't agree--the more the idea is tested, the better it stands, or the sooner
it gets refactored.)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=f03c0ea3-6c5e-48a1-884e-6e1f616290d6" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>The Strategies of Software Development</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,f03c0ea3-6c5e-48a1-884e-6e1f616290d6.aspx</guid>
      <link>http://blogs.tedneward.com/2007/07/14/The+Strategies+Of+Software+Development.aspx</link>
      <pubDate>Sat, 14 Jul 2007 05:41:02 GMT</pubDate>
      <description>&lt;p&gt;
At a software conference not too long ago, I was asked what book I was currently reading
that I'd recommend, and I responded, "Robert Greene's &lt;em&gt;The 33 Strategies of War"&lt;/em&gt;.
When asked why I'd recommend this, the response was pretty simple: "Because I believe
that there's more parallels to what we do in military history than in constructing
buildings."
&lt;/p&gt;
&lt;p&gt;
Greene's book is an attempt at a distillation of what all the most successful generals
and military leaders throughout history used to make them so successful. A lot of
these concepts and ideas are just generally good practices, but a fair amount of them
actually apply pretty directly to software development (whether you call it "agile"
or not). Consider this excerpt from the Preface, for example:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
The war [that exists in the real world] exists on several levels. Most obviously,
we have our rivals on the other side. The world has become increasingly competitive
and nasty. In politics, business, even the arts, we face opponents who will do almost
anything to gain an edge. More troubling and complex, however, are the battles we
face with those who are supposedly on our side. There are those who outwardly play
the team game, who act very friendly and agreeable, but who sabotage us behind the
scenes, ues the group to promote their own agenda. Others, more difficult to spot,
play subtle games of passive aggression, offering help that never comes, instilling
guilt as a secret weapon. On the surface everything seems peaceful enough, but just
below it, it is every man and woman for him- or herself, this dynamic infecting even
families and relationships. The culture may deny this reality and promote a gentler
picture, but we know it and feel it, in our battle scars.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Without trying to paint a paranoid picture, this "dynamic of war" frequently infects
software development teams and organizations; developers vs. management, developers
vs. system adminstrators, developers vs. DBAs, even developers vs. architects or developers
vs. developers. His book, then, suggests that we need to face this reality and learn
how to deal with it:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
What we need are not impossible and inhuman ideals of peace and cooperation to live
up to, and the confusion that brings us, but rather practical knowledge on how to
deal with conflict and the daily battles we face. And this knowledge is not about
how to be more forceful in getting what we want or defending ourselves but rather
how to be more rational and strategic when it comes to conflict, channeling our aggressive
impulses instead of denying or repressing them. If there is an ideal to aim for, it
should be that of the strategic warrior, the man or woman who manages difficult situations
and people through deft and intelligent maneuver.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
... and I want that man or woman heading up my project team.
&lt;/p&gt;
&lt;p&gt;
It may seem incongruous to draw parallels between war and software development, because
in war there is an obvious "enemy", an obvious target for our aggression and intentions
and strategies and tactics. It turns out, however, that the "enemy" in software development
is far more nebulous and amorphous, that of "failure", which can be just as tenacious
and subversive. This enemy won't ever try to storm your cubicles and kill you or try
to hold you for ransom, but a lot of the strategies that Greene talks about aren't
so much about how to kill people, but how to think strategically, which is, to my
mind, something we all of us have to do more of.
&lt;/p&gt;
&lt;p&gt;
Consider this, for example; Greene suggests "six fundamental ideals you should aim
for in transforming yourself into a strategic warrior in daily life":
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Look at things as they are, not as your emotions color them&lt;/em&gt;. Too often, it's
easy to "lose your head" and see the situation in emotional terms, rather than rational
ones. "Fear will make you overestimate the enemy and act too defensively"; in other
words, fear will cause you to act too conservatively and resist taking the necessary
gamble on a technology or idea that will lead to success. "Anger and impatience will
draw you into rash actions that will cut off your options"; or, anger and impatience
will cause you to act rashly with respect to co-workers (such as DBAs and sysadmins)
or technology decisions that may leave you with no clear path forward. "The only remedy
is to be aware that the pull of emotion is inevitable, to notice it when it is happening,
and to compensate for it."&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Judge people by their actions&lt;/em&gt;. "What people say about themselves [on resumes,
in meetings, during conversations] does not matter; people will say anything. Look
at what they have done; deeds do not lie." Which means, you have to have a way by
which to measure those deeds, meaning you have to have a good "feel" for what's going
on in your department--simply listening to reports in meetings is often not enough.
"In looking back at a defeat [failed project], you must identify the things you could
have done differently. It is your own bad strategies, not the unfair opponent [or
management decisions or unhelpful IT department, or whatever], that are to blame for
your failures. You are responsible for the good and bad in your life."&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Depend on your own arms&lt;/em&gt;. "... people tend to rely on things that seem simple
and easy or that have worked before. ... But true strategy is psychological--a matter
of intelligence, not material force. ... But if your mind is armed with the art of
war, there is no power that can take that away. In the middle of a crisis, your mind
will find its way to the right solution. ... As Sun-tzu says, 'Being unconquerable
lies with yourself.' "&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Worship Athena, not Ares&lt;/em&gt;. This one probably doesn't translate directly; Athena
was the goddess of war in its form seen in guile, wisdom, and cleverness, whereas
Ares was the god of war in its direct and brutal form. Athena always fought with the
utmost intelligence and subtlety; Ares fought for the sheer joy of blood. Probably
the closest parallel here would be to suggest that we seek subtle solutions, not brute
force ones, meaning look for answers that don't require hiring thousands of consultants
and developers. But that's a stretch.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Elevate yourself above the battlefield&lt;/em&gt;. "In war, strategy is the art of commanding
the entire miliary operation. Tactics, on the other hand, is the skill of forming
up the army for battle [project] itself and dealing with the immediate needs of the
battlefield. Most of us in life are tacticians, not strategists." Too many project
managers (and team members) never look beyond the immediate project in front of them
to consider the wider implications of their actions. "To have the power that only
strategy can bring, you must be able to elevate yourself above the battlefield, to
focus on your long-term objectives, to craft an entire campaign, to get out of the
reactive mode that so many battles in life lock you into. Keeping your overall goals
in mind, it becomes much easier to decide when to fight [or accept a job or accept
a project] and when to walk away."&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Spiritualize your warfare&lt;/em&gt;. "... the greatest battle is with yourself--your
weaknesses, your emotions, your lack of resolution in seeing things through to the
end. You must declare unceasing war on yourself. As a warrior in life, you welcome
combat and conflict as ways to prove yourself, to better your skills, to gain courage,
confidence and experience." That means we should never let fear or doubt stop us from
tackling a new challenge (but, similarly, we shouldn't risk others' welfare on wild
risks). "You want more challenges, and you invite more war [or projects]."&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Granted, it's not a complete 1-to-1 match, but there's a lot that the average developer
can learn from the likes of Sun-Tzu, MacArthur, Julies Caesar, Genghis Khan, Miyamoto
Musashi, Erwin Rommel, or Carl von Clausewitz.
&lt;/p&gt;
&lt;p&gt;
Just for reference purposes, the original 33 strategies (some of which may not be
easy or even possible to adapt) are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Declare war on your enemies: The Polarity Strategy&lt;/li&gt;
&lt;li&gt;
Do not fight the last war: The Guerilla-War-of-the-Mind Strategy&lt;/li&gt;
&lt;li&gt;
Amidst the turmoil of events, do not lose your presence of mind: The Counterbalance
Strategy&lt;/li&gt;
&lt;li&gt;
Create a sense of urgency and desperation: The Death-Ground Strategy&lt;/li&gt;
&lt;li&gt;
Avoid the snares of groupthink: The Command-and-Control Strategy&lt;/li&gt;
&lt;li&gt;
Segment your forces: The Controlled-Chaos Strategy&lt;/li&gt;
&lt;li&gt;
Transform your war into a crusade: Morale Strategies&lt;/li&gt;
&lt;li&gt;
Pick your battles carefully: The Perfect-Economy Strategy&lt;/li&gt;
&lt;li&gt;
Turn the Tables: The Counterattack Strategy&lt;/li&gt;
&lt;li&gt;
Create a threatening presence: Deterrence Strategies&lt;/li&gt;
&lt;li&gt;
Trade space for time: The Nonengagement Strategy&lt;/li&gt;
&lt;li&gt;
Lose battles but win the war: Grand Strategy&lt;/li&gt;
&lt;li&gt;
Know your enemy: The Intelligence Strategy&lt;/li&gt;
&lt;li&gt;
Overwhelm resistance with speed and suddenness: The Blitzkrieg Strategy&lt;/li&gt;
&lt;li&gt;
Control the dynamic: Forcing Strategies&lt;/li&gt;
&lt;li&gt;
Hit them where it hurts: The Center-of-Gravity Strategy&lt;/li&gt;
&lt;li&gt;
Defeat them in detail: The Divide-and-Conquer Strategy&lt;/li&gt;
&lt;li&gt;
Expose and attack your opponent's soft flank: The Turning Strategy&lt;/li&gt;
&lt;li&gt;
Envelop the enemy: The Annihiliation Strategy&lt;/li&gt;
&lt;li&gt;
Maneuver them into weakness: The Ripening-for-the-sickle Strategy&lt;/li&gt;
&lt;li&gt;
Negotiate while advancing: The Diplomatic-War Strategy&lt;/li&gt;
&lt;li&gt;
Know how to end things: The Exit Strategy&lt;/li&gt;
&lt;li&gt;
Weave a seamless blend of fact and fiction: Misperception Strategies&lt;/li&gt;
&lt;li&gt;
Take the line of least expectation: The Ordinary Extraordinary Strategy&lt;/li&gt;
&lt;li&gt;
Occupy the moral high ground: The Righteous Strategy&lt;/li&gt;
&lt;li&gt;
Deny them targets: The Strategy of the Void&lt;/li&gt;
&lt;li&gt;
Seem to work for the interests of others while furthering your own: The Alliance Strategy&lt;/li&gt;
&lt;li&gt;
Give your rivals enough rope to hang themselves: The One-Upmanship Strategy&lt;/li&gt;
&lt;li&gt;
Take small bites: The Fait Accompli Strategy&lt;/li&gt;
&lt;li&gt;
Penetrate their minds: Communication Strategies&lt;/li&gt;
&lt;li&gt;
Destroy them from within: The Inner-Front Strategy&lt;/li&gt;
&lt;li&gt;
Dominate while seeming to submit: The Passive-Aggression Strategy&lt;/li&gt;
&lt;li&gt;
Sow uncertainty and panic through acts of terror: The Chain-Reaction Strategy&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
What I'm planning to do, then, is go through the 33 strategies of war, analogize as
necessary/possible, and publishthe results. Hopefully people find it useful, but even
if you don't think it's going to help, it'll help me internalize the elements I want
to through the process just for my own use. And, in the end, that's the point of "spiritualize
your warfare": trying to continuously enhance yourself.
&lt;/p&gt;
&lt;p&gt;
Naturally, I invite comment and debate; in fact, I'd really encourage it, because
I'm not going to promise that these are 100%-polished ideas or concepts, at least
as how they apply to software. So please, feel free to comment, either publicly on
the blog or privately through email, whether you agree or not.&amp;nbsp;(Particularly
if you don't agree--the more the idea is tested, the better it stands, or the sooner
it gets refactored.)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=f03c0ea3-6c5e-48a1-884e-6e1f616290d6" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,f03c0ea3-6c5e-48a1-884e-6e1f616290d6.aspx</comments>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=31f27c88-e3c7-48cb-bc12-13505f4993ba</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,31f27c88-e3c7-48cb-bc12-13505f4993ba.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,31f27c88-e3c7-48cb-bc12-13505f4993ba.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=31f27c88-e3c7-48cb-bc12-13505f4993ba</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://softarc.blogspot.com/">Frank Kelly</a> posted some good ideas on his
entry, <a href="http://softarc.blogspot.com/2006/12/java-are-we-worrying-about-wrong-things.html">"Java:
Are we worrying about the wrong things?"</a>, but more interestingly, he suggested
(implicitly) a new format for weighing in on trends and such, his "Important/Not-so-important"
style. For example,
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <strong>NOT SO IMPORTANT</strong>: Web 2.0<br /><strong>IMPORTANT</strong>: Giving users a good, solid user experience. Web 2.0 doesn't
make sites better by itself - it provides powerful technologies but it's no silver
bullet. There are so many terrible web sites out there with issues such as<br />
- Too much content / too cluttered <a href="http://jdj.sys-con.com/"><font color="#338888">http://jdj.sys-con.com/</font></a><br />
- Too heavy for the many folks still on dial-up<br />
- Inconsistent labeling- etc. (See <a href="http://www.useit.com/alertbox/"><font color="#338888">Jakob
Nielsen's site </font></a>for some great articles )<br />
Sometimes you have to wonder if some web site designers actually care about their
intended audience?
</p>
        </blockquote>
        <p>
I love this format--it helps cut through the B/S and get to the point. Frank, I freely
admit that I'm going to steal this idea from you, so I hope you're watching Trackbacks
or blog links or whatever. :)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=31f27c88-e3c7-48cb-bc12-13505f4993ba" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Important/Not-so-important</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,31f27c88-e3c7-48cb-bc12-13505f4993ba.aspx</guid>
      <link>http://blogs.tedneward.com/2007/01/30/ImportantNotsoimportant.aspx</link>
      <pubDate>Tue, 30 Jan 2007 11:17:23 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://softarc.blogspot.com/"&gt;Frank Kelly&lt;/a&gt; posted some good ideas on his
entry, &lt;a href="http://softarc.blogspot.com/2006/12/java-are-we-worrying-about-wrong-things.html"&gt;"Java:
Are we worrying about the wrong things?"&lt;/a&gt;, but more interestingly, he suggested
(implicitly) a new format for weighing in on trends and such, his "Important/Not-so-important"
style. For example,
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;strong&gt;NOT SO IMPORTANT&lt;/strong&gt;: Web 2.0&lt;br&gt;
&lt;strong&gt;IMPORTANT&lt;/strong&gt;: Giving users a good, solid user experience. Web 2.0 doesn't
make sites better by itself - it provides powerful technologies but it's no silver
bullet. There are so many terrible web sites out there with issues such as&lt;br&gt;
- Too much content / too cluttered &lt;a href="http://jdj.sys-con.com/"&gt;&lt;font color=#338888&gt;http://jdj.sys-con.com/&lt;/font&gt;&lt;/a&gt;
&lt;br&gt;
- Too heavy for the many folks still on dial-up&lt;br&gt;
- Inconsistent labeling- etc. (See &lt;a href="http://www.useit.com/alertbox/"&gt;&lt;font color=#338888&gt;Jakob
Nielsen's site &lt;/font&gt;&lt;/a&gt;for some great articles )&lt;br&gt;
Sometimes you have to wonder if some web site designers actually care about their
intended audience?
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
I love this format--it helps cut through the B/S and get to the point. Frank, I freely
admit that I'm going to steal this idea from you, so I hope you're watching Trackbacks
or blog links or whatever. :)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=31f27c88-e3c7-48cb-bc12-13505f4993ba" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,31f27c88-e3c7-48cb-bc12-13505f4993ba.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=8bb98382-dc28-442a-ab8b-6b61a8794bd4</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,8bb98382-dc28-442a-ab8b-6b61a8794bd4.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,8bb98382-dc28-442a-ab8b-6b61a8794bd4.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8bb98382-dc28-442a-ab8b-6b61a8794bd4</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
While traveling not too long ago, I saw a great piece on ethics, and wished I'd kept
the silly magazine (I couldn't remember which one) because it was just a really good
summation of how to live the ethical life. While wandering around the Web with Google
tonight, <a href="http://www.hemispheresmagazine.com/nov06/cybersidebar.html">I found
it</a> (scroll down a bit, to after the bits on Prohibition and Laughable Laws);
in summary, the author advocates a life around five basic points:
</p>
        <ol>
          <li>
Do no harm</li>
          <li>
Make things better</li>
          <li>
Respect others</li>
          <li>
Be fair</li>
          <li>
Be loving</li>
        </ol>
        <p>
Seems pretty simple, no? The problems occur, of course, in the interpretation and
execution. For example, how exactly do we define "better", when we seek to make things
better? Had I the power, I would create a world where all people are free to practice
whatever religious beliefs they hold, but clearly if those religious beliefs involve
human sacrifice, then it's of dubious belief that my actions made the world "better".
(Of course, said practitioners would probably disagree.)
</p>
        <p>
It's also pretty hard to actually follow through on these on a daily basis. The author,
Bruce Weinstein, makes this pretty clear in this example:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
For example, how often do we really keep “do no harm” in mind during our daily interactions
with people? If a clerk at the grocery store is nasty to us, don’t we return the nastiness
and tell ourselves, “Serves them right?”  We may, but if we do, we harm the other
person. In so doing, we harm our own soul—and this is one of the reasons why we shouldn’t
return nastiness with more of the same.
</p>
        </blockquote>
        <p>
Ouch. Guilty as charged.
</p>
        <p>
There's a quiz attached to the article, and I highly suggest anyone who cares about
their own ethical behavior take it; some of the questions are pretty clear-cut (at
least to me), but some of them fall into that category of "Well, I know what I *should*
say I would do, but...", and some of them are just downright surprising.
</p>
        <p>
Personally, I think these five points are points that every developer should also
advocate and life their life by, since, quite honestly, I think we as an industry
do a pretty poor job on all five points. Clearly we violate #1 when we're not careful
with security measures in the code; too many programmers (and projects) fail
to realize that "better" in #2 is from the customers' perspective, not our own; too
many programmers look down on anyone who's not technical in some way, or even those
who disagree with them, thus violating #3; too many consultants I've met (thankfully
none I can call "friends") will take any excuse to overbill a client (#4); and so
on, and so on, and so on.
</p>
        <p>
Maybe I'm getting negative in my old age, but it just seems to me that there's too
much shouting and posturing going on (*cough* Fleury *cough*) and not enough focus
on the people to whom we are ultimately beholden: our customers. Do what's right for
them, even if it's not the easy thing to do, even when they don't think they need
it (such as the incapcitated friend in the quiz), and you can never go wrong.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=8bb98382-dc28-442a-ab8b-6b61a8794bd4" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>More on Ethics</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,8bb98382-dc28-442a-ab8b-6b61a8794bd4.aspx</guid>
      <link>http://blogs.tedneward.com/2007/01/27/More+On+Ethics.aspx</link>
      <pubDate>Sat, 27 Jan 2007 01:34:23 GMT</pubDate>
      <description>&lt;p&gt;
While traveling not too long ago, I saw a great piece on ethics, and wished I'd kept
the silly magazine (I couldn't remember which one) because it was just a really good
summation of how to live the ethical life. While wandering around the Web with Google
tonight, &lt;a href="http://www.hemispheresmagazine.com/nov06/cybersidebar.html"&gt;I found
it&lt;/a&gt;&amp;nbsp;(scroll down a bit, to after the bits on Prohibition and Laughable Laws);
in summary, the author advocates a life around five basic points:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Do no harm&lt;/li&gt;
&lt;li&gt;
Make things better&lt;/li&gt;
&lt;li&gt;
Respect others&lt;/li&gt;
&lt;li&gt;
Be fair&lt;/li&gt;
&lt;li&gt;
Be loving&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Seems pretty simple, no? The problems occur, of course, in the interpretation and
execution. For example, how exactly do we define "better", when we seek to make things
better? Had I the power, I would create a world where all people are free to practice
whatever religious beliefs they hold, but clearly if those religious beliefs involve
human sacrifice, then it's of dubious belief that my actions made the world "better".
(Of course, said practitioners would probably disagree.)
&lt;/p&gt;
&lt;p&gt;
It's also pretty hard to actually follow through on these on a daily basis. The author,
Bruce Weinstein, makes this pretty clear in this example:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
For example, how often do we really keep “do no harm” in mind during our daily interactions
with people? If a clerk at the grocery store is nasty to us, don’t we return the nastiness
and tell ourselves, “Serves them right?”&amp;nbsp; We may, but if we do, we harm the other
person. In so doing, we harm our own soul—and this is one of the reasons why we shouldn’t
return nastiness with more of the same.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Ouch. Guilty as charged.
&lt;/p&gt;
&lt;p&gt;
There's a quiz attached to the article, and I highly suggest anyone who cares about
their own ethical behavior take it; some of the questions are pretty clear-cut (at
least to me), but some of them fall into that category of "Well, I know what I *should*
say I would do, but...", and some of them are just downright surprising.
&lt;/p&gt;
&lt;p&gt;
Personally, I think these five points are points that every developer should also
advocate and life their life by, since, quite honestly, I think we as an industry
do a pretty poor job on all five points. Clearly we violate #1 when we're not careful
with security measures in the code; too many&amp;nbsp;programmers (and projects)&amp;nbsp;fail
to realize that "better" in #2 is from the customers' perspective, not our own; too
many programmers look down on anyone who's not technical in some way, or even those
who disagree with them, thus violating #3; too many consultants I've met (thankfully
none I can call "friends") will take any excuse to overbill a client (#4); and so
on, and so on, and so on.
&lt;/p&gt;
&lt;p&gt;
Maybe I'm getting negative in my old age, but it just seems to me that there's too
much shouting and posturing going on (*cough* Fleury *cough*) and not enough focus
on the people to whom we are ultimately beholden: our customers. Do what's right for
them, even if it's not the easy thing to do, even when they don't think they need
it (such as the incapcitated friend in the quiz), and you can never go wrong.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=8bb98382-dc28-442a-ab8b-6b61a8794bd4" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,8bb98382-dc28-442a-ab8b-6b61a8794bd4.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=17a2b01b-f398-4033-b914-d10418fb0a53</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,17a2b01b-f398-4033-b914-d10418fb0a53.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,17a2b01b-f398-4033-b914-d10418fb0a53.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=17a2b01b-f398-4033-b914-d10418fb0a53</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Michael.NET, apparently inspired by my "Check Your Politics At The Door" post, and
equally peeved at <a href="http://blogs.msdn.com/reedme/archive/2007/01/10/is-your-daylight-going-to-be-saved-this-year.aspx">another
post on blogs.msdn.com</a>, hit a note of pure inspiration when he created his list
of <a href="http://michaeldotnet.blogspot.com/2007/01/programming-promises.html">"Programming
Promises"</a>, which I repeat below:
</p>
        <ul>
          <li>
I promise to get the job done. 
</li>
          <li>
I promise to use whatever tools I need to, regardless of politics. 
</li>
          <li>
I promise to listen to the Closed Source and Open Source zealots equally, and then
dismiss them. 
</li>
          <li>
I promise to support, as long as I am able, any closed source applications I may release. 
</li>
          <li>
I promise to release open source any applications I can not, or will not, support. 
</li>
          <li>
I promise to learn as many languages and libraries as possible, regardless of politics. 
</li>
          <li>
I promise to engage with as many other programmers as possible, both in person and
online, in order to learn from them; regardless of politics. 
</li>
          <li>
I promise to not bash Microsoft nor GNU, nor others like them, everyone has a place
in our industry. 
</li>
          <li>
I promise to use both Windows and Linux, both have their uses. 
</li>
          <li>
I promise to ask questions when I don't know the answer, and answer questions when
I do. 
</li>
          <li>
I promise to learn from my mistakes, and to try to the first time. 
</li>
          <li>
I promise to listen to any idea, however crazy it may sound.</li>
        </ul>
        <p>
In many ways, this strikes me as fundamentally similar to the <a href="http://en.wikipedia.org/wiki/Hippocratic_Oath">Hippocratic
Oath</a> that all doctors must take as part of their acceptance into the ranks of
the medical profession. For most, this isn't just a bunch of words they recite as
entry criteria, this is something they firmly believe and adhere to, almost religiously.
It seems to me that our discipline could use something similar. Thus, do I swear by,
and encourage others to similarly adopt, the Oath of the Conscientious Programmer: 
</p>
        <blockquote>
          <p>
I swear to fulfill, to the best of my ability and judgment, this covenant: 
</p>
          <p>
I will respect the hard-won scientific gains of those programmers and researchers in
whose steps I walk, and gladly share such knowledge as is mine with those who are
to follow. That includes respect for both those who prefer to keep their work to themselves,
as well as those who seek improvement through the open community.
</p>
          <p>
I will apply, for the benefit of the customer, all measures [that] are required, avoiding
those twin traps of gold-plating and computing nihilism. 
</p>
          <p>
I will remember that there is humanity to programming as well as science, and
that warmth, sympathy, and understanding will far outweigh the programmer's editor
or the vendor's tool.
</p>
          <p>
I will not be ashamed to say "I know not," nor will I fail to call in my colleagues
when the skills of another are needed for a system's development, nor will I hold
in lower estimation those colleagues who ask of my opinions or skills.
</p>
          <p>
I will respect the privacy of my customers, for their problems are not disclosed to
me that the world may know. Most especially must I tread with care in matters of life
and death, or of customers' perceptions of the same. If it is given me to save a project
or a company, all thanks. But it may also be within my power to kill a project, for
the company's greater good; this awesome responsibility must be faced with great humbleness
and awareness of my own frailty. Above all, I must not play at God, and remain open
to others' ideas or opinions.
</p>
          <p>
I will remember that I do not create a report, or a data entry screen, but tools
for human beings, whose problems may affect the person's family and economic
stability. My responsibility includes these related problems, if I am to care adequately
for those who are technologically impaired.
</p>
          <p>
I will actively seek to avoid problems that are time-locked, for I know that software
written today will still be running long after I was told it would be replaced.
</p>
          <p>
I will remember that I remain a member of society, both our own and of the one surrounding
all of us, with special obligations to all my fellow human beings, those sound of
mind and body as well as the clueless.
</p>
          <p>
If I do not violate this oath, may I enjoy life and art, respected while I live and
remembered with affection thereafter. May I always act so as to preserve the finest
traditions of my calling and may I long experience the joy of the thanks and
praise from those who seek my help. 
</p>
        </blockquote>
        <p>
        </p>
        <p>
I, Ted Neward, so solemnly swear.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=17a2b01b-f398-4033-b914-d10418fb0a53" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Programming Promises (or, the Professional Programmer's Hippocratic Oath)</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,17a2b01b-f398-4033-b914-d10418fb0a53.aspx</guid>
      <link>http://blogs.tedneward.com/2007/01/27/Programming+Promises+Or+The+Professional+Programmers+Hippocratic+Oath.aspx</link>
      <pubDate>Sat, 27 Jan 2007 00:51:53 GMT</pubDate>
      <description>&lt;p&gt;
Michael.NET, apparently inspired by my "Check Your Politics At The Door" post, and
equally peeved at &lt;a href="http://blogs.msdn.com/reedme/archive/2007/01/10/is-your-daylight-going-to-be-saved-this-year.aspx"&gt;another
post on blogs.msdn.com&lt;/a&gt;, hit a note of pure inspiration when he created his list
of &lt;a href="http://michaeldotnet.blogspot.com/2007/01/programming-promises.html"&gt;"Programming
Promises"&lt;/a&gt;, which I repeat below:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I promise to get the job done. 
&lt;li&gt;
I promise to use whatever tools I need to, regardless of politics. 
&lt;li&gt;
I promise to listen to the Closed Source and Open Source zealots equally, and then
dismiss them. 
&lt;li&gt;
I promise to support, as long as I am able, any closed source applications I may release. 
&lt;li&gt;
I promise to release open source any applications I can not, or will not, support. 
&lt;li&gt;
I promise to learn as many languages and libraries as possible, regardless of politics. 
&lt;li&gt;
I promise to engage with as many other programmers as possible, both in person and
online, in order to learn from them; regardless of politics. 
&lt;li&gt;
I promise to not bash Microsoft nor GNU, nor others like them, everyone has a place
in our industry. 
&lt;li&gt;
I promise to use both Windows and Linux, both have their uses. 
&lt;li&gt;
I promise to ask questions when I don't know the answer, and answer questions when
I do. 
&lt;li&gt;
I promise to learn from my mistakes, and to try to the first time. 
&lt;li&gt;
I promise to listen to any idea, however crazy it may sound.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In many ways, this strikes me as fundamentally similar to the &lt;a href="http://en.wikipedia.org/wiki/Hippocratic_Oath"&gt;Hippocratic
Oath&lt;/a&gt; that all doctors must take as part of their acceptance into the ranks of
the medical profession. For most, this isn't just a bunch of words they recite as
entry criteria, this is something they firmly believe and adhere to, almost religiously.
It seems to me that our discipline could use something similar. Thus, do I swear by,
and encourage others to similarly adopt, the Oath of the Conscientious Programmer: &lt;blockquote&gt; 
&lt;p&gt;
I swear to fulfill, to the best of my ability and judgment, this covenant: 
&lt;/p&gt;
&lt;p&gt;
I will respect the hard-won scientific gains of those&amp;nbsp;programmers and researchers&amp;nbsp;in
whose steps I walk, and gladly share such knowledge as is mine with those who are
to follow. That includes respect for both those who prefer to keep their work to themselves,
as well as those who seek improvement through the open community.
&lt;/p&gt;
&lt;p&gt;
I will apply, for the benefit of the customer, all measures [that] are required, avoiding
those twin traps of&amp;nbsp;gold-plating and&amp;nbsp;computing nihilism. 
&lt;/p&gt;
&lt;p&gt;
I will remember that there is humanity to&amp;nbsp;programming as well as science, and
that warmth, sympathy, and understanding&amp;nbsp;will far&amp;nbsp;outweigh the programmer's&amp;nbsp;editor
or the vendor's tool.
&lt;/p&gt;
&lt;p&gt;
I will not be ashamed to say "I know not," nor will I fail to call in my colleagues
when the skills of another are needed for a system's development, nor will I hold
in lower estimation those colleagues who ask of my opinions or skills.
&lt;/p&gt;
&lt;p&gt;
I will respect the privacy of my customers, for their problems are not disclosed to
me that the world may know. Most especially must I tread with care in matters of life
and death, or of customers' perceptions of the same. If it is given me to save a project
or a company, all thanks. But it may also be within my power to kill a project, for
the company's greater good; this awesome responsibility must be faced with great humbleness
and awareness of my own frailty. Above all, I must not play at God, and remain open
to others' ideas or opinions.
&lt;/p&gt;
&lt;p&gt;
I will remember that I do not create a report, or a data entry screen, but&amp;nbsp;tools
for&amp;nbsp;human beings, whose&amp;nbsp;problems may affect the person's family and economic
stability. My responsibility includes these related problems, if I am to care adequately
for those who are technologically impaired.
&lt;/p&gt;
&lt;p&gt;
I will actively seek to avoid problems that are time-locked, for I know that software
written today will still be running long after I was told it would be replaced.
&lt;/p&gt;
&lt;p&gt;
I will remember that I remain a member of society, both our own and of the one surrounding
all of us, with special obligations to all my fellow human beings, those sound of
mind and body as well as the clueless.
&lt;/p&gt;
&lt;p&gt;
If I do not violate this oath, may I enjoy life and art, respected while I live and
remembered with affection thereafter. May I always act so as to preserve the finest
traditions of my calling and may I long experience the joy of&amp;nbsp;the thanks and
praise from those who seek my help. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I, Ted Neward,&amp;nbsp;so solemnly swear.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=17a2b01b-f398-4033-b914-d10418fb0a53" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,17a2b01b-f398-4033-b914-d10418fb0a53.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=8d24764a-f4c4-477e-b894-e3e1ec591a05</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,8d24764a-f4c4-477e-b894-e3e1ec591a05.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,8d24764a-f4c4-477e-b894-e3e1ec591a05.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8d24764a-f4c4-477e-b894-e3e1ec591a05</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
At a No Fluff Just Stuff conference not that long ago, Brian Goetz and I
were hosting a BOF on "Java Internals" (I think it was), and he tossed off a one-liner
that just floored me; I forget the exact phrasology, but it went something like:
</p>
        <blockquote>
          <p>
Remember that part about premature optimization being the root of all evil? He was
referring to programmer career lifecycle, not software development lifecycle. 
</p>
        </blockquote>
        <p>
... and the more I thought about it, the more I think Brian was absolutely right.
There are some projects, no matter how mature or immature, that I simply don't want
any developer on the team to "optimize", because I know what their optimizations will
be like: trying to avoid method calls because "they're expensive", trying to avoid
allocating objects because "it's more work for the GC", and completely ignoring network
traversals because they just don't realize the cost of going across the wire (or else
they think it really can't be all <em>that</em> bad). And then there are those programmers
I've met who are "optimizing" from the very get-go, because they work to avoid network
round-trips, or write SQL statements that don't need later optimization, simply because
they got it right the first time (where "right" means "correct" <em>and</em> "fast").
</p>
        <p>
It made me wish there was a "Developer Skill" setting I could throw on the compiler/IDE,
something that would pick up the following keystrokes...
</p>
        <blockquote>
          <p>
for (int x = 10; x &gt; 0; x--)
</p>
        </blockquote>
        <p>
... and immediately pop Clippy up (yes, the annoying paperclip from Office) who then
says, "It looks like you're doing a decrementing loop count as a premature optimization--would
you like me to help you out?" and promptly rewrites the code as...
</p>
        <blockquote>
          <p>
// QUIT BEING STUPID, STUPID!
</p>
          <p>
for (int x = 0; x &lt; 10; x++)
</p>
        </blockquote>
        <p>
... because the JVM and CLR actually better understand and therefore JIT better code
when your code is more clear than "hand-optimized".
</p>
        <p>
And before any of those thirty-year crusty old curmudgeons start to stand up and shout
"See? I <em>told</em> you young whippersnappers to start listening to me, we should
have wrote it all in COBOL and we would have <em>liked</em> it!", let me be very quick
to point out that years of experience in a developer are very subjective things--I've
met developers with less than two years experience that I would qualify as "senior",
and I've met developers with more than thirty that I wouldn't feel safe to code "Hello
World".
</p>
        <p>
Which, naturally, then brings up the logical question, "How do I know if I'm ready
to start optimizing?" For our answer, we turn to that ancient Master, Yoda:
</p>
        <blockquote>
          <p>
YODA: Yes, a Jedi's strength flows from the Force. But beware of the dark side. Anger,
fear, aggression; the dark side of the Force are they. Easily they flow, quick to
join you in a fight. If once you start down the dark path, forever will it dominate
your destiny, consume you it will, as it did Obi-Wan's apprentice. 
<br />
LUKE: Vader... Is the dark side stronger? 
<br />
YODA: No, no, no. Quicker, easier, more seductive. 
<br />
LUKE: But how am I to know the good side from the bad? 
<br />
YODA: You will know... when you are calm, at peace, passive. A Jedi uses the Force
for knowledge and defense, never for attack. 
</p>
        </blockquote>
        <p>
What he refers to, of course, is that most ancient of all powers, the Source. When
you feel calm, at peace, while you look through the Source, and aren't scrambling
through it looking for a quick and easy answer to your performance problem, then you
know you are channelling the Light Side of the Source. Remember, a Master uses the
Source for knowledge and defense, never for a hack.
</p>
        <p>
          <em>(Few people realize that Yoda, in addition to being a great Jedi Master, was
also a great Master of the Source. Go back and read your Empire Strikes Back if you
don't believe me--most of his teaching to Luke applies to programming just as much
as it does to righting evils in the galaxy.)</em>
        </p>
        <p>
All humor bits aside, the time to learn about performance and JIT compilation is <em>not</em> the
eleventh hour; spend some time cruisng the Hotspot FAQ and the various performance-tuning
books, and most importantly, if you see a result that doesn't jibe with your experience,
ask yourself "why".
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=8d24764a-f4c4-477e-b894-e3e1ec591a05" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>The Root of All Evil</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,8d24764a-f4c4-477e-b894-e3e1ec591a05.aspx</guid>
      <link>http://blogs.tedneward.com/2007/01/15/The+Root+Of+All+Evil.aspx</link>
      <pubDate>Mon, 15 Jan 2007 22:26:29 GMT</pubDate>
      <description>&lt;p&gt;
At&amp;nbsp;a No Fluff Just Stuff&amp;nbsp;conference not that long ago, Brian Goetz and I
were hosting a BOF on "Java Internals" (I think it was), and he tossed off a one-liner
that just floored me; I forget the exact phrasology, but it went something like:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
Remember that part about premature optimization being the root of all evil? He was
referring to programmer career lifecycle, not software development lifecycle. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
... and the more I thought about it, the more I think Brian was absolutely right.
There are some projects, no matter how mature or immature, that I simply don't want
any developer on the team to "optimize", because I know what their optimizations will
be like: trying to avoid method calls because "they're expensive", trying to avoid
allocating objects because "it's more work for the GC", and completely ignoring network
traversals because they just don't realize the cost of going across the wire (or else
they think it really can't be all &lt;em&gt;that&lt;/em&gt; bad). And then there are those programmers
I've met who are "optimizing" from the very get-go, because they work to avoid network
round-trips, or write SQL statements that don't need later optimization, simply because
they got it right the first time (where "right" means "correct" &lt;em&gt;and&lt;/em&gt; "fast").
&lt;/p&gt;
&lt;p&gt;
It made me wish there was a "Developer Skill" setting I could throw on the compiler/IDE,
something that would pick up the following keystrokes...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
for (int x = 10; x &amp;gt; 0; x--)
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
... and immediately pop Clippy up (yes, the annoying paperclip from Office) who then
says, "It looks like you're doing a decrementing loop count as a premature optimization--would
you like me to help you out?" and promptly rewrites the code as...
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
// QUIT BEING STUPID, STUPID!
&lt;/p&gt;
&lt;p&gt;
for (int x = 0; x &amp;lt; 10; x++)
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
... because the JVM and CLR actually better understand and therefore JIT better code
when your code is more clear than "hand-optimized".
&lt;/p&gt;
&lt;p&gt;
And before any of those thirty-year crusty old curmudgeons start to stand up and shout
"See? I &lt;em&gt;told&lt;/em&gt; you young whippersnappers to start listening to me, we should
have wrote it all in COBOL and we would have &lt;em&gt;liked&lt;/em&gt; it!", let me be very quick
to point out that years of experience in a developer are very subjective things--I've
met developers with less than two years experience that I would qualify as "senior",
and I've met developers with more than thirty that I wouldn't feel safe to code "Hello
World".
&lt;/p&gt;
&lt;p&gt;
Which, naturally, then brings up the logical question, "How do I know if I'm ready
to start optimizing?" For our answer, we turn to that ancient Master, Yoda:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
YODA: Yes, a Jedi's strength flows from the Force. But beware of the dark side. Anger,
fear, aggression; the dark side of the Force are they. Easily they flow, quick to
join you in a fight. If once you start down the dark path, forever will it dominate
your destiny, consume you it will, as it did Obi-Wan's apprentice. 
&lt;br&gt;
LUKE: Vader... Is the dark side stronger? 
&lt;br&gt;
YODA: No, no, no. Quicker, easier, more seductive. 
&lt;br&gt;
LUKE: But how am I to know the good side from the bad? 
&lt;br&gt;
YODA: You will know... when you are calm, at peace, passive. A Jedi uses the Force
for knowledge and defense, never for attack. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
What he refers to, of course, is that most ancient of all powers, the Source. When
you feel calm, at peace, while you look through the Source, and aren't scrambling
through it looking for a quick and easy answer to your performance problem, then you
know you are channelling the Light Side of the Source. Remember, a Master uses the
Source for knowledge and defense, never for a hack.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;(Few people realize that Yoda, in addition to being a great Jedi Master,&amp;nbsp;was
also a great Master of the Source. Go back and read your Empire Strikes Back if you
don't believe me--most of his teaching to Luke applies to programming just as much
as it does to righting evils in the galaxy.)&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
All humor bits aside, the time to learn about performance and JIT compilation is &lt;em&gt;not&lt;/em&gt; the
eleventh hour; spend some time cruisng the Hotspot FAQ and the various performance-tuning
books, and most importantly, if you see a result that doesn't jibe with your experience,
ask yourself "why".
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=8d24764a-f4c4-477e-b894-e3e1ec591a05" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,8d24764a-f4c4-477e-b894-e3e1ec591a05.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=e9611025-3a1d-45e6-bbf4-a2bb42f8c368</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,e9611025-3a1d-45e6-bbf4-a2bb42f8c368.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,e9611025-3a1d-45e6-bbf4-a2bb42f8c368.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e9611025-3a1d-45e6-bbf4-a2bb42f8c368</wfw:commentRss>
      <title>Welcome to Borders' Microsoft Days...</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,e9611025-3a1d-45e6-bbf4-a2bb42f8c368.aspx</guid>
      <link>http://blogs.tedneward.com/2006/11/16/Welcome+To+Borders+Microsoft+Days.aspx</link>
      <pubDate>Thu, 16 Nov 2006 13:13:54 GMT</pubDate>
      <description>&lt;p&gt;
If you're a Microsoftie and you're in the Redmond area this week, swing by the Borders
in the Redmond Town Center, where they're having their "Microsoft Days" experience--everything
a Microsoftie buys (whether for themselves or for their significant other, hint hint,
guys) is 15% off.
&lt;/p&gt;
&lt;p&gt;
Why the advertisement? Two reasons: one, because I love supporting the local causes,
and two, because I'm going to be there Friday night on a panel discussion with several
.NET notables, including Bill Vaughn (the original SQL Server curmudgeon), Harry "I
Got Your Architecture Right Here, Baby" Pierson, contributor to the "VB6 Migration
Guide" book Keith Pleas, and possibly (if we can drag them out of the p &amp; p "war room")
agile afficionados Peter Provost and Brad Wilson. We have no real idea what we're
going to talk about, but given the fact that we all like to express opinions regardless
of whether we have any real working knowledge on the subject, I expect it'll be an
interesting discussion....
&lt;/p&gt;
&lt;p&gt;
See your local Borders for details, and while you're there, drop into the cafe and
grab an espresso from the cheerful cafe staff... caffeine makes &lt;i&gt;everything&lt;/i&gt; better.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=e9611025-3a1d-45e6-bbf4-a2bb42f8c368" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,e9611025-3a1d-45e6-bbf4-a2bb42f8c368.aspx</comments>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=cabdeead-36a1-4b21-883f-91a21f89dea2</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,cabdeead-36a1-4b21-883f-91a21f89dea2.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,cabdeead-36a1-4b21-883f-91a21f89dea2.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=cabdeead-36a1-4b21-883f-91a21f89dea2</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So I'm in Borders tonight, looking around, and I happen to see one of APress's latest
titles, "Practical OCaml". Several things go through my mind at once: 
</p>
        <ol>
          <li>
WOW. OCaml.</li>
          <li>
A <i>book</i> on OCaml. Not even a "Programming Languages 101" textbook, but a practical
one, even.</li>
          <li>
Like, a book, copywrit <i>this year</i>, on OCaml.</li>
          <li>
Gotta buy it--not just because it's another of those Dead Languages I like to explore,
but because F# is a dead-ringer for OCaml, and I'm really interested in seeing where
we can go with F# these days.</li>
          <li>
Gotta buy it--not only for the F# tie-in, but because Scala comes from that same family
of languages, so there's probably some goodness on the Scala thought experiment, too.</li>
          <li>
You know, come to think of it, this is the third or fourth book on the "Non-Mainstream"
languages that APress has done recently. I thought maybe "Practical Common Lisp" was
a one-shot, and hey, "Programming Sudoku" isn't a language but definitely a fun title
nevertheless, but with "Practical OCaml", maybe Apress is quickly becoming like Morgan-Kaufman,
in that they're going after territories that aren't already flooding with ten thousand
"Me Too Ruby" books.</li>
          <li>
And it's not just limited to languages either, come to think of it: they just published
a <a href="http://www.db4objects.com" target="_blank">db4o</a> book, and even before
then they had the only Lego Mindstorms books for years.</li>
          <li>
Nice going, Gary.</li>
          <li>
Hmm.... Wonder if Gary is already has "Practical Scala" under contract...?</li>
        </ol>
Well done, APress. You had me worried there for a while, when you bought up all those
Wrox titles (most of which were unadulterated crap, IMHO), but you've restored my
faith in you once again. In fact, in my book, you have graduated to an entirely new
level of coolness.
<img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=cabdeead-36a1-4b21-883f-91a21f89dea2" /><br /><hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Kudos to APress...</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,cabdeead-36a1-4b21-883f-91a21f89dea2.aspx</guid>
      <link>http://blogs.tedneward.com/2006/11/03/Kudos+To+APress.aspx</link>
      <pubDate>Fri, 03 Nov 2006 06:22:41 GMT</pubDate>
      <description>&lt;p&gt;
So I'm in Borders tonight, looking around, and I happen to see one of APress's latest
titles, "Practical OCaml". Several things go through my mind at once: 
&lt;ol&gt;
&lt;li&gt;
WOW. OCaml.&lt;/li&gt;
&lt;li&gt;
A &lt;i&gt;book&lt;/i&gt; on OCaml. Not even a "Programming Languages 101" textbook, but a practical
one, even.&lt;/li&gt;
&lt;li&gt;
Like, a book, copywrit &lt;i&gt;this year&lt;/i&gt;, on OCaml.&lt;/li&gt;
&lt;li&gt;
Gotta buy it--not just because it's another of those Dead Languages I like to explore,
but because F# is a dead-ringer for OCaml, and I'm really interested in seeing where
we can go with F# these days.&lt;/li&gt;
&lt;li&gt;
Gotta buy it--not only for the F# tie-in, but because Scala comes from that same family
of languages, so there's probably some goodness on the Scala thought experiment, too.&lt;/li&gt;
&lt;li&gt;
You know, come to think of it, this is the third or fourth book on the "Non-Mainstream"
languages that APress has done recently. I thought maybe "Practical Common Lisp" was
a one-shot, and hey, "Programming Sudoku" isn't a language but definitely a fun title
nevertheless, but with "Practical OCaml", maybe Apress is quickly becoming like Morgan-Kaufman,
in that they're going after territories that aren't already flooding with ten thousand
"Me Too Ruby" books.&lt;/li&gt;
&lt;li&gt;
And it's not just limited to languages either, come to think of it: they just published
a &lt;a href="http://www.db4objects.com" target="_blank"&gt;db4o&lt;/a&gt; book, and even before
then they had the only Lego Mindstorms books for years.&lt;/li&gt;
&lt;li&gt;
Nice going, Gary.&lt;/li&gt;
&lt;li&gt;
Hmm.... Wonder if Gary is already has "Practical Scala" under contract...?&lt;/li&gt;
&lt;/ol&gt;
Well done, APress. You had me worried there for a while, when you bought up all those
Wrox titles (most of which were unadulterated crap, IMHO), but you've restored my
faith in you once again. In fact, in my book, you have graduated to an entirely new
level of coolness.&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=cabdeead-36a1-4b21-883f-91a21f89dea2" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,cabdeead-36a1-4b21-883f-91a21f89dea2.aspx</comments>
      <category>Reading</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=faec9013-cbab-4438-863b-4e155a76af8c</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,faec9013-cbab-4438-863b-4e155a76af8c.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,faec9013-cbab-4438-863b-4e155a76af8c.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=faec9013-cbab-4438-863b-4e155a76af8c</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently, while engaging in my other passion (international relations), I was reading
the latest issue of Foreign Affairs, and ran across an interesting essay regarding
the increasing outsourcing--or, the term they introduce which I prefer in this case,
"offshoring"--of technical work, and I found some interesting analysis there that
I think solidifies why I think programmers shouldn't fear offshoring, but instead
embrace it and ride the wave to a better life for both us and consumers. Permit me
to explain.
</p>
        <p>
The essay, entitled "Offshoring: The Next Industrial Revolution?" (by Alan S. Blinder),
opens with an interesting point, made subtly, that offshoring (or "offshore outsourcing"),
is really a natural economic consequence: 
</p>
        <blockquote>
          <p>
In February 2004, when N. Gregory Mankiw, a Harvard professor then serving as chairman
of the White House Council of Economic Advisers, caused a national uproar with a "textbook"
statement about trade, economists rushed to his defense. Mankiw was commenting on
the phenomenon that has been clumsily dubbed "offshoring" (or "offshore outsourcing")--the
migration of jobs, but not the people who perform them, from rich countries to poor
ones. Offshoring, Mankiw said, is only "the latest manifestation of the gains from
trade that economists have talked about at least since Adam Smith. ... More things
are tradable than were tradable in the past, and that's a good thing." Although Democratic
and Republican politicians alike excoriated Mankiw for his callous attitude toward
American jobs, economists lined up to support his claim that offshoring is simply
international business as usual.
</p>
          <p>
Their economics were basically sound: the well-known principle of comparative advantage
implies that trade in new kinds of products will bring overall improvements in productivity
and well-being. But Mankiw and his defenders underestimated both the importance of
offshoring and its disruptive effect on wealthy countries. Sometimes a quantitative
change is so large that it brings qualitative changes, as offshoring likely will.
We have so far barely seen the tip of the offshoring iceberg, the eventual dimensions
of which may be staggering.
</p>
        </blockquote> So far, you're not likely convinced that this is a good thing, and Blinder's
article doesn't really offer much reassurance as you go on: <blockquote><p>
To be sure, the furor over Mankiw's remark was grotesquely out of proportion to the
current importance of offshoring, which is still largely a prospective phenomenon.
Although there are no reliable national data, fragmentary studies indicate that well
under a million service-sector jobs have been lost to offshoring to date. (A million
seems impressive, but in the gigantic and rapidly churning U.S. labor market, a million
jobs is less than two weeks' worth of normal gross job losses.)<sup>1</sup> However,
constant improvements in technology and global communications will bring much more
offshoring of "impersonal services"--that is, services that can be delivered electronically
over long distances, with little or no degradation in quality.
</p><p>
That said, we should not view the coming wave of offshoring as an impending catastrophe.
Nor should we try to stop it. The normal gains from trade mean that the world as a
whole cannot lose from increases in productivity, and the United States and other
industrial countries have not only weathered but also benefited from comparable changes
in the past. But in order to do so again, the governments and societies of the developed
world must face up to the massive, complex, and multifaceted challenges that offshoring
will bring. National data systems, trade policies, educational systems, social welfare
programs, and politics must all adapt to new realities. Unfortunately, none of this
is happening now.
</p></blockquote> Phrases like "the world cannot lose from increases in productivity"
are hardly comforting to programmers who are concerned about their jobs, and hearing
"nor should we try to stop" the impending wave of offshoring is not what most programmers
want to hear. But there's an interesting analytical point that I think Blinder misses
about the software industry, and in order to make the point I have to walk through
his argument a bit to get to it. I'm not going to quote the entirety of the article
to you, don't worry, but I do have to walk through a few points to get there. Bear
with me, it's worth the ride, I think.
<h3>Why Offshoring
</h3><p>
Blinder first describes the basics of "comparative advantage" and why it's important
in this context: 
</p><blockquote><p>
Countries trade with one another for the same reasons that individuals, businesses
and regions do: to exploit their comparative advantages. Some advantages are "natural":
Texas and Saudi Arabia sit atop massive deposits of oil that are entirely lacking
in New York and Japan, and nature has conspired to make Hawaii a more attractive tourist
destination than Greenland. Ther eis not much anyone can do about such natural advantages.
</p><p>
But in modern economics, nature's whimsy is far less important than it was in the
past. Today, much comparative advantage derives from human effort rather than natural
conditions. The concentration of computer companies around Silicon Valley, for example,
has nothing to do with bountiful natural deposits of silicon; it has to do with Xerox's
fabled Palo Alto Research Center, the proximity of Stanford University, and the arrival
of two young men named Hewlett and Packard. Silicon Valley could have sprouted up
anywhere.
</p><p>
One important aspect of this modern reality is that patterns of man-made comparative
advantage can and do change over time. The economist Jagdish Bhagwait has labeled
this phenomenon "kaleidoscopic comparative advantage", and it is critical to understanding
offshoring. Once upon a time, the United Kingdom had a comparative advantage in textile
manufacturing. Then that advantage shifted to New England, and so jobs were moved
from the United Kingdom to the United States.<sup>2</sup> Then the comparative advantage
in textile manufacturing shifted once again--this time to the Carolinas--and jobs
migrated south within the United States.<sup>3</sup> Now the comparative advantage
in textile manufacturing resides in China and other low-wage countries, and what many
are wont to call "American jobs" have been moved there as a result.
</p><p>
Of course, not everything can be traded across long distances. At any point in time,
the available technology--especially in transportation and communications<sup>4</sup>--largely
determines what can be traded internationally and what cannot. Economic theorists
accordingly divide the world's goods and services into two bins: tradable and non-tradable.
Traditionally, any item that could be put in a box and shipped (roughly, manufactured
goods) was considered tradable, and anything that could not be put into a box (such
as services) or was too heavy to ship (such as houses) was thought of as nontradable.
But because technology is always improving and transportation is becoming cheaper
and easier, the boundary between what is tradable and what is not is constantly shifting.
And unlike comparative advantage, this change is not kaleidoscopic; it moves in only
one direction, with more and more items becoming tradable.
</p><p>
The old assumption that if you cannot put it in a box, you cannot trade it is thus
hopelessly obsolete. Because packets of digitized information play the role that boxes
used to play, many more services are now tradable and many more will surely become
so. In the future, and to a great extent already, the key distinction will no longer
be between things that can be put in a box and things that cannot. Rather, it will
be between services that can be delivered electronically and those that cannot.
</p></blockquote> Blinder goes on to describe the three industrial revolutions, the first
being the one we all learned in school, coming at the end of the 18th century and
marked by Adam Smith's <i>The Wealth of Nations</i> in 1776. It was a massive shift
in the economic system, as workers in industrializing countries migrated from farm
to factory. "It has been estimated that in 1810, 84 percent of the U.S. work force
was engaged in agriculture, compared to a paltry 3 percent in manufacturing. By 1960,
manufacturing's share had rised to almost 25 percent and agriculture's had dwindled
to just 8 percent. (Today, agriculture's share is under 2 percent.)" (This statistic
is important, by the way--keep it in mind as we go.) He goes on to point out the second
Revolution, the shift from manufacturing to services: <blockquote><p>
Then came the second Industrial Revolution, and jobs shifted once again--this time
away from manufacturing and toward services. The shift to services is still viewed
with alarm in the United States and other rich countries, where people bemoan rather
than welcome the resulting loss of manufacturing jobs<sup>5</sup>. But in reality,
new service-sector jobs have been created far more rapidly than old manufacturing
jobs have disappeared. In 1960, about 35 percent of nonagricultural workers in the
United States produced goods and 65 percent produced services. By 2004, only about
one-sixth of the United States' nonagricultural jobs were in goods-producing industries,
while five-sixths produced services. This trend is worldwide and continuing.
</p></blockquote> It's also important to point out that the years from 1960 to 2004 saw
a meteoric rise in the average standard of living for the United States, on a scale
that's basically unheard of in history. In fact, it was SUCH a huge rise that it became
an expectation that your children would live better than you did, and the inability
to keep that basic expectation in place (which has become a core part of the so-called
"American Dream") that creates major societal angst on the part of the United States
today. <blockquote><p>
We are now i nthe arly stages of a third Industrial Revolution--the information age.
The cheap and easy flow of information around the globe has vastly expanded the scope
of tradable services, and there is much more to come. Industrial revolutions are big
deals. And just like the previous two, the third Industrial Revolution will require
vast and usettling adjustments in the way Americans and residents of other developed
countries work, live, and educate their children.
</p></blockquote> Wow, nothing unsettles people more than statements like "the world you
know will cease to exist" and the like. But think about this for a second: despite
the basic "growing pains" that accompanied the transitions themselves, on just about
every quantifiable scale imaginable, we live a much better life today than our forebears
did just two hundred years ago, and orders of magnitude better than our forebears
did three hundred or more years ago (before the first Industrial Revolution). And
if you still hearken back to the days of the "American farmer" with some kind of nostalgia,
you never worked on a farm. Trust me on this. 
<h3>So what does this mean?
</h3><p>
But now we start to come to the interesting part of the article. 
</p><blockquote> But a bit of historical perspective should help temper fears of offshoring.
The first Industrial Revolution did not spell the end of agriculture, or even the
end of food production, in the United States. It jus tmean that a much smaller percentage
of Americans had to work on farms to feed the population. (By charming historical
coincidence, the actual number of Americans working on farms today--around 2 million--is
about what it was in 1810.) The main reason for this shift was not foreign trade,
but soaring farm productivity. And most important, the massive movement of labor off
the farms did not result in mass unemployment. Rather, it led to a large-scale reallocation
of labor to factories. </blockquote> Here's where we get to the "hole" in the argument.
Most readers will read that paragraph, do the simple per-capita math, and conclude
that thanks to soaring productivity gains in the programming industry (cite whatever
technology you want here--Ruby, objects, hardware gains, it really doesn't matter
what), the percentage of programmers in the country is about to fall into a black
hole. After all, if we can go from 84 percent of the population involved in agriculture
to less than 2% or so, thanks to that soaring productivity, why wouldn't it happen
here again?
<p>
Therein lies the flaw in the argument: <i>the amount of productivity required to achieve
the desired ends is constant in the agriculture industry, yet a constantly-changing
dynamic value in software</i>. This is also known as what I will posit as the Groves-Gates
Maxim: "What Andy Groves giveth, Bill Gates taketh away."
</p><h3>The Groves-Gates Maxim
</h3><p>
The argument here is simple: the process of growing food is a pretty constant one:
put seed in ground, wait until it comes up, then harvest the results and wait until
next year to start again. Although we might have numerous tools that can help make
it easier to put seeds into the ground, or harvesting the results, or even helping
to increase the yield of the crop when it comes up, the basic amount of productivity
required is pretty much constant. (My cousin, the FFA Farmer of the Year from some
years back and a seed hybrid researcher in Iowa might disagree with me, mind you.)
Compare this with the software industry: the basic differences between what's an acceptable
application to our users today, compared to even ten years ago, is an order of magnitude
different. Gains in productivity have not yielded the ability to build applications
faster and faster, but instead have created a situation where users and managers ask
more of us with each successive application.
</p><p>
The Groves-Gates Maxim is an example of that: every time Intel (where Andy Groves
is CEO) releases new hardware that accelerates the power and potential of what the
"average" computer (meaning, priced at somewhere between $1500-$2000) is capable of,
it seems that Microsoft (Mr. Gates' little firm) releases a new version of Windows
that sucks up that power by providing a spiffier user interface and "eye-candy" features,
be they useful/important or not. In other words, the more the hardware creates possibilities,
the more software is created to exploit and explore those possibilities. The additional
productivity is spent not in reducing the time required to produce the thing desired
(food in the case of agriculture, an operating system or other non-trivial program
in the case of software), but in the expansion of the functionality of the product.
</p><p>
This basic fact, the Groves-Gates Maxim, is what saves us from the bloody axe of forced
migration. Because what's expected of software is constantly on the same meteoric
rise as what productivity gains provide us, the need for programmer time remains pretty
close to constant. Now, once the desire for exponentially complicated features starts
to level off, the exponentially increasing gains in productivity will have the same
effect as they did in the agricultural industry, and we will start seeing a migration
of programmers into other, "personal service" industries (which are hard to offshore,
as opposed to "impersonal service" industries which can be easily shipped overseas).
</p><h3>Implications
</h3><p>
What does this mean for programmers? For starters, as Dave Thomas has already frequently
pointed out on NFJS panels, programmers need to start finding ways to make their service
a "personal service" position rather than an "impersonal service" one. Blinder points
out that the services industry is facing a split down the middle along this distinction,
and it's not necessarily a high-paying vs low-paying divide: 
</p><blockquote><p>
Many people blithely assume that the critical labor-market distinction is, and will
remain, between highly educated (or highly-skilled) people and less-educated (or less-skilled)
people--doctors versus call-center operators, for example. The supposed remedy for
the rich countries, accordingly, is more education and a general "upskilling" of the
work force. But this view may be mistaken. Other things being equal, education and
skills are, of course, good things; education yields higher returns in advanced societies,
and more schooling probably makes workers more flexible and more adaptable to change.
But the problem with relying on education as the remedy for potential job losses is
that "other things" are not remotely close to equal. The critical divide in the future
may instead be between those types are work that are easily deliverable through a
wire (or via wireless connections) with little or no diminution in quality and those
that are not. And this unconventional divide does not correspond well to traditional
distinctions between jobs that require high levels of education and jobs that do not.
</p><p>
A few disparate examples will illustrate just how complex--or, rather, how untraditional--the
new divide is. It is unlikely that the services of either taxi drivers or airline
pilots will ever be delivered electronically over long distances. The first is a "bad
job" with negligible educational requirements; the second is quite the reverse. On
the other hand, typing services (a low-skill job) and security analysis (a high-skill
job) are already being delivered electronically from India--albeit on a small scale
so far. Most physicians need not fear that their jobs will be moved offshore, but
radiologists are beginning to see this happening already. Police officers will not
be replaced by electronic monitoring, but some security guards will be. Janitors and
crane operators are probably immune to foreign competition; accountants and computer
programmers are not. In short, the dividing line between the jobs that produce services
that are suitable for electronic delivery (and are thus threatened by offshoring)
and those that do not does not correspond to traditional distinctions between high-end
and low-end work.
</p></blockquote> What's the implications here for somebody deep in our industry? Pay
close attention to Blinder's conclusion, that computer programmers are highly vulnerable
to foreign competition, based on the assumption that the product we deliver is easily
transferable across electronic media. But there is hope: <blockquote><p>
There is currently not even a vocabulary, much less any systematic data, to help society
come to grips with the coming labor-market reality. So here is some suggested nomenclature.
Service that cannot be delivered electronically, or that are notably inferior when
so delivered, have one essential characteristic: personal, face-to-face contact is
either imperative or highly desirable. Think of hte waiter who serves you dinner,
the doctor you gives you your annual physical, or the cop on the beat. Now think of
any of those tasks being performed by robots controlled from India--not quite the
same. But such face-to-face human contact is not necessary in the relationship you
have with the telephone operator who arranges your conference call or the clerk who
takes your airline reservation over the phone. He or she may be in India already.
</p><p>
The first group of tasks can be called personally-delivered services, or simply personal
services, and the second group of impersonally delivered services, or impersonal services.
In the brave new world of globalized electronic commerce, impersonal services have
more in common with manufactured goods that can be put in boxes than they do with
personal services. Thus, many impersonal services are destined to become tradable
and therefore vulnerable to offshoring. By contrast, most personal services have attributes
that cannot be transmitted through a wire. Some require face-to-face contact (child
care), some are inherently "high-risk" (nursing), some involve high levels of personal
trust (psychotherapy), and some depend on location-specific attributes (lobbying).
</p></blockquote> In other words, programmers that want to remain less vulnerable to foreign
competition need to find ways to stress the personal, face-to-face contact between
themselves and their clients, regardless of whether you are a full-time employee of
a company, a contractor, or a consultant (or part of a team of consultants) working
on a project for a client. Look for ways to maximize the four cardinalities he points
out: 
<ul><li><b>Face-to-face contact.</b> Agile methodologies demand that customers be easily accessible
in order to answer questions regarding implementation decisions or to resolve lack
of understanding of the requirements. Instead of demanding customers be present at
your site, you may find yourself in a better position if you put yourself close to
your customers.</li><li><b>"High-risk".</b> This is a bit harder to do with software projects--either the
project is inherently high-risk in its makeup (perhaps this is a mission-critical
app that the company depends on, such as the e-commerce portal for an online e-tailer),
or it's not. There's not much you can do to change this, unless you are politically
savvy enough to "sell" your project to a group that would make it mission-critical.</li><li><b>High levels of personal trust.</b> This is actually easier than you might think--trust
in this case refers not to the privileged nature of therapist-patient communication,
but in the credibility the organization has in you to carry out the work required.
One way to build this trust is to understand the business domain of the client, rather
than remaining aloof and "staying focused on the technology". This trust-based approach
is already present in a variety of forms outside our industry--regardless of the statistical
ratings that might be available, most people find that they have a favorite auto repair
mechanic or shop not for any quantitatively-measurable reason, but beceause the mechanic
"understands" them somehow. The best customer-service shops understand this, and have
done so for years. The restaurant that recognizes me as a regular after just a few
visits and has my Diet Coke ready for me at my favorite table is far likelier to get
my business on a regular basis than the one that never does. Learn your customers,
learn their concerns, learn their business model and business plan, and get yourself
into the habit of trying to predict what they might need next--not so you can build
it already, but so that you can demonstrate to them that you understand <i>them</i>,
and by extension, their needs.</li><li><b>Location-specific attributes.</b> Sometimes, the software being built is localized
to a particular geographic area, and simply being in that same area can yield significant
benefits, particularly when heroic efforts are called for. (It's very hard to flip
the reset switch on a server in Indiana from a console in India, for example.) 
</li></ul>
In general, what you're looking to do is demonstrate how your value to the company
arises out of more than just your technical skill, but also some other qualities that
you can provide in better and more valuable form than somebody in India (or China,
or Brazil, or across the country for that matter, wherever the offshoring goes). It's
not a guarantee that you might still be offshored--some management folks will just
see bottom-line dollars and not recognize the intangible value-add that high levels
of personal trust or locality provides--but it'll minimize it on the whole.
<p>
But even if this analysis doesn't make you feel a little more comfortable, consider
this: there are 1 billion people in China alone, and close to the same in India. Instead
of seeing them as potential competition, imagine what happens when the wages from
the offshored jobs start to create a demand for goods and services in those countries--if
you think the software market in the U.S. was hot a decade ago, where only a half-billion
(across both the U.S. and Europe) people were demanding software, now think about
it when four <i>times</i> that many start looking for it.
</p><hr /><h3>Footnotes
</h3><p><sup>1</sup> Which in of itself is an interesting statistic--it implies that offshoring
is far less prevalent than some of people worried about it believe it to be, including
me.
</p><p><sup>2</sup> Interesting bit of trivia--part of the reason that advantage shifted
was because the US stole (yes, stole, as in industrial espionage, one of the first
recorded cases of modern industrial espionage) the plans for modern textile machinery
from the UK. Remember that, next time you get upset at China's rather loose grip of
intellectual property law....
</p><p><sup>3</sup> Which, by the way, was a large part of the reason we fought the Civil
War (the "War Between the States" to some, or the "War of Northern Aggression" to
others)--the Carolinas depended on slave labor to pick their cotton cheaply, and couldn't
acquire Northern-made machinery cheaply to replace the slaves. Hence, for that (and
a lot of other reasons), war followed.
</p><p><sup>4</sup> An interesting argument--is there any real difference between transportation
and communications? One ships "stuff", the other "data", beyond that, is there any
difference?
</p><p><sup>5</sup> And, I'd like to point out, the shrinking environmental damage that can
arise from a manufacturing-based economy. Services rarely generate pollution, which
is part of the clash between the industrialized "Western" nations and the developing
"Southern" ones over environmental issues.
</p><h3>Resources
</h3><p><i>"Offshoring: The Next Industrial Revolutoin?"</i>, by Alan S. Blinder, Foreign
Affairs (March/April 2006), pp 113 - 128.
</p><img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=faec9013-cbab-4438-863b-4e155a76af8c" /><br /><hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Why programmers shouldn't fear offshoring</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,faec9013-cbab-4438-863b-4e155a76af8c.aspx</guid>
      <link>http://blogs.tedneward.com/2006/03/24/Why+Programmers+Shouldnt+Fear+Offshoring.aspx</link>
      <pubDate>Fri, 24 Mar 2006 09:43:00 GMT</pubDate>
      <description>&lt;p&gt;
Recently, while engaging in my other passion (international relations), I was reading
the latest issue of Foreign Affairs, and ran across an interesting essay regarding
the increasing outsourcing--or, the term they introduce which I prefer in this case,
"offshoring"--of technical work, and I found some interesting analysis there that
I think solidifies why I think programmers shouldn't fear offshoring, but instead
embrace it and ride the wave to a better life for both us and consumers. Permit me
to explain.
&lt;/p&gt;
&lt;p&gt;
The essay, entitled "Offshoring: The Next Industrial Revolution?" (by Alan S. Blinder),
opens with an interesting point, made subtly, that offshoring (or "offshore outsourcing"),
is really a natural economic consequence: &lt;blockquote&gt; 
&lt;p&gt;
In February 2004, when N. Gregory Mankiw, a Harvard professor then serving as chairman
of the White House Council of Economic Advisers, caused a national uproar with a "textbook"
statement about trade, economists rushed to his defense. Mankiw was commenting on
the phenomenon that has been clumsily dubbed "offshoring" (or "offshore outsourcing")--the
migration of jobs, but not the people who perform them, from rich countries to poor
ones. Offshoring, Mankiw said, is only "the latest manifestation of the gains from
trade that economists have talked about at least since Adam Smith. ... More things
are tradable than were tradable in the past, and that's a good thing." Although Democratic
and Republican politicians alike excoriated Mankiw for his callous attitude toward
American jobs, economists lined up to support his claim that offshoring is simply
international business as usual.
&lt;/p&gt;
&lt;p&gt;
Their economics were basically sound: the well-known principle of comparative advantage
implies that trade in new kinds of products will bring overall improvements in productivity
and well-being. But Mankiw and his defenders underestimated both the importance of
offshoring and its disruptive effect on wealthy countries. Sometimes a quantitative
change is so large that it brings qualitative changes, as offshoring likely will.
We have so far barely seen the tip of the offshoring iceberg, the eventual dimensions
of which may be staggering.
&lt;/p&gt;
&lt;/blockquote&gt; So far, you're not likely convinced that this is a good thing, and Blinder's
article doesn't really offer much reassurance as you go on: &lt;blockquote&gt; 
&lt;p&gt;
To be sure, the furor over Mankiw's remark was grotesquely out of proportion to the
current importance of offshoring, which is still largely a prospective phenomenon.
Although there are no reliable national data, fragmentary studies indicate that well
under a million service-sector jobs have been lost to offshoring to date. (A million
seems impressive, but in the gigantic and rapidly churning U.S. labor market, a million
jobs is less than two weeks' worth of normal gross job losses.)&lt;sup&gt;1&lt;/sup&gt; However,
constant improvements in technology and global communications will bring much more
offshoring of "impersonal services"--that is, services that can be delivered electronically
over long distances, with little or no degradation in quality.
&lt;/p&gt;
&lt;p&gt;
That said, we should not view the coming wave of offshoring as an impending catastrophe.
Nor should we try to stop it. The normal gains from trade mean that the world as a
whole cannot lose from increases in productivity, and the United States and other
industrial countries have not only weathered but also benefited from comparable changes
in the past. But in order to do so again, the governments and societies of the developed
world must face up to the massive, complex, and multifaceted challenges that offshoring
will bring. National data systems, trade policies, educational systems, social welfare
programs, and politics must all adapt to new realities. Unfortunately, none of this
is happening now.
&lt;/p&gt;
&lt;/blockquote&gt; Phrases like "the world cannot lose from increases in productivity"
are hardly comforting to programmers who are concerned about their jobs, and hearing
"nor should we try to stop" the impending wave of offshoring is not what most programmers
want to hear. But there's an interesting analytical point that I think Blinder misses
about the software industry, and in order to make the point I have to walk through
his argument a bit to get to it. I'm not going to quote the entirety of the article
to you, don't worry, but I do have to walk through a few points to get there. Bear
with me, it's worth the ride, I think.&gt;
&lt;h3&gt;Why Offshoring
&lt;/h3&gt;
&lt;p&gt;
Blinder first describes the basics of "comparative advantage" and why it's important
in this context: &lt;blockquote&gt; 
&lt;p&gt;
Countries trade with one another for the same reasons that individuals, businesses
and regions do: to exploit their comparative advantages. Some advantages are "natural":
Texas and Saudi Arabia sit atop massive deposits of oil that are entirely lacking
in New York and Japan, and nature has conspired to make Hawaii a more attractive tourist
destination than Greenland. Ther eis not much anyone can do about such natural advantages.
&lt;/p&gt;
&lt;p&gt;
But in modern economics, nature's whimsy is far less important than it was in the
past. Today, much comparative advantage derives from human effort rather than natural
conditions. The concentration of computer companies around Silicon Valley, for example,
has nothing to do with bountiful natural deposits of silicon; it has to do with Xerox's
fabled Palo Alto Research Center, the proximity of Stanford University, and the arrival
of two young men named Hewlett and Packard. Silicon Valley could have sprouted up
anywhere.
&lt;/p&gt;
&lt;p&gt;
One important aspect of this modern reality is that patterns of man-made comparative
advantage can and do change over time. The economist Jagdish Bhagwait has labeled
this phenomenon "kaleidoscopic comparative advantage", and it is critical to understanding
offshoring. Once upon a time, the United Kingdom had a comparative advantage in textile
manufacturing. Then that advantage shifted to New England, and so jobs were moved
from the United Kingdom to the United States.&lt;sup&gt;2&lt;/sup&gt; Then the comparative advantage
in textile manufacturing shifted once again--this time to the Carolinas--and jobs
migrated south within the United States.&lt;sup&gt;3&lt;/sup&gt; Now the comparative advantage
in textile manufacturing resides in China and other low-wage countries, and what many
are wont to call "American jobs" have been moved there as a result.
&lt;/p&gt;
&lt;p&gt;
Of course, not everything can be traded across long distances. At any point in time,
the available technology--especially in transportation and communications&lt;sup&gt;4&lt;/sup&gt;--largely
determines what can be traded internationally and what cannot. Economic theorists
accordingly divide the world's goods and services into two bins: tradable and non-tradable.
Traditionally, any item that could be put in a box and shipped (roughly, manufactured
goods) was considered tradable, and anything that could not be put into a box (such
as services) or was too heavy to ship (such as houses) was thought of as nontradable.
But because technology is always improving and transportation is becoming cheaper
and easier, the boundary between what is tradable and what is not is constantly shifting.
And unlike comparative advantage, this change is not kaleidoscopic; it moves in only
one direction, with more and more items becoming tradable.
&lt;/p&gt;
&lt;p&gt;
The old assumption that if you cannot put it in a box, you cannot trade it is thus
hopelessly obsolete. Because packets of digitized information play the role that boxes
used to play, many more services are now tradable and many more will surely become
so. In the future, and to a great extent already, the key distinction will no longer
be between things that can be put in a box and things that cannot. Rather, it will
be between services that can be delivered electronically and those that cannot.
&lt;/p&gt;
&lt;/blockquote&gt; Blinder goes on to describe the three industrial revolutions, the first
being the one we all learned in school, coming at the end of the 18th century and
marked by Adam Smith's &lt;i&gt;The Wealth of Nations&lt;/i&gt; in 1776. It was a massive shift
in the economic system, as workers in industrializing countries migrated from farm
to factory. "It has been estimated that in 1810, 84 percent of the U.S. work force
was engaged in agriculture, compared to a paltry 3 percent in manufacturing. By 1960,
manufacturing's share had rised to almost 25 percent and agriculture's had dwindled
to just 8 percent. (Today, agriculture's share is under 2 percent.)" (This statistic
is important, by the way--keep it in mind as we go.) He goes on to point out the second
Revolution, the shift from manufacturing to services: &lt;blockquote&gt; 
&lt;p&gt;
Then came the second Industrial Revolution, and jobs shifted once again--this time
away from manufacturing and toward services. The shift to services is still viewed
with alarm in the United States and other rich countries, where people bemoan rather
than welcome the resulting loss of manufacturing jobs&lt;sup&gt;5&lt;/sup&gt;. But in reality,
new service-sector jobs have been created far more rapidly than old manufacturing
jobs have disappeared. In 1960, about 35 percent of nonagricultural workers in the
United States produced goods and 65 percent produced services. By 2004, only about
one-sixth of the United States' nonagricultural jobs were in goods-producing industries,
while five-sixths produced services. This trend is worldwide and continuing.
&lt;/p&gt;
&lt;/blockquote&gt; It's also important to point out that the years from 1960 to 2004 saw
a meteoric rise in the average standard of living for the United States, on a scale
that's basically unheard of in history. In fact, it was SUCH a huge rise that it became
an expectation that your children would live better than you did, and the inability
to keep that basic expectation in place (which has become a core part of the so-called
"American Dream") that creates major societal angst on the part of the United States
today. &lt;blockquote&gt; 
&lt;p&gt;
We are now i nthe arly stages of a third Industrial Revolution--the information age.
The cheap and easy flow of information around the globe has vastly expanded the scope
of tradable services, and there is much more to come. Industrial revolutions are big
deals. And just like the previous two, the third Industrial Revolution will require
vast and usettling adjustments in the way Americans and residents of other developed
countries work, live, and educate their children.
&lt;/p&gt;
&lt;/blockquote&gt; Wow, nothing unsettles people more than statements like "the world you
know will cease to exist" and the like. But think about this for a second: despite
the basic "growing pains" that accompanied the transitions themselves, on just about
every quantifiable scale imaginable, we live a much better life today than our forebears
did just two hundred years ago, and orders of magnitude better than our forebears
did three hundred or more years ago (before the first Industrial Revolution). And
if you still hearken back to the days of the "American farmer" with some kind of nostalgia,
you never worked on a farm. Trust me on this. &gt;
&lt;h3&gt;So what does this mean?
&lt;/h3&gt;
&lt;p&gt;
But now we start to come to the interesting part of the article. &lt;blockquote&gt; But
a bit of historical perspective should help temper fears of offshoring. The first
Industrial Revolution did not spell the end of agriculture, or even the end of food
production, in the United States. It jus tmean that a much smaller percentage of Americans
had to work on farms to feed the population. (By charming historical coincidence,
the actual number of Americans working on farms today--around 2 million--is about
what it was in 1810.) The main reason for this shift was not foreign trade, but soaring
farm productivity. And most important, the massive movement of labor off the farms
did not result in mass unemployment. Rather, it led to a large-scale reallocation
of labor to factories. &lt;/blockquote&gt; Here's where we get to the "hole" in the argument.
Most readers will read that paragraph, do the simple per-capita math, and conclude
that thanks to soaring productivity gains in the programming industry (cite whatever
technology you want here--Ruby, objects, hardware gains, it really doesn't matter
what), the percentage of programmers in the country is about to fall into a black
hole. After all, if we can go from 84 percent of the population involved in agriculture
to less than 2% or so, thanks to that soaring productivity, why wouldn't it happen
here again?&gt;
&lt;p&gt;
Therein lies the flaw in the argument: &lt;i&gt;the amount of productivity required to achieve
the desired ends is constant in the agriculture industry, yet a constantly-changing
dynamic value in software&lt;/i&gt;. This is also known as what I will posit as the Groves-Gates
Maxim: "What Andy Groves giveth, Bill Gates taketh away."
&lt;/p&gt;
&lt;h3&gt;The Groves-Gates Maxim
&lt;/h3&gt;
&lt;p&gt;
The argument here is simple: the process of growing food is a pretty constant one:
put seed in ground, wait until it comes up, then harvest the results and wait until
next year to start again. Although we might have numerous tools that can help make
it easier to put seeds into the ground, or harvesting the results, or even helping
to increase the yield of the crop when it comes up, the basic amount of productivity
required is pretty much constant. (My cousin, the FFA Farmer of the Year from some
years back and a seed hybrid researcher in Iowa might disagree with me, mind you.)
Compare this with the software industry: the basic differences between what's an acceptable
application to our users today, compared to even ten years ago, is an order of magnitude
different. Gains in productivity have not yielded the ability to build applications
faster and faster, but instead have created a situation where users and managers ask
more of us with each successive application.
&lt;/p&gt;
&lt;p&gt;
The Groves-Gates Maxim is an example of that: every time Intel (where Andy Groves
is CEO) releases new hardware that accelerates the power and potential of what the
"average" computer (meaning, priced at somewhere between $1500-$2000) is capable of,
it seems that Microsoft (Mr. Gates' little firm) releases a new version of Windows
that sucks up that power by providing a spiffier user interface and "eye-candy" features,
be they useful/important or not. In other words, the more the hardware creates possibilities,
the more software is created to exploit and explore those possibilities. The additional
productivity is spent not in reducing the time required to produce the thing desired
(food in the case of agriculture, an operating system or other non-trivial program
in the case of software), but in the expansion of the functionality of the product.
&lt;/p&gt;
&lt;p&gt;
This basic fact, the Groves-Gates Maxim, is what saves us from the bloody axe of forced
migration. Because what's expected of software is constantly on the same meteoric
rise as what productivity gains provide us, the need for programmer time remains pretty
close to constant. Now, once the desire for exponentially complicated features starts
to level off, the exponentially increasing gains in productivity will have the same
effect as they did in the agricultural industry, and we will start seeing a migration
of programmers into other, "personal service" industries (which are hard to offshore,
as opposed to "impersonal service" industries which can be easily shipped overseas).
&lt;/p&gt;
&lt;h3&gt;Implications
&lt;/h3&gt;
&lt;p&gt;
What does this mean for programmers? For starters, as Dave Thomas has already frequently
pointed out on NFJS panels, programmers need to start finding ways to make their service
a "personal service" position rather than an "impersonal service" one. Blinder points
out that the services industry is facing a split down the middle along this distinction,
and it's not necessarily a high-paying vs low-paying divide: &lt;blockquote&gt; 
&lt;p&gt;
Many people blithely assume that the critical labor-market distinction is, and will
remain, between highly educated (or highly-skilled) people and less-educated (or less-skilled)
people--doctors versus call-center operators, for example. The supposed remedy for
the rich countries, accordingly, is more education and a general "upskilling" of the
work force. But this view may be mistaken. Other things being equal, education and
skills are, of course, good things; education yields higher returns in advanced societies,
and more schooling probably makes workers more flexible and more adaptable to change.
But the problem with relying on education as the remedy for potential job losses is
that "other things" are not remotely close to equal. The critical divide in the future
may instead be between those types are work that are easily deliverable through a
wire (or via wireless connections) with little or no diminution in quality and those
that are not. And this unconventional divide does not correspond well to traditional
distinctions between jobs that require high levels of education and jobs that do not.
&lt;/p&gt;
&lt;p&gt;
A few disparate examples will illustrate just how complex--or, rather, how untraditional--the
new divide is. It is unlikely that the services of either taxi drivers or airline
pilots will ever be delivered electronically over long distances. The first is a "bad
job" with negligible educational requirements; the second is quite the reverse. On
the other hand, typing services (a low-skill job) and security analysis (a high-skill
job) are already being delivered electronically from India--albeit on a small scale
so far. Most physicians need not fear that their jobs will be moved offshore, but
radiologists are beginning to see this happening already. Police officers will not
be replaced by electronic monitoring, but some security guards will be. Janitors and
crane operators are probably immune to foreign competition; accountants and computer
programmers are not. In short, the dividing line between the jobs that produce services
that are suitable for electronic delivery (and are thus threatened by offshoring)
and those that do not does not correspond to traditional distinctions between high-end
and low-end work.
&lt;/p&gt;
&lt;/blockquote&gt; What's the implications here for somebody deep in our industry? Pay
close attention to Blinder's conclusion, that computer programmers are highly vulnerable
to foreign competition, based on the assumption that the product we deliver is easily
transferable across electronic media. But there is hope: &lt;blockquote&gt; 
&lt;p&gt;
There is currently not even a vocabulary, much less any systematic data, to help society
come to grips with the coming labor-market reality. So here is some suggested nomenclature.
Service that cannot be delivered electronically, or that are notably inferior when
so delivered, have one essential characteristic: personal, face-to-face contact is
either imperative or highly desirable. Think of hte waiter who serves you dinner,
the doctor you gives you your annual physical, or the cop on the beat. Now think of
any of those tasks being performed by robots controlled from India--not quite the
same. But such face-to-face human contact is not necessary in the relationship you
have with the telephone operator who arranges your conference call or the clerk who
takes your airline reservation over the phone. He or she may be in India already.
&lt;/p&gt;
&lt;p&gt;
The first group of tasks can be called personally-delivered services, or simply personal
services, and the second group of impersonally delivered services, or impersonal services.
In the brave new world of globalized electronic commerce, impersonal services have
more in common with manufactured goods that can be put in boxes than they do with
personal services. Thus, many impersonal services are destined to become tradable
and therefore vulnerable to offshoring. By contrast, most personal services have attributes
that cannot be transmitted through a wire. Some require face-to-face contact (child
care), some are inherently "high-risk" (nursing), some involve high levels of personal
trust (psychotherapy), and some depend on location-specific attributes (lobbying).
&lt;/p&gt;
&lt;/blockquote&gt; In other words, programmers that want to remain less vulnerable to foreign
competition need to find ways to stress the personal, face-to-face contact between
themselves and their clients, regardless of whether you are a full-time employee of
a company, a contractor, or a consultant (or part of a team of consultants) working
on a project for a client. Look for ways to maximize the four cardinalities he points
out: 
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;Face-to-face contact.&lt;/b&gt; Agile methodologies demand that customers be easily accessible
in order to answer questions regarding implementation decisions or to resolve lack
of understanding of the requirements. Instead of demanding customers be present at
your site, you may find yourself in a better position if you put yourself close to
your customers.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;"High-risk".&lt;/b&gt; This is a bit harder to do with software projects--either the
project is inherently high-risk in its makeup (perhaps this is a mission-critical
app that the company depends on, such as the e-commerce portal for an online e-tailer),
or it's not. There's not much you can do to change this, unless you are politically
savvy enough to "sell" your project to a group that would make it mission-critical.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;High levels of personal trust.&lt;/b&gt; This is actually easier than you might think--trust
in this case refers not to the privileged nature of therapist-patient communication,
but in the credibility the organization has in you to carry out the work required.
One way to build this trust is to understand the business domain of the client, rather
than remaining aloof and "staying focused on the technology". This trust-based approach
is already present in a variety of forms outside our industry--regardless of the statistical
ratings that might be available, most people find that they have a favorite auto repair
mechanic or shop not for any quantitatively-measurable reason, but beceause the mechanic
"understands" them somehow. The best customer-service shops understand this, and have
done so for years. The restaurant that recognizes me as a regular after just a few
visits and has my Diet Coke ready for me at my favorite table is far likelier to get
my business on a regular basis than the one that never does. Learn your customers,
learn their concerns, learn their business model and business plan, and get yourself
into the habit of trying to predict what they might need next--not so you can build
it already, but so that you can demonstrate to them that you understand &lt;i&gt;them&lt;/i&gt;,
and by extension, their needs.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;Location-specific attributes.&lt;/b&gt; Sometimes, the software being built is localized
to a particular geographic area, and simply being in that same area can yield significant
benefits, particularly when heroic efforts are called for. (It's very hard to flip
the reset switch on a server in Indiana from a console in India, for example.) 
&lt;/li&gt;
&lt;/ul&gt;
In general, what you're looking to do is demonstrate how your value to the company
arises out of more than just your technical skill, but also some other qualities that
you can provide in better and more valuable form than somebody in India (or China,
or Brazil, or across the country for that matter, wherever the offshoring goes). It's
not a guarantee that you might still be offshored--some management folks will just
see bottom-line dollars and not recognize the intangible value-add that high levels
of personal trust or locality provides--but it'll minimize it on the whole.&gt;
&lt;p&gt;
But even if this analysis doesn't make you feel a little more comfortable, consider
this: there are 1 billion people in China alone, and close to the same in India. Instead
of seeing them as potential competition, imagine what happens when the wages from
the offshored jobs start to create a demand for goods and services in those countries--if
you think the software market in the U.S. was hot a decade ago, where only a half-billion
(across both the U.S. and Europe) people were demanding software, now think about
it when four &lt;i&gt;times&lt;/i&gt; that many start looking for it.
&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Footnotes
&lt;/h3&gt;
&lt;p&gt;
&lt;sup&gt;1&lt;/sup&gt; Which in of itself is an interesting statistic--it implies that offshoring
is far less prevalent than some of people worried about it believe it to be, including
me.
&lt;/p&gt;
&lt;p&gt;
&lt;sup&gt;2&lt;/sup&gt; Interesting bit of trivia--part of the reason that advantage shifted
was because the US stole (yes, stole, as in industrial espionage, one of the first
recorded cases of modern industrial espionage) the plans for modern textile machinery
from the UK. Remember that, next time you get upset at China's rather loose grip of
intellectual property law....
&lt;/p&gt;
&lt;p&gt;
&lt;sup&gt;3&lt;/sup&gt; Which, by the way, was a large part of the reason we fought the Civil
War (the "War Between the States" to some, or the "War of Northern Aggression" to
others)--the Carolinas depended on slave labor to pick their cotton cheaply, and couldn't
acquire Northern-made machinery cheaply to replace the slaves. Hence, for that (and
a lot of other reasons), war followed.
&lt;/p&gt;
&lt;p&gt;
&lt;sup&gt;4&lt;/sup&gt; An interesting argument--is there any real difference between transportation
and communications? One ships "stuff", the other "data", beyond that, is there any
difference?
&lt;/p&gt;
&lt;p&gt;
&lt;sup&gt;5&lt;/sup&gt; And, I'd like to point out, the shrinking environmental damage that can
arise from a manufacturing-based economy. Services rarely generate pollution, which
is part of the clash between the industrialized "Western" nations and the developing
"Southern" ones over environmental issues.
&lt;/p&gt;
&lt;h3&gt;Resources
&lt;/h3&gt;
&lt;p&gt;
&lt;i&gt;"Offshoring: The Next Industrial Revolutoin?"&lt;/i&gt;, by Alan S. Blinder, Foreign
Affairs (March/April 2006), pp 113 - 128.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=faec9013-cbab-4438-863b-4e155a76af8c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,faec9013-cbab-4438-863b-4e155a76af8c.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=3541bd6b-c6c5-4d58-9481-92e37925cbed</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,3541bd6b-c6c5-4d58-9481-92e37925cbed.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,3541bd6b-c6c5-4d58-9481-92e37925cbed.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=3541bd6b-c6c5-4d58-9481-92e37925cbed</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
My father, whom I've often used (somewhat disparagingly...) as an example of the classic
"power user", meaning "he-thinks-he-knows-what-he's-doing-but-usually-ends-up-needing-me-to-fix-his-computer-afterwards"
(sorry Dad, but it's true...), often forwards me emails that turn out to be one hoax
or another. This time, though, he found a winner--he sent me <a href="http://www.snopes.com/crime/fraud/juryduty.asp" target="_blank">this
article</a>, warning against the latest caller identity scam: this time, they call
claiming to be clerks of the local court, threatening that because the victim hasn't
reported in for jury duty, arrest warrants have been issued. When the victim protests,
the "clerk" asks for confidential info to verify the records. Highly credible attack,
if you ask me.
</p>
        <p>
Net result (from the article): 
</p>
        <ul>
          <li>
            <font size="3">Court workers will not telephone to say you've missed jury duty or
that they are assembling juries and need to pre-screen those who might be selected
to serve on them, so dismiss as fraudulent phones call of this nature. About the only
time you would hear by telephone (rather than by mail) about anything having to do
with jury service would be <u>after</u> you have mailed back your completed questionnaire,
and even then only rarely. </font>
          </li>
          <li>
            <font size="3">Do not give out bank account, social security, or credit card numbers
over the phone if you didn't initiate the call, whether it be to someone trying to
sell you something or to someone who claims to be from a bank or government department.
If such callers insist upon "verifying" such information with you, have them read
the data to you from their notes, with you saying yea or nay to it rather than the
other way around. </font>
          </li>
          <li>
            <font size="3">Examine your credit card and bank account statements every month, keeping
an eye peeled for unauthorized charges. Immediately challenge items you did not approve. </font>
          </li>
        </ul>
In other words, don't assume the voice on the other end of the phone is actually who
they say they are. I think it's fairly reasonable to ask to speak to a supervisor
or ask for a phone # to call back on after you've "assembled the appropriate records"
and what-not. Who knows? Some scammers might even be dumb enough to give you the phone
# back, and then it's "Hello, Police...?", baby....
<p>
Remember, it's always acceptable to ask for verification of THEIR identity if they're
asking for confidential information. And most credible organizations are taking great
pains to not ask for that information over the phone in the first place. Practice
the same discretion over the phone that you would over IM or email; the phone can
be just as anonymous as the Internet can.
</p><img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=3541bd6b-c6c5-4d58-9481-92e37925cbed" /><br /><hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Don't fall prey to the latest social engineering attack</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,3541bd6b-c6c5-4d58-9481-92e37925cbed.aspx</guid>
      <link>http://blogs.tedneward.com/2006/03/04/Dont+Fall+Prey+To+The+Latest+Social+Engineering+Attack.aspx</link>
      <pubDate>Sat, 04 Mar 2006 06:00:57 GMT</pubDate>
      <description>&lt;p&gt;
My father, whom I've often used (somewhat disparagingly...) as an example of the classic
"power user", meaning "he-thinks-he-knows-what-he's-doing-but-usually-ends-up-needing-me-to-fix-his-computer-afterwards"
(sorry Dad, but it's true...), often forwards me emails that turn out to be one hoax
or another. This time, though, he found a winner--he sent me &lt;a href="http://www.snopes.com/crime/fraud/juryduty.asp" target="_blank"&gt;this
article&lt;/a&gt;, warning against the latest caller identity scam: this time, they call
claiming to be clerks of the local court, threatening that because the victim hasn't
reported in for jury duty, arrest warrants have been issued. When the victim protests,
the "clerk" asks for confidential info to verify the records. Highly credible attack,
if you ask me.
&lt;/p&gt;
&lt;p&gt;
Net result (from the article): 
&lt;ul&gt;
&lt;li&gt;
&lt;font size=3&gt;Court workers will not telephone to say you've missed jury duty or that
they are assembling juries and need to pre-screen those who might be selected to serve
on them, so dismiss as fraudulent phones call of this nature. About the only time
you would hear by telephone (rather than by mail) about anything having to do with
jury service would be &lt;u&gt;after&lt;/u&gt; you have mailed back your completed questionnaire,
and even then only rarely. &lt;/font&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;font size=3&gt;Do not give out bank account, social security, or credit card numbers
over the phone if you didn't initiate the call, whether it be to someone trying to
sell you something or to someone who claims to be from a bank or government department.
If such callers insist upon "verifying" such information with you, have them read
the data to you from their notes, with you saying yea or nay to it rather than the
other way around. &lt;/font&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;font size=3&gt;Examine your credit card and bank account statements every month, keeping
an eye peeled for unauthorized charges. Immediately challenge items you did not approve. &lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
In other words, don't assume the voice on the other end of the phone is actually who
they say they are. I think it's fairly reasonable to ask to speak to a supervisor
or ask for a phone # to call back on after you've "assembled the appropriate records"
and what-not. Who knows? Some scammers might even be dumb enough to give you the phone
# back, and then it's "Hello, Police...?", baby....&gt;
&lt;p&gt;
Remember, it's always acceptable to ask for verification of THEIR identity if they're
asking for confidential information. And most credible organizations are taking great
pains to not ask for that information over the phone in the first place. Practice
the same discretion over the phone that you would over IM or email; the phone can
be just as anonymous as the Internet can.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=3541bd6b-c6c5-4d58-9481-92e37925cbed" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,3541bd6b-c6c5-4d58-9481-92e37925cbed.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49</wfw:commentRss>
      <slash:comments>97</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In keeping with the tradition, I'm suggesting the following will take place for 2006: 
</p>
        <ol>
          <li>
The hype surrounding Ajax will slowly fade, as people come to realize that there's
really nothing new here, just that DHTML is cool again. As <a href="http://www.almaer.com/blog/archives/001122.html" target="_blank">Dion
points out</a>, Ajax will become a toolbox that you use in web development without
thinking that "I am doing Ajax". Just as we don't think about "doing HTML" vs "doing
DOM".</li>
          <li>
The release of EJB 3 may actually start people thinking about EJB again, but hopefully
this time in a more pragmatic and less hype-driven fashion. (Yes, EJB does have its
place in the world, folks--it's just a much smaller place than most of the EJB vendors
and book authors wanted it to be.)</li>
          <li>
Vista will be slipped to 2007, despite Microsoft's best efforts. In the meantime,
however, WinFX (which is effectively .NET 3.0) will ship, and people will discover
that Workflow (WWF) is by far the more interesting of the WPF/WCF/WWF triplet. Notice
that I don't say "powerful" or "important", but "interesting".</li>
          <li>
Scripting languages will hit their peak interest period in 2006; Ruby conversions
will be at its apogee, and its likely that somewhere in the latter half of 2006 we'll
hear about the first major Ruby project failure, most likely from a large consulting
firm that tries to duplicate the success of Ruby's evangelists (Dave Thomas, David
Geary, and the other Rubyists I know of from the NFJS tour) by throwing Ruby at a
project without really understanding it. In other words, same story, different technology,
same result. By 2007 the Ruby Backlash will have begun.</li>
          <li>
Interest in building languages that somehow bridge the gap between static and dynamic
languages will start to grow, most likely beginning with E4X, the variant of ECMAScript
(Javascript to those of you unfamiliar with the standards) that integrates XML into
the language.</li>
          <li>
Java developers will start gaining interest in building rich Java apps again. (Freely
admit, this is a long shot, but the work being done by the Swing researchers at Sun,
not least of which is Romain Guy, will by the middle of 2006 probably be ready for
prime-time consumption, and there's some seriously interesting sh*t in there.)</li>
          <li>
Somebody at Microsoft starts seriously hammering on the CLR team to support continuations.
Talk emerges about supporting it in the 4.0 (post-WinFX) release.</li>
          <li>
            <i>Effective Java</i> (2nd Edition) will ship. (Hardly a difficult prediction to make--Josh
said as much in the Javapolis interview I did with him and Neal Gafter.)</li>
          <li>
            <i>Effective .NET</i> will ship.</li>
          <li>
            <i>Pragmatic XML Services</i> will ship.</li>
          <li>
JDK 6 will ship, and a good chunk of the Java community self-proclaimed experts and
cognoscente will claim it sucks.</li>
          <li>
Java developers will seriously begin to talk about what changes we want/need to Java
for JDK 7 ("Dolphin"). Lots of ideas will be put forth. Hopefully most will be shot
down. With any luck, Joshua Bloch and Neal Gafter will still be involved in the process,
and will keep tight rein on the more... aggressive... ideas and turn them into useful
things that won't break the spirit of the platform.</li>
          <li>
My long-shot hope, rather than prediction, for 2006: Sun comes to realize that the
Java platform isn't about the <i>language</i>, but the <i>platform</i>, and begin
to give serious credence and hope behind a multi-linguistic JVM ecosystem.</li>
          <li>
My long-shot dream: JBoss goes out of business, the JBoss source code goes back to
being maintained by developers whose principal interest is in maintaining open-source
projects rather than making money, and it all gets folded together with what the Geronimo
folks are doing. In other words, the open-source community stops the infighting and
starts pulling oars in the same direction at the same time. For once.</li>
        </ol>
Flame away....
<img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49" /><br /><hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>2006 Tech Predictions</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49.aspx</guid>
      <link>http://blogs.tedneward.com/2006/01/01/2006+Tech+Predictions.aspx</link>
      <pubDate>Sun, 01 Jan 2006 08:25:56 GMT</pubDate>
      <description>&lt;p&gt;
In keeping with the tradition, I'm suggesting the following will take place for 2006: 
&lt;ol&gt;
&lt;li&gt;
The hype surrounding Ajax will slowly fade, as people come to realize that there's
really nothing new here, just that DHTML is cool again. As &lt;a href="http://www.almaer.com/blog/archives/001122.html" target="_blank"&gt;Dion
points out&lt;/a&gt;, Ajax will become a toolbox that you use in web development without
thinking that "I am doing Ajax". Just as we don't think about "doing HTML" vs "doing
DOM".&lt;/li&gt;
&lt;li&gt;
The release of EJB 3 may actually start people thinking about EJB again, but hopefully
this time in a more pragmatic and less hype-driven fashion. (Yes, EJB does have its
place in the world, folks--it's just a much smaller place than most of the EJB vendors
and book authors wanted it to be.)&lt;/li&gt;
&lt;li&gt;
Vista will be slipped to 2007, despite Microsoft's best efforts. In the meantime,
however, WinFX (which is effectively .NET 3.0) will ship, and people will discover
that Workflow (WWF) is by far the more interesting of the WPF/WCF/WWF triplet. Notice
that I don't say "powerful" or "important", but "interesting".&lt;/li&gt;
&lt;li&gt;
Scripting languages will hit their peak interest period in 2006; Ruby conversions
will be at its apogee, and its likely that somewhere in the latter half of 2006 we'll
hear about the first major Ruby project failure, most likely from a large consulting
firm that tries to duplicate the success of Ruby's evangelists (Dave Thomas, David
Geary, and the other Rubyists I know of from the NFJS tour) by throwing Ruby at a
project without really understanding it. In other words, same story, different technology,
same result. By 2007 the Ruby Backlash will have begun.&lt;/li&gt;
&lt;li&gt;
Interest in building languages that somehow bridge the gap between static and dynamic
languages will start to grow, most likely beginning with E4X, the variant of ECMAScript
(Javascript to those of you unfamiliar with the standards) that integrates XML into
the language.&lt;/li&gt;
&lt;li&gt;
Java developers will start gaining interest in building rich Java apps again. (Freely
admit, this is a long shot, but the work being done by the Swing researchers at Sun,
not least of which is Romain Guy, will by the middle of 2006 probably be ready for
prime-time consumption, and there's some seriously interesting sh*t in there.)&lt;/li&gt;
&lt;li&gt;
Somebody at Microsoft starts seriously hammering on the CLR team to support continuations.
Talk emerges about supporting it in the 4.0 (post-WinFX) release.&lt;/li&gt;
&lt;li&gt;
&lt;i&gt;Effective Java&lt;/i&gt; (2nd Edition) will ship. (Hardly a difficult prediction to make--Josh
said as much in the Javapolis interview I did with him and Neal Gafter.)&lt;/li&gt;
&lt;li&gt;
&lt;i&gt;Effective .NET&lt;/i&gt; will ship.&lt;/li&gt;
&lt;li&gt;
&lt;i&gt;Pragmatic XML Services&lt;/i&gt; will ship.&lt;/li&gt;
&lt;li&gt;
JDK 6 will ship, and a good chunk of the Java community self-proclaimed experts and
cognoscente will claim it sucks.&lt;/li&gt;
&lt;li&gt;
Java developers will seriously begin to talk about what changes we want/need to Java
for JDK 7 ("Dolphin"). Lots of ideas will be put forth. Hopefully most will be shot
down. With any luck, Joshua Bloch and Neal Gafter will still be involved in the process,
and will keep tight rein on the more... aggressive... ideas and turn them into useful
things that won't break the spirit of the platform.&lt;/li&gt;
&lt;li&gt;
My long-shot hope, rather than prediction, for 2006: Sun comes to realize that the
Java platform isn't about the &lt;i&gt;language&lt;/i&gt;, but the &lt;i&gt;platform&lt;/i&gt;, and begin
to give serious credence and hope behind a multi-linguistic JVM ecosystem.&lt;/li&gt;
&lt;li&gt;
My long-shot dream: JBoss goes out of business, the JBoss source code goes back to
being maintained by developers whose principal interest is in maintaining open-source
projects rather than making money, and it all gets folded together with what the Geronimo
folks are doing. In other words, the open-source community stops the infighting and
starts pulling oars in the same direction at the same time. For once.&lt;/li&gt;
&lt;/ol&gt;
Flame away....&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,771ab347-c3ba-4a0a-b5ed-cd4dd7b73d49.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Conferences</category>
      <category>Development Processes</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=54f13989-ed2a-45cd-b87d-a79b9b187283</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,54f13989-ed2a-45cd-b87d-a79b9b187283.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,54f13989-ed2a-45cd-b87d-a79b9b187283.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=54f13989-ed2a-45cd-b87d-a79b9b187283</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For those of you who don't know this, the <a href="http://www.neward.net">blog at
the root of the neward.net domain</a> is one that my wife maintains--all I can claim
is inspiration, providing her with plenty of material to write about, like the stories
about her kids and her uber-geek husband. A regular Muse, that's me. :-)
</p>
        <p>
The reason I bring it up here, in this channel, is that I've had more speaker-friends
of mine come to me and tell me that while they like reading my blog, they <em>love</em> reading
Charlotte's blog. What's more, <em>their</em> spouses find Charlotte's blog to be
highly entertaining, probably because they can relate so deeply to Charlotte's dilemma
as Geek Widow. So if you've got a girlfriend or wife who'd like to check out a non-technical
blog, or if you're looking for a bit more insight into the personal world of Ted,
or maybe you just want to read a pretty good writer, check out <a href="http://www.neward.net">The
Neward Family Weblog</a>.
</p>
        <p>
G'wan--the geek blogs will still be waiting for you when you get back. ;-)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=54f13989-ed2a-45cd-b87d-a79b9b187283" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Props to my wife</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,54f13989-ed2a-45cd-b87d-a79b9b187283.aspx</guid>
      <link>http://blogs.tedneward.com/2005/09/29/Props+To+My+Wife.aspx</link>
      <pubDate>Thu, 29 Sep 2005 07:48:13 GMT</pubDate>
      <description>&lt;p&gt;
For those of you who don't know this, the &lt;a href="http://www.neward.net"&gt;blog at
the root of the neward.net domain&lt;/a&gt; is one that my wife maintains--all I can claim
is inspiration, providing her with plenty of material to write about, like the stories
about her kids and her uber-geek husband. A regular Muse, that's me. :-)
&lt;/p&gt;
&lt;p&gt;
The reason I bring it up here, in this channel, is that I've had more speaker-friends
of mine come to me and tell me that while they like reading my blog, they &lt;em&gt;love&lt;/em&gt; reading
Charlotte's blog. What's more, &lt;em&gt;their&lt;/em&gt; spouses find Charlotte's blog to be
highly entertaining, probably because they can relate so deeply to Charlotte's dilemma
as Geek Widow. So if you've got a girlfriend or wife who'd like to check out a non-technical
blog, or if you're looking for a bit more insight into the personal world of Ted,
or maybe you just want to read a pretty good writer, check out &lt;a href="http://www.neward.net"&gt;The
Neward Family Weblog&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
G'wan--the geek blogs will still be waiting for you when you get back. ;-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=54f13989-ed2a-45cd-b87d-a79b9b187283" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,54f13989-ed2a-45cd-b87d-a79b9b187283.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>Ruby</category>
      <category>Windows</category>
      <category>XML Services</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=b14202c6-4399-4dd5-ad45-cc712838f1c8</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,b14202c6-4399-4dd5-ad45-cc712838f1c8.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,b14202c6-4399-4dd5-ad45-cc712838f1c8.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=b14202c6-4399-4dd5-ad45-cc712838f1c8</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The title is a bit scary, but "Rootkits", by Hoglund and Butler, really is anything
but. Oh, I'll admit, their talk of how rootkits--programs that hackers install onto
your system that patch into kernel space and thus are undetectable by any user-mode
program--is scary, but then they walk you through the process of developing your own
rootkit, thereby giving you some awareness of what a rootkit looks like, acts like,
and therefore can be discovered and killed.
</p>
        <p>
Well, in theory, anyway.
</p>
        <p>
To put it bluntly, I'm <i>loving</i> this book, if only because it's the first book
I've run into that really sits down and explains how to write a device driver, not
to mention how to communicate with it from user mode. I've been fascinated with that
very idea for many years now, but all the DDK-based material I've found--books, articles,
etc--all assumed that you wanted to write some variation on the SCSI driver or something,
implying that you care more about device-level details than you do in writing kernel-mode
code. Rootkits, of course, are nothing like real device drivers, but a lot more like
what I'm interested in exploring and displaying (that is, getting at program information
from within the kernel--very useful for debugging scenarios, for example).
</p>
        <p>
By page 30, you've already written and compiled a basic kernel driver, and by page
39 they've discussed how you can have your driver expose itself as a special file
handle for communication with user-mode code. Pages 40-43 talk about loading the driver
from code, and 43-46, how to extract your driver from a user-mode program as a resource,
suitable for loading (because, of course, rootkits need to piggyback on top of other
code to install themselves, stealthy-like). Pages 46-47 talk about how to make your
rootkit survive reboot, and that concludes Chapter Two.
</p>
        <p>
Wow. I'm in love.
</p>
        <p>
It's not the be-all-end-all book on drivers, nor is it going to necessarily turn you
into a l33t hax0r, but if you ever wanted to get started understanding how rootkits
work (so as to start looking for them on your own system in order to remove them)
or just use that knowledge for more benign purposes (such as trying to figure out
NT internals so you can more efficiently--and automatedly--debug services or server-style
programs), this book rocks. Easily a classic, and one I'm probably going to carry
around with me as much as I do Hoglund's other book (with Gary McGraw, one of my favorite
security authors), "Exploiting Software".
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=b14202c6-4399-4dd5-ad45-cc712838f1c8" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Book Review: Rootkits, by Hoglund/Butler</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,b14202c6-4399-4dd5-ad45-cc712838f1c8.aspx</guid>
      <link>http://blogs.tedneward.com/2005/09/14/Book+Review+Rootkits+By+HoglundButler.aspx</link>
      <pubDate>Wed, 14 Sep 2005 21:47:21 GMT</pubDate>
      <description>&lt;p&gt;
The title is a bit scary, but "Rootkits", by Hoglund and Butler, really is anything
but. Oh, I'll admit, their talk of how rootkits--programs that hackers install onto
your system that patch into kernel space and thus are undetectable by any user-mode
program--is scary, but then they walk you through the process of developing your own
rootkit, thereby giving you some awareness of what a rootkit looks like, acts like,
and therefore can be discovered and killed.
&lt;/p&gt;
&lt;p&gt;
Well, in theory, anyway.
&lt;/p&gt;
&lt;p&gt;
To put it bluntly, I'm &lt;i&gt;loving&lt;/i&gt; this book, if only because it's the first book
I've run into that really sits down and explains how to write a device driver, not
to mention how to communicate with it from user mode. I've been fascinated with that
very idea for many years now, but all the DDK-based material I've found--books, articles,
etc--all assumed that you wanted to write some variation on the SCSI driver or something,
implying that you care more about device-level details than you do in writing kernel-mode
code. Rootkits, of course, are nothing like real device drivers, but a lot more like
what I'm interested in exploring and displaying (that is, getting at program information
from within the kernel--very useful for debugging scenarios, for example).
&lt;/p&gt;
&lt;p&gt;
By page 30, you've already written and compiled a basic kernel driver, and by page
39 they've discussed how you can have your driver expose itself as a special file
handle for communication with user-mode code. Pages 40-43 talk about loading the driver
from code, and 43-46, how to extract your driver from a user-mode program as a resource,
suitable for loading (because, of course, rootkits need to piggyback on top of other
code to install themselves, stealthy-like). Pages 46-47 talk about how to make your
rootkit survive reboot, and that concludes Chapter Two.
&lt;/p&gt;
&lt;p&gt;
Wow. I'm in love.
&lt;/p&gt;
&lt;p&gt;
It's not the be-all-end-all book on drivers, nor is it going to necessarily turn you
into a l33t hax0r, but if you ever wanted to get started understanding how rootkits
work (so as to start looking for them on your own system in order to remove them)
or just use that knowledge for more benign purposes (such as trying to figure out
NT internals so you can more efficiently--and automatedly--debug services or server-style
programs), this book rocks. Easily a classic, and one I'm probably going to carry
around with me as much as I do Hoglund's other book (with Gary McGraw, one of my favorite
security authors), "Exploiting Software".
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=b14202c6-4399-4dd5-ad45-cc712838f1c8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,b14202c6-4399-4dd5-ad45-cc712838f1c8.aspx</comments>
      <category>Reading</category>
      <category>.NET</category>
      <category>C++</category>
      <category>Java/J2EE</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=ec9d467c-2b90-41e7-9dbe-288b9a83eb52</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,ec9d467c-2b90-41e7-9dbe-288b9a83eb52.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,ec9d467c-2b90-41e7-9dbe-288b9a83eb52.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=ec9d467c-2b90-41e7-9dbe-288b9a83eb52</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A bit late, but I realized after I posted the Recommended Reading List that I forgot
to add Mike Clark's <i>Pragmatic Project Automation</i>, a great resource for ideas
on how to automate various parts of your build cycle... and, more importantly, why
this is such a necessary step. Although nominally a Java book, there's really nothing
in here that couldn't also be adopted to a .NET environment, particularly now that
$g(NAnt) and $g(MSBuild) are prevalent in .NET development shops all over the planet.
</p>
        <p>
Most importantly, Mike indirectly points out a great lesson when he uses $g(Groovy)
to script $g(Ant) builds: that you don't have to stick with just the tools that are
given to you. Automation can take place in a variety of ways, and scripting languages
(like Groovy, or Ruby, or Python...) are a great way to drive lower-level tools like
Ant. <a href="http://www.relevancellc.com/blogs" target="_blank">Stu Halloway</a> has
begun talking about the same concept when he discusses "Unit Testing with Jython"
at the $NFJS shows. Coming from the .NET space? Then think about $g(IronPython), or
even the JScript implementation that comes out of the box with Visual Studio.
</p>
        <p>
All in all, a highly-recommended read.
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=ec9d467c-2b90-41e7-9dbe-288b9a83eb52" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Book Review: Pragmatic Project Automation</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,ec9d467c-2b90-41e7-9dbe-288b9a83eb52.aspx</guid>
      <link>http://blogs.tedneward.com/2005/08/22/Book+Review+Pragmatic+Project+Automation.aspx</link>
      <pubDate>Mon, 22 Aug 2005 10:31:19 GMT</pubDate>
      <description>&lt;p&gt;
A bit late, but I realized after I posted the Recommended Reading List that I forgot
to add Mike Clark's &lt;i&gt;Pragmatic Project Automation&lt;/i&gt;, a great resource for ideas
on how to automate various parts of your build cycle... and, more importantly, why
this is such a necessary step. Although nominally a Java book, there's really nothing
in here that couldn't also be adopted to a .NET environment, particularly now that
$g(NAnt) and $g(MSBuild) are prevalent in .NET development shops all over the planet.
&lt;/p&gt;
&lt;p&gt;
Most importantly, Mike indirectly points out a great lesson when he uses $g(Groovy)
to script $g(Ant) builds: that you don't have to stick with just the tools that are
given to you. Automation can take place in a variety of ways, and scripting languages
(like Groovy, or Ruby, or Python...) are a great way to drive lower-level tools like
Ant. &lt;a href="http://www.relevancellc.com/blogs" target="_blank"&gt;Stu Halloway&lt;/a&gt; has
begun talking about the same concept when he discusses "Unit Testing with Jython"
at the $NFJS shows. Coming from the .NET space? Then think about $g(IronPython), or
even the JScript implementation that comes out of the box with Visual Studio.
&lt;/p&gt;
&lt;p&gt;
All in all, a highly-recommended read.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=ec9d467c-2b90-41e7-9dbe-288b9a83eb52" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,ec9d467c-2b90-41e7-9dbe-288b9a83eb52.aspx</comments>
      <category>Reading</category>
      <category>.NET</category>
      <category>Java/J2EE</category>
    </item>
    <item>
      <trackback:ping>http://blogs.tedneward.com/Trackback.aspx?guid=624cf311-956e-4ac0-a381-c71666057db6</trackback:ping>
      <pingback:server>http://blogs.tedneward.com/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.tedneward.com/PermaLink,guid,624cf311-956e-4ac0-a381-c71666057db6.aspx</pingback:target>
      <dc:creator>Ted Neward</dc:creator>
      <wfw:comment>http://blogs.tedneward.com/CommentView,guid,624cf311-956e-4ac0-a381-c71666057db6.aspx</wfw:comment>
      <wfw:commentRss>http://blogs.tedneward.com/SyndicationService.asmx/GetEntryCommentsRss?guid=624cf311-956e-4ac0-a381-c71666057db6</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
(Note that this is a reprint, so to speak, of <a href="http://www.neward.net/ted/weblog/index.jsp?date=20030205#1044497180661">the
same entry</a> on the old weblog, but I wanted to kick the Reading category off with
a reprise of what I'd written before.)
</p>
        <p>
I've been asked on several occasions (from students, from blog readers, and from a
few friends who happen to be in the business) what my recommended reading list is.
I've never really put one together formally, instead just sort of relying on impromptu
answers that cover some of my absolute favorites and a few that just leap to mind
at the time. 
</p>
        <p>
Enough is enough. It's time for me to post my recommended reading list, broken out
for both Java and .NET programmers. (If you're of one camp, it's still worth reading
books on the other camp's list, since the two environments really are Evil Twin Brothers.)
And I've left my own books off the list, because I think it's rather forward of me
to recommend them as recommended reading--naturally, I think they're all good, but
whether or not they make the cut of "recommended reading" is for others to weigh in
on, not me (at least not here). (<b>Update</b>: several commenters on the old blog
suggested it was not out of line to recommend my own books if I thought they were
worth recommending, so I added them.)
</p>
        <p>
          <b>Java Recommended Reading list</b>: 
</p>
        <ul>
          <li>
            <i>Effective Java</i> by Bloch. 
</li>
          <li>
            <em>Java Puzzlers</em> by Bloch and Gafter. You think you know the Java language?
Try it. (Makes for great interview question fodder, and for that reason alone practicing
Java programmers should have a copy on their shelf.) 
</li>
          <li>
            <em>Effective Enterprise Java</em> by Neward. (Had to do it. :-) ) 
</li>
          <li>
            <i>Concurrent Programming in Java (2nd Ed)</i> by Lea. 
</li>
          <li>
Either <em>Inside Java2 Platform Security</em> by Gong or <i>Java Security (2nd Ed)</i> by
Oaks. 
</li>
          <li>
            <i>Component Development for the Java Platform</i> by Halloway. 
</li>
          <li>
            <i>Inside the Java2 Virtual Machine</i> by Venners. 
</li>
          <li>
            <i>Java Development with Ant</i> by Hatcher and Loughran. 
</li>
          <li>
Either <i>Java RMI</i> by Grosso or <i>java.rmi</i> by McNiff and Pitt. 
</li>
          <li>
            <em>Server-Based Java Programming</em> by Neward. For obvious reasons. :-) Actually,
I still think this book is applicable if you want to understand the reasons why an
app server makes some of the restrictions that it does, but I freely admit that I
don't think I did a great job of "closing the loop" on that and finishing the book
with a good summary that ties everything together. Ah, retrospect.... 
</li>
          <li>
            <i>Servlets and Java Server Pages</i> by Jones and Falkner, possibly <em>Java Servlet
Programming (2nd Ed)</em> by Hunter, if you aren't planning to use JSP. (Jason's legendary
bias against JSP, right or wrong, puts him somewhat out of tune with what a majority
of Java web-client shops are doing. That said, it's a great servlets resource.) 
</li>
          <li>
            <em>AspectJ in Action</em> by Laddad. AspectJ represents the best of the AOP solutions,
IMHO, and this book represents the best of the AspectJ books available.</li>
        </ul>
        <p>
        </p>
        <p>
          <b>.NET Recommended Reading list</b>: 
</p>
        <ul>
          <li>
            <em>C# In a Nutshell (2nd Ed)</em> by Drayton, Albahari, and Neward. For obvious reasons.
:-) 
</li>
          <li>
            <i>Advanced .NET Remoting</i> by Rammer. 
</li>
          <li>
            <i>Essential ADO.NET</i> by Beauchemin. 
</li>
          <li>
            <i>Inside Microsoft .NET IL Assembler</i> by Lidin. 
</li>
          <li>
            <em>SSCLI Essentials</em> by Stutz, Neward and Shilling. For obvious reasons. :-) 
</li>
          <li>
            <i>Debugging Applications</i> by Robbins. 
</li>
          <li>
            <i>Inside Windows 2000</i> by Russinovich and Solomon. 
</li>
          <li>
            <i>Essential COM</i> by Box. <i>(Yes, I mean Essential COM and not his more recent
Essential .NET book. The first chapter of Essential COM is probably the best well-written
technical prose I've ever read in my life, and everybody who ever wanted to write
reusable components in C++ needs to read it to understand why C++ failed so miserably
at that goal. Once you've seen that, you're ready to understand why components are
so powerful and so necessary.)</i></li>
          <li>
            <em>Essential ASP.NET</em> by Onion. 
</li>
          <li>
            <em>Expert C# Business Objects</em> or <em>Expert VB Business Objects</em>, by
Lhotka. Not an intro to business objects, per se, but a great read on how to build
a framework. Pay close attention to how Rocky handles distribution; he avoids the
canonical problems of "distributed objects" by not distributing objects, but instead
making them <em>mobile objects</em>. 
</li>
          <li>
            <i>The Common Language Infrastructure Annotated Standard</i> by Miller 
</li>
          <li>
            <i>Programming in the .NET Environment</i> by Watkins et al. 
</li>
        </ul>
        <p>
        </p>
        <p>
          <b>C++ Recommended Reading list</b>:<br /><i>(For the twelve people left in the world still writing C++ code, anyway.)</i></p>
        <ul>
          <li>
            <i>The C++ Programming Language (3rd Ed)</i> by Stroustrup. 
</li>
          <li>
            <em>Effective C++ (1st, 2nd </em>or<em> 3rd Ed)</em> by Meyers. 
</li>
          <li>
            <i>More Effective C++</i> by Meyers. 
</li>
          <li>
            <i>Effective STL</i> by Meyers. 
</li>
          <li>
            <em>Inside the C++ Object Model</em> by Lippmann. You don't know how C++ works until
you've read this cover to cover. Twice. And peeked at everything under the hood with
a debugger, just to make sure Stan's right. Seriously.</li>
        </ul>
        <p>
        </p>
        <p>
          <b>Database/Relational Storage Recommended Reading list:</b>
        </p>
        <ul>
          <li>
            <em>Introduction to Database Systems</em>
            <em>(8th Ed)</em> by Date. Heavy on theory,
and for that reason alone should be read at least once by any practicing programmer
who thinks they understand SQL and the relational world. 
</li>
          <li>
            <em>SQL for Smarties (3rd Ed)</em> by Celko. Actually, you need to own just about
everything by Celko. 
</li>
          <li>
            <i>Principles of Transaction Processing</i> by Bernstein and Newcomer. 
</li>
          <li>
            <i>Transaction Processing: Concepts and Techniques</i> by Gray and Reuter. What to
read when you're done with the Bernstein and Newcomer book and still want to know
more about the Zen of Transactional Processing. 
</li>
        </ul>
        <p>
          <b>Security-related Recommended Reading list</b>: 
</p>
        <ul>
          <li>
            <i>Secrets and Lies</i> by Schneier. 
</li>
          <li>
Either <i>Cryptography Decrypted</i> by (can't remember the name offhand), <i>Practical
Cryptography</i> by Schneier and Ferguson, or <i>Applied Cryptography (2nd Ed)</i> by
Schneier. The first is a lightweight introduction to the subject, the second is a
more detailed introspection, the third required reading for anybody who wants to be
a security wonk. 
</li>
          <li>
            <i>The Code Book</i> by Singh. 
</li>
          <li>
            <em>Hacking Exposed (5th Ed)</em>, by McClure, et al. 
</li>
          <li>
            <em>Exploting Software</em>, by Hogland and McGraw. The most fun book in the list,
if you ask me. 
</li>
          <li>
            <em>Reversing</em> by Eilam. Who says unmanaged code is "safe from reverse-engineering"? 
</li>
          <li>
            <em>The Art of Deception</em>, by Mitnick</li>
        </ul>
        <p>
          <strong>Operating System/Platform Reading list:</strong>
        </p>
        <ul>
          <li>
            <em>Windows Internals</em> (4th Ed) by Russinovich and Solomon. Actually, any of the
last three editions (2nd, 3rd, 4th) is awesome, so look for 3rd Ed in a bargain bin
and pick up a great bargain. 
</li>
          <li>
            <em>Operating Systems</em> (2nd Ed) by Tanenbaum. The original "Minix" book. Taught
me the basics of how an O/S works, and the basic concepts are still applicable to
this day.</li>
        </ul>
        <p>
          <b>Platform-agnostic Recommended Reading list</b>: 
</p>
        <ul>
          <li>
            <i>Design and Evolution of C++</i> by Stroustrup. It's fascinating hearing how a language
develops over time, and what was behind some of the decisions in the features of the
language. For example, why did multiple inheritance come before templates or RTTI?
Not because it was more important, but because Stroustrup wanted to tackle MI first
because he wasn't sure if or how he could do it. He describes that as a great regret,
that he didn't do templates first. 
</li>
          <li>
            <i>Component Software (2nd Ed)</i> by Szyperski. 
</li>
          <li>
            <i>Rapid Development</i> by McConnell. Read this before you read any of the Extreme
Programming books, because this book describes a whole taxonomy of what I think a
lot of people are reaching for in agile and other methodologies. 
</li>
          <li>
            <i>The Inmates Are Running the Asylum</i> by Cooper. 
</li>
          <li>
            <i>The Invisible Computer</i> by Norman. 
</li>
          <li>
            <i>Refactoring</i> by Fowler. 
</li>
          <li>
            <i>Design Patterns</i> by Gamma, Helm, Johnson and Vlissides. 
</li>
          <li>
            <i>Pattern Oriented Software Architecture, Vol 1</i> by Stal et al. 
</li>
          <li>
            <i>Pattern Oriented Software Architecture, Vol 2</i> by Schmidt et al. 
</li>
          <li>
            <i>Patterns of Enterprise Application Architecture</i> by Fowler. 
</li>
          <li>
            <i>Enterprise Integration Patterns</i> by Hohpe and Woolf. Excellent discussion of
message-based architecture. I personally think the title is something of a misnomer,
but it's understandable since message-oriented communication is the easiest means
by which to integrate heterogeneous systems. 
</li>
        </ul>
        <p>
        </p>
        <p>
Note that this list will undergo revision and change as I continue, so I'm putting
a link to this item in the links column in the sidepanel to the left for easy reference.
For now, I'm just listing them out as they come to mind. Later, if I have time, I'll
put paragraphs of detail behind them so you can know why I recommend them. (Updated
on 13 Feb 2002) (Moved to this weblog 21 Aug 2005) (Updated 5 Oct 2005)
</p>
        <p>
Look for more book reviews and recommended reading via the "Reading" category on the
RSS feeds. There's undoubtedly titles that I'm forgetting, and I'm hoping I'll get
around to blogging more about the books I'm reading now, including Ruby (the Pickaxe
book and the Rails book), some other titles in the Pragmatic series, as well as some
WS-*-related stuff and (of course) the staple C# and Java stuff. And of course I'm
always open to suggestions of new and interesting technical titles to peruse....
</p>
        <p>
          <hr />
        </p>
        <p>
        </p>
        <p>
Update: <a href="http://www.stevenrockarts.com/blog/PermaLink,guid,e054ed79-8291-4e83-adf1-cfc1fb1f72dc.aspx">Steven
Rockarts</a> pointed out that Rocky's "Objects" books are missing, as is Fritz's Essential
ASP.NET. Added. (He also lists Object Thinking, by West, but I don't care for that
book--too Zen, I think, for most readers.)
</p>
        <img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=624cf311-956e-4ac0-a381-c71666057db6" />
        <br />
        <hr />
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. <a href="mailto:ted@tedneward.com">Contact
me for details</a>.</body>
      <title>Recommended Reading List (old version)</title>
      <guid isPermaLink="false">http://blogs.tedneward.com/PermaLink,guid,624cf311-956e-4ac0-a381-c71666057db6.aspx</guid>
      <link>http://blogs.tedneward.com/2005/08/21/Recommended+Reading+List+Old+Version.aspx</link>
      <pubDate>Sun, 21 Aug 2005 08:40:23 GMT</pubDate>
      <description>&lt;p&gt;
(Note that this is a reprint, so to speak, of &lt;a href="http://www.neward.net/ted/weblog/index.jsp?date=20030205#1044497180661"&gt;the
same entry&lt;/a&gt; on the old weblog, but I wanted to kick the Reading category off with
a reprise of what I'd written before.)
&lt;/p&gt;
&lt;p&gt;
I've been asked on several occasions (from students, from blog readers, and from a
few friends who happen to be in the business) what my recommended reading list is.
I've never really put one together formally, instead just sort of relying on impromptu
answers that cover some of my absolute favorites and a few that just leap to mind
at the time. 
&lt;/p&gt;
&lt;p&gt;
Enough is enough. It's time for me to post my recommended reading list, broken out
for both Java and .NET programmers. (If you're of one camp, it's still worth reading
books on the other camp's list, since the two environments really are Evil Twin Brothers.)
And I've left my own books off the list, because I think it's rather forward of me
to recommend them as recommended reading--naturally, I think they're all good, but
whether or not they make the cut of "recommended reading" is for others to weigh in
on, not me (at least not here). (&lt;b&gt;Update&lt;/b&gt;: several commenters on the old blog
suggested it was not out of line to recommend my own books if I thought they were
worth recommending, so I added them.)
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Java Recommended Reading list&lt;/b&gt;: 
&lt;ul&gt;
&lt;li&gt;
&lt;i&gt;Effective Java&lt;/i&gt; by Bloch. 
&lt;li&gt;
&lt;em&gt;Java Puzzlers&lt;/em&gt; by Bloch and Gafter. You think you know the Java language?
Try it. (Makes for great interview question fodder, and for that reason alone practicing
Java programmers should have a copy on their shelf.) 
&lt;li&gt;
&lt;em&gt;Effective Enterprise Java&lt;/em&gt; by Neward. (Had to do it. :-) ) 
&lt;li&gt;
&lt;i&gt;Concurrent Programming in Java (2nd Ed)&lt;/i&gt; by Lea. 
&lt;li&gt;
Either &lt;em&gt;Inside Java2 Platform Security&lt;/em&gt; by Gong or &lt;i&gt;Java Security (2nd Ed)&lt;/i&gt; by
Oaks. 
&lt;li&gt;
&lt;i&gt;Component Development for the Java Platform&lt;/i&gt; by Halloway. 
&lt;li&gt;
&lt;i&gt;Inside the Java2 Virtual Machine&lt;/i&gt; by Venners. 
&lt;li&gt;
&lt;i&gt;Java Development with Ant&lt;/i&gt; by Hatcher and Loughran. 
&lt;li&gt;
Either &lt;i&gt;Java RMI&lt;/i&gt; by Grosso or &lt;i&gt;java.rmi&lt;/i&gt; by McNiff and Pitt. 
&lt;li&gt;
&lt;em&gt;Server-Based Java Programming&lt;/em&gt; by Neward. For obvious reasons. :-) Actually,
I still think this book is applicable if you want to understand the reasons why an
app server makes some of the restrictions that it does, but I freely admit that I
don't think I did a great job of "closing the loop" on that and finishing the book
with a good summary that ties everything together. Ah, retrospect.... 
&lt;li&gt;
&lt;i&gt;Servlets and Java Server Pages&lt;/i&gt; by Jones and Falkner, possibly &lt;em&gt;Java Servlet
Programming (2nd Ed)&lt;/em&gt; by Hunter, if you aren't planning to use JSP. (Jason's legendary
bias against JSP, right or wrong, puts him somewhat out of tune with what a majority
of Java web-client shops are doing. That said, it's a great servlets resource.) 
&lt;li&gt;
&lt;em&gt;AspectJ in Action&lt;/em&gt; by Laddad. AspectJ represents the best of the AOP solutions,
IMHO, and this book represents the best of the AspectJ books available.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;.NET Recommended Reading list&lt;/b&gt;: 
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;C# In a Nutshell (2nd Ed)&lt;/em&gt; by Drayton, Albahari, and Neward. For obvious reasons.
:-) 
&lt;li&gt;
&lt;i&gt;Advanced .NET Remoting&lt;/i&gt; by Rammer. 
&lt;li&gt;
&lt;i&gt;Essential ADO.NET&lt;/i&gt; by Beauchemin. 
&lt;li&gt;
&lt;i&gt;Inside Microsoft .NET IL Assembler&lt;/i&gt; by Lidin. 
&lt;li&gt;
&lt;em&gt;SSCLI Essentials&lt;/em&gt; by Stutz, Neward and Shilling. For obvious reasons. :-) 
&lt;li&gt;
&lt;i&gt;Debugging Applications&lt;/i&gt; by Robbins. 
&lt;li&gt;
&lt;i&gt;Inside Windows 2000&lt;/i&gt; by Russinovich and Solomon. 
&lt;li&gt;
&lt;i&gt;Essential COM&lt;/i&gt; by Box. &lt;i&gt;(Yes, I mean Essential COM and not his more recent
Essential .NET book. The first chapter of Essential COM is probably the best well-written
technical prose I've ever read in my life, and everybody who ever wanted to write
reusable components in C++ needs to read it to understand why C++ failed so miserably
at that goal. Once you've seen that, you're ready to understand why components are
so powerful and so necessary.)&lt;/i&gt; 
&lt;li&gt;
&lt;em&gt;Essential ASP.NET&lt;/em&gt; by Onion. 
&lt;li&gt;
&lt;em&gt;Expert C# Business Objects&lt;/em&gt; or &lt;em&gt;Expert VB Business Objects&lt;/em&gt;,&amp;nbsp;by
Lhotka. Not an intro to business objects, per se, but a great read on how to build
a framework. Pay close attention to how Rocky handles distribution; he avoids the
canonical problems of "distributed objects" by not distributing objects, but instead
making them &lt;em&gt;mobile objects&lt;/em&gt;. 
&lt;li&gt;
&lt;i&gt;The Common Language Infrastructure Annotated Standard&lt;/i&gt; by Miller 
&lt;li&gt;
&lt;i&gt;Programming in the .NET Environment&lt;/i&gt; by Watkins et al. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;C++ Recommended Reading list&lt;/b&gt;:&lt;br&gt;
&lt;i&gt;(For the twelve people left in the world still writing C++ code, anyway.)&lt;/i&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;i&gt;The C++ Programming Language (3rd Ed)&lt;/i&gt; by Stroustrup. 
&lt;li&gt;
&lt;em&gt;Effective C++ (1st, 2nd &lt;/em&gt;or&lt;em&gt; 3rd Ed)&lt;/em&gt; by Meyers. 
&lt;li&gt;
&lt;i&gt;More Effective C++&lt;/i&gt; by Meyers. 
&lt;li&gt;
&lt;i&gt;Effective STL&lt;/i&gt; by Meyers. 
&lt;li&gt;
&lt;em&gt;Inside the C++ Object Model&lt;/em&gt; by Lippmann. You don't know how C++ works until
you've read this cover to cover. Twice. And peeked at everything under the hood with
a debugger, just to make sure Stan's right. Seriously.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Database/Relational Storage Recommended Reading list:&lt;/b&gt; 
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Introduction to Database Systems&lt;/em&gt; &lt;em&gt;(8th Ed)&lt;/em&gt; by Date. Heavy on theory,
and for that reason alone should be read at least once by any practicing programmer
who thinks they understand SQL and the relational world. 
&lt;li&gt;
&lt;em&gt;SQL for Smarties (3rd Ed)&lt;/em&gt; by Celko. Actually, you need to own just about
everything by Celko. 
&lt;li&gt;
&lt;i&gt;Principles of Transaction Processing&lt;/i&gt; by Bernstein and Newcomer. 
&lt;li&gt;
&lt;i&gt;Transaction Processing: Concepts and Techniques&lt;/i&gt; by Gray and Reuter. What to
read when you're done with the Bernstein and Newcomer book and still want to know
more about the Zen of Transactional Processing. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;b&gt;Security-related Recommended Reading list&lt;/b&gt;: 
&lt;ul&gt;
&lt;li&gt;
&lt;i&gt;Secrets and Lies&lt;/i&gt; by Schneier. 
&lt;li&gt;
Either &lt;i&gt;Cryptography Decrypted&lt;/i&gt; by (can't remember the name offhand), &lt;i&gt;Practical
Cryptography&lt;/i&gt; by Schneier and Ferguson, or &lt;i&gt;Applied Cryptography (2nd Ed)&lt;/i&gt; by
Schneier. The first is a lightweight introduction to the subject, the second is a
more detailed introspection, the third required reading for anybody who wants to be
a security wonk. 
&lt;li&gt;
&lt;i&gt;The Code Book&lt;/i&gt; by Singh. 
&lt;li&gt;
&lt;em&gt;Hacking Exposed (5th Ed)&lt;/em&gt;, by McClure, et al. 
&lt;li&gt;
&lt;em&gt;Exploting Software&lt;/em&gt;, by Hogland and McGraw. The most fun book in the list,
if you ask me. 
&lt;li&gt;
&lt;em&gt;Reversing&lt;/em&gt; by Eilam. Who says unmanaged code is "safe from reverse-engineering"? 
&lt;li&gt;
&lt;em&gt;The Art of Deception&lt;/em&gt;, by Mitnick&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Operating System/Platform Reading list:&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Windows Internals&lt;/em&gt; (4th Ed) by Russinovich and Solomon. Actually, any of the
last three editions (2nd, 3rd, 4th) is awesome, so look for 3rd Ed in a bargain bin
and pick up a great bargain. 
&lt;li&gt;
&lt;em&gt;Operating Systems&lt;/em&gt; (2nd Ed) by Tanenbaum. The original "Minix" book. Taught
me the basics of how an O/S works, and the basic concepts are still applicable to
this day.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;b&gt;Platform-agnostic Recommended Reading list&lt;/b&gt;: 
&lt;ul&gt;
&lt;li&gt;
&lt;i&gt;Design and Evolution of C++&lt;/i&gt; by Stroustrup. It's fascinating hearing how a language
develops over time, and what was behind some of the decisions in the features of the
language. For example, why did multiple inheritance come before templates or RTTI?
Not because it was more important, but because Stroustrup wanted to tackle MI first
because he wasn't sure if or how he could do it. He describes that as a great regret,
that he didn't do templates first. 
&lt;li&gt;
&lt;i&gt;Component Software (2nd Ed)&lt;/i&gt; by Szyperski. 
&lt;li&gt;
&lt;i&gt;Rapid Development&lt;/i&gt; by McConnell. Read this before you read any of the Extreme
Programming books, because this book describes a whole taxonomy of what I think a
lot of people are reaching for in agile and other methodologies. 
&lt;li&gt;
&lt;i&gt;The Inmates Are Running the Asylum&lt;/i&gt; by Cooper. 
&lt;li&gt;
&lt;i&gt;The Invisible Computer&lt;/i&gt; by Norman. 
&lt;li&gt;
&lt;i&gt;Refactoring&lt;/i&gt; by Fowler. 
&lt;li&gt;
&lt;i&gt;Design Patterns&lt;/i&gt; by Gamma, Helm, Johnson and Vlissides. 
&lt;li&gt;
&lt;i&gt;Pattern Oriented Software Architecture, Vol 1&lt;/i&gt; by Stal et al. 
&lt;li&gt;
&lt;i&gt;Pattern Oriented Software Architecture, Vol 2&lt;/i&gt; by Schmidt et al. 
&lt;li&gt;
&lt;i&gt;Patterns of Enterprise Application Architecture&lt;/i&gt; by Fowler. 
&lt;li&gt;
&lt;i&gt;Enterprise Integration Patterns&lt;/i&gt; by Hohpe and Woolf. Excellent discussion of
message-based architecture. I personally think the title is something of a misnomer,
but it's understandable since message-oriented communication is the easiest means
by which to integrate heterogeneous systems. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Note that this list will undergo revision and change as I continue, so I'm putting
a link to this item in the links column in the sidepanel to the left for easy reference.
For now, I'm just listing them out as they come to mind. Later, if I have time, I'll
put paragraphs of detail behind them so you can know why I recommend them. (Updated
on 13 Feb 2002) (Moved to this weblog 21 Aug 2005) (Updated 5 Oct 2005)
&lt;/p&gt;
&lt;p&gt;
Look for more book reviews and recommended reading via the "Reading" category on the
RSS feeds. There's undoubtedly titles that I'm forgetting, and I'm hoping I'll get
around to blogging more about the books I'm reading now, including Ruby (the Pickaxe
book and the Rails book), some other titles in the Pragmatic series, as well as some
WS-*-related stuff and (of course) the staple C# and Java stuff. And of course I'm
always open to suggestions of new and interesting technical titles to peruse....
&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Update: &lt;a href="http://www.stevenrockarts.com/blog/PermaLink,guid,e054ed79-8291-4e83-adf1-cfc1fb1f72dc.aspx"&gt;Steven
Rockarts&lt;/a&gt; pointed out that Rocky's "Objects" books are missing, as is Fritz's Essential
ASP.NET. Added. (He also lists Object Thinking, by West, but I don't care for that
book--too Zen, I think, for most readers.)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.tedneward.com/aggbug.ashx?id=624cf311-956e-4ac0-a381-c71666057db6" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
Enterprise consulting, mentoring or instruction. Java, C++, .NET or XML services.
1-day or multi-day workshops available. &lt;a href="mailto:ted@tedneward.com"&gt;Contact
me for details&lt;/a&gt;.</description>
      <comments>http://blogs.tedneward.com/CommentView,guid,624cf311-956e-4ac0-a381-c71666057db6.aspx</comments>
      <category>.NET</category>
      <category>C++</category>
      <category>Java/J2EE</category>
      <category>Reading</category>
      <category>XML Services</category>
    </item>
  </channel>
</rss>