<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Generalities &amp; Details: Adventures in the High-tech Underbelly</title>
  <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/" />
  <link rel="self" href="http://www.bluebytesoftware.com/blog/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-12-28T19:58:08.1724029-05:00</updated>
  <author>
    <name>Joe Duffy</name>
  </author>
  <subtitle>Joe Duffy's Weblog</subtitle>
  <id>http://www.bluebytesoftware.com/blog/</id>
  <generator uri="http://www.dasblog.net" version="1.8.5223.2">DasBlog</generator>
  <entry>
    <title>CPOW errata and code samples</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/12/29/CPOWErrataAndCodeSamples.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,45920e3f-36ac-494a-afa6-b3961049aa93.aspx</id>
    <published>2008-12-28T19:58:08.1724029-05:00</published>
    <updated>2008-12-28T19:58:08.1724029-05:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      As embarassing as it is, the errata for <em>Concurrent Programming on Windows</em> is
      non-empty.
   </p>
        <p>
      I've posted an initial listing -- full of primarily simple typos like misplaced commas
      -- at <a href="http://www.bluebytesoftware.com/books/winconc/winconc_book_resources.html#Errata">http://www.bluebytesoftware.com/books/winconc/winconc_book_resources.html#Errata</a>.
   </p>
        <p>
      Sincere thanks to everybody who has reported errors thus far.  If you find any
      additional ones, please email them to me directly: joe AT bluebytesoftware DOT com. 
      We'll attempt to fix as many errors as possible in subsequent printings of the
      1st edition and, if that fails, they'll make the 2nd edition.
   </p>
        <p>
      I've spent the past few months (from September onward) travelling approximately
      75% of the time.  As a result, I may be slow responding to email concerning the
      book.  I've also not finished putting together the code samples up for download;
      my current ETA for that is mid-January 2009.  I already know there are a few
      more errata entries lurking within, due to some last minute typographical updates
      made late in the editing process.  If only word processing software came complete
      with built-in compilers...  (excuses, excuses)
   </p>
        <p>
      In any case, I'd love to receive feedback on the book.  Even if it's not about
      an error.  Things you like, things you'd like to see improved, things you wish
      I'd not written about, requests for clarifications, etc.  Just drop
      me an email.  Cheers.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=45920e3f-36ac-494a-afa6-b3961049aa93" />
      </div>
    </content>
  </entry>
  <entry>
    <title>A new book: Notation and Thought</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/11/29/ANewBookNotationAndThought.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,be71e963-8501-45f1-8670-8bb04f9a18c9.aspx</id>
    <published>2008-11-29T04:21:48.5250000-05:00</published>
    <updated>2008-11-29T04:30:08.6141713-05:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I've had an obsession with programming languages for some time now. This probably
      began the first time I learned of LISP. Most people I know have had a similar "Ah-Hah!"
      moment associated with LISP, but it was when I first truly realized the deep extent
      to which a programming language shapes thought -- sometimes in negative ways. LISP
      put it all into perspective.
   </p>
        <p>
      Since then, the obsession has only become worse through my employment at Microsoft,
      where I've had the privilege to work alongside and interact with some of the greatest
      minds in programming languages. This is an absolute honor. I worked on a few compilers
      and did some language design, particularly when on the Common Language Runtime team,
      and my favorite project today is my work on type-system support for static enforcment
      of concurrency safety and guaranteed isolation. I have found great joy in
      applying underlying concepts in more niche (and extreme) languages like
      Haskell to more mainstream languages like C#.  My favorite pasttime is tracing
      back the lineage of languages to their earliest ideas, especially when this leads
      to the unearthing of a subtle commonality among them. I have been designing one of
      my own and, while it is undoubtedly a 5-year project that may never see the light
      of day, I do it for the love of languages. 
   </p>
        <p>
      This book has been stewing inside me for a while now. And after seeing Guy L. Steele
      and Richard P. Gabriel's infinitely beautiful <a href="http://blog.jaoo.dk/2008/11/21/art-and-code-obscure-or-beautiful-code/">"50
      in 50" presentation</a> at JAOO this year, I decided it was time for it to escape. 
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <strong>
              <a href="http://www.bluebytesoftware.com/books/notation_and_thought.html">
                <font size="3">Notation
      and Thought:</font>
                <br />
                <em>Behind Computer Science's Most Influential Programming Languages</em>
              </a>
            </strong>
          </p>
          <p>
           “That language is an instrument of human reason, and
      not merely a medium<br />
           for the expression of thought, is a truth generally
      admitted.”<br />
           --- George Boole, <i>Laws of Thought</i></p>
          <p>
      Programming languages are not only a notation for expression, but also a medium of
      thought, akin to the duality between natural written and spoken languages. If you
      can think it, you can create it. The reverse is also true: if a language poses impediments
      to your thought process, certain solutions to problems are simply unfathomable. Languages
      are therefore <i>not</i> just what you see “on paper”--each is a unique tool that
      can substantially limit, or expand, the creative freedom of the programmer in whose
      hands it sits. Good languages get out of the way, and great ones do a whole lot more.
   </p>
          <p>
      In the early days, there was of course nothing that resembled modern day languages.
      Computers had to be told what to do in excruciating detail. One only has to look at
      modern day assembly language to see that programming a computer in this manner constrains
      creativity and slows progress. Alan Turing didn’t even have that when he wrote his
      classic <i>On Computable Numbers with an Application to the Entscheidungsproblem</i> paper,
      but he at least managed to solve some simple problems: by moving a tape reader and
      reading and writing symbols, he was able to create the modern day equivalent to subroutines
      and even add up a number or two. But our industry would have never seen radical advances
      in enabling technologies, and widespread computer use, that we enjoy today without
      significant advances in higher-order abstractions. 
   </p>
          <p>
      Plankalkül, or the <i>plan calculus</i>, is widely recognized as the first real programming
      language. It was designed by a German computer engineer, Konrad Zuse, and first written
      down in an unpublished manuscript in 1943. The language offered composite (albeit
      simplistic) data structures, arrays, named variables, subroutines, and moderately
      sophisticated control flow and looping constructs. Although it was never used in practice,
      Plankalkül was surprisingly ahead of its time. It was a big step towards more abstract
      problem solving. 
   </p>
          <p>
      It should be no surprise that subsequent programming languages are as varied in their
      design as the humans that created them. This fact can be seen by examining the ensuing
      decade of computing post-Plankalkül. The 1950s saw the invention of four new major
      languages that fundamentally shaped the future of language design. FORTRAN, or the <i>FORmula
      TRANslation language</i>, specialized in describing transformations on data and numerics,
      and was the first non- assembly language to reach widespread use in performance sensitive
      situations. LISP, or the <i>LISt Processing language</i>, was developed for symbolic
      processing and, eventually, found a home in artificial intelligence, pioneering many
      techniques that are still in use today such as first class functions as data, a recursive
      style of programming, and garbage collection. Its principles were derived from the
      mathematical logics of Alonzo Church and Haskell B. Curry, notably Church’s lambda
      calculus from the 1930s. ALGOL, or the <i>ALGOrightmic Language</i>, focused on describing
      algorithms elegantly, kick-started the imperative family of languages (of which many
      popular industry programming languages like C++ and Java are members), and later set
      the de facto standard style for Computer Science education curricula. Its method of
      encoding algorithms with assignments was far closer to the von Neumann architecture
      than was LISP, making the resulting programs behave predictably and efficiently. Lastly,
      COBOL, or the <i>COmmon Business-Oriented Language</i>, became the first domain-specific
      language (DSL) that targeted non-programming business and finance experts, broadening
      the general accessibility of computers. Each of the four has had a crucially important
      role to play in the history of programming languages. 
   </p>
          <p>
      There has been no shortage of language diversity after the birth of the initial four.
      In fact, hundreds of languages have since come and gone, some enjoying brief or extended
      periods of popular use. All that have since come have been deeply influenced by the
      pioneers, but have also contributed a handful of innovative new ideas that help programmers
      more clearly think about and express solutions to real-world problems. The lineage
      of languages has branched off into separately named family trees--such as <i>imperative</i>, <i>functional</i>, <i>logic</i>, <i>declarative</i> and <i>domain-specific</i>--only
      to reunite intimately with each other down the line. Indeed, it really is just one
      big happy family. 
   </p>
          <p>
      This book traces this lineage through the most influential languages--those that have
      deeply impacted the way that programmers think and write--and provides insight into
      the motivation behind them, their major influences, and the important features that
      each language contributed. Throughout, it is my hope to develop within the reader
      a new appreciation of the art of programming computers, an understanding of the impact
      that language has on our thinking, and an excitement about the future of language
      design that lies ahead. 
   </p>
        </blockquote>
        <p>
      Joe Duffy<br /><i>November, 2008</i></p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=be71e963-8501-45f1-8670-8bb04f9a18c9" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Longing for higher-kinded C#</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/11/04/LongingForHigherkindedC.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,fdb30c7d-36a3-4b3d-a423-929fc9f6409a.aspx</id>
    <published>2008-11-04T15:55:52.1720000-05:00</published>
    <updated>2008-11-04T20:46:25.6738720-05:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="html">&lt;p&gt;
   Type classes, kinds, and higher-order polymorphism represent some of Haskell’s most
   unique and important contributions to the world of programming languages.&amp;nbsp; They
   are all related, and began life as type classes in Wadler and Blott’s 1988 paper, &lt;em&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=75277.75283"&gt;How
   to make ad-hoc polymorphism less ad hoc&lt;/a&gt;&lt;/em&gt;.&amp;nbsp; Eventually, Jones introduced
   the&amp;nbsp;(then separate) concept of constructor classes, in his 1993 paper, &lt;em&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=165180.165190"&gt;A
   system of constructor classes: overloading and implicit higher-order polymorphism&lt;/a&gt;&lt;/em&gt;.&amp;nbsp;
   Eventually these two ideas were unified into a beautiful single set of features (namely,
   type constructors and kinds) in Haskell.
&lt;/p&gt;
&lt;p&gt;
   In this short essay, I’ll explain what these things are and why I’m sad that we don’t
   have them in C#. 
&lt;/p&gt;
&lt;p&gt;
   To take the simplest motivating example, say we want to define a generic square function:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;square
   x = x * x&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Given a Hindley-Milney type system (with type inference), how should the compiler
   type this function?&amp;nbsp; The challenge that immediately arises is that, to know the
   type of x and the function’s return value, we must know something about the function
   * being called within the body of square.&amp;nbsp; But to know something about that function,
   we’d need to know the type of x.&amp;nbsp; We’ve entered into a cycle, and have hit a
   wall.&amp;nbsp; Clearly the type will be something generic, but polymorphic on what?
&lt;/p&gt;
&lt;p&gt;
   Imagine that we could infer the type of the * function as follows:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;(*)
   :: a -&amp;gt; a -&amp;gt; b&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   In other words, * is a function that takes two values, both of type a, and produces
   some value of another type b.&amp;nbsp; We know its two arguments must be of the same
   type because in square we pass the same value x to it twice.&amp;nbsp; Given this typing
   for *, we could then type square similarly as:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;square
   :: a -&amp;gt; b&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   In other words, square takes a single value of type a and produces a value of type
   b.&amp;nbsp; The constraint on the type a here is, of course, that some function * is
   available that is typed as taking an a as input.&amp;nbsp; There’s no obvious way to capture
   this in the type system, though we might conceive of something like:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;square
   :: (* :: a -&amp;gt; a -&amp;gt; b) =&amp;gt; a -&amp;gt; b&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   In other words, given a type a for which some function * is defined, which takes two
   a’s and returns a single b, the type of square thus takes an a and produces a b.&amp;nbsp;
   You can’t say that in Haskell, although we’ll see a bit later that type classes allow
   similar constraints (with “=&amp;gt;”) to be written.
&lt;/p&gt;
&lt;p&gt;
   While this hypothetical typing is extremely general purpose, it would produce considerable
   challenges in its implementation.&amp;nbsp; Standard ML throws up its hands and infers
   all mathematical operators (like *) as working with floats, meaning that all of the
   types above (both a and b) will be inferred under the type of float.&amp;nbsp; (*) is
   of type float -&amp;gt; float -&amp;gt; float, and square is of type float -&amp;gt; float.&amp;nbsp;
   Similarly, F# assumes you’re working with ints.&amp;nbsp; Both Standard ML and F# have
   amazingly rich type inference systems, but this begins to run right up against the
   limits of what they can do.&amp;nbsp; We’ll see some harder examples shortly.
&lt;/p&gt;
&lt;p&gt;
   You can probably guess that Haskell’s solution to this conundrum is to use higher
   order polymorphism with a feature of its type system called type classes.&amp;nbsp; They
   allow us to classify types much in the same way types ordinarily classify objects.&amp;nbsp;
   We can classify the set of numeric types as follows, for instance:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;class
   Num a where&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(*)
   :: a -&amp;gt; a -&amp;gt; a&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;…
   other numeric operations …&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   And then we can go ahead and provide concrete mappings for integers and floating point
   numbers:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;instance
   Num Int where&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(*)
   = addInt&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;…&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;instance
   Num Float where&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;(*)
   = addFloat&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Each instance of the type class (in this case, Num) is a bit like a dictionary mapping
   the named functions (in this case, just *) to other functions that are defined for
   the concrete type (in this case, supplied in a’s stead).&amp;nbsp; With this information
   defined, the Haskell compiler can now infer the type of square as:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;square
   :: Num a =&amp;gt; a -&amp;gt; a&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   This inference really just says that the function square is defined for all types
   a that are in the type class Num.&amp;nbsp; The “Num a =&amp;gt;” part is a bit like a C#
   generic type constraint, in that it restricts what kinds of a’s can be supplied.&amp;nbsp;
   Given what has been stated thus far, that’s just Int and Float.&amp;nbsp; So we can only
   call the square function with types on which multiplication is properly defined, which
   is exactly what we want.
&lt;/p&gt;
&lt;p&gt;
   At this point, we might want to try defining a similar thing in C# using generics.&amp;nbsp;
   (And for this simplistic example, and others like Haskell’s Eq a type class, we will
   succeed.)&amp;nbsp; There are two basic ways we could achieve this.&amp;nbsp; The first is
   to define an INum&amp;lt;T&amp;gt; interface (or abstract class—pick your poison), and give
   it an instance method to multiply the target with another number:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;interface
   INum&amp;lt;T&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T
   Mult(T x);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   We would then have the basic numeric data types like Int32 and Float implement INum&amp;lt;T&amp;gt;:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;struct
   Int32 : INum&amp;lt;Int32&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public
   Int32 Mult(Int32 x) { return value * x; }&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;…&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;struct
   Float : INum&amp;lt;Float&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public
   Float Mult(Float x) { return value * x; }&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;…&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Given these definitions, it would be a breeze to write a Square method that only operates
   on INum&amp;lt;T&amp;gt;s:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;T
   Square&amp;lt;T&amp;gt;(T x) where T : INum&amp;lt;T&amp;gt; { return x.Mult(x); }&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Thankfully, we can recursively reference the T from within the generic type constraint.
&lt;/p&gt;
&lt;p&gt;
   Now, of course, there’s no way the C# compiler would infer the necessary INum&amp;lt;T&amp;gt;
   constraint.&amp;nbsp; But given that we don’t have rich type inference (aside from for
   local variables) in C#, this doesn’t pose any new problems.&amp;nbsp; Another slight annoyance
   is that you need to modify the source type to declare support for INum&amp;lt;T&amp;gt;, when
   a perfectly reasonable implementation could have been provided “from the outside,”
   but you’ll find that this will only occasionally get under your skin.
&lt;/p&gt;
&lt;p&gt;
   The second way we might go about this is to take an approach similar to .NET’s EqualityComparer&amp;lt;T&amp;gt;
   class, where we have an abstract base class that represents the ability to do something
   with instances of Ts.&amp;nbsp; And then we only provide implementations on concrete Ts
   for which that ability makes sense.&amp;nbsp; For example, we could have a Multiplier&amp;lt;T&amp;gt;
   that looks a lot like INum&amp;lt;T&amp;gt;:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;abstract
   class Multiplier&amp;lt;T&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public
   abstract T Mult(T x, T y);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Multiplier&amp;lt;T&amp;gt; on its own isn’t usable.&amp;nbsp; But we can provide implementations
   for Int32 and Float:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;class
   Int32Multiplier : Multiplier&amp;lt;Int32&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public
   override Int32 Mult(Int32 x, Int32 y) { return x * y; }&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;class
   FloatMultiplier : Multiplier&amp;lt;Float&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;public
   override Float Mult(Float x, Float y) { return x * y; }&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;//
   And so on …&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Now we can write a slightly different Square method that takes a Multiplier&amp;lt;T&amp;gt;
   as an extra argument:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;T
   Square&amp;lt;T&amp;gt;(T x, Multiplier&amp;lt;T&amp;gt; m) { return m.Mult(x, x); }&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   Now there isn’t any kind of generic type constraint on Square’s T, but of course we
   can only call it if we have a concrete instance of Multiplier&amp;lt;T&amp;gt; in hand.&amp;nbsp;
   And by definition that means there is a Mult method defined that we can call.&amp;nbsp;
   (This isn’t wholeheartedly true.&amp;nbsp; You can of course call Square&amp;lt;U&amp;gt; for
   any U, passing in null as the second argument.&amp;nbsp; But presumably the method would
   check for null and throw.&amp;nbsp; This is a real limitation, however, which would likely
   push us back in the direction of the original interface solution.&amp;nbsp; If we had
   non-null types, we could get closer to a fully statically verifiable solution.) 
&lt;/p&gt;
&lt;p&gt;
   Aside from a lot more typing, and the lack of rich type inference, we seem to have
   reached parity.&amp;nbsp; The simple examples provided in the literature and Haskell’s
   Standard Prelude can be implemented in such a fashion.&amp;nbsp; But we are kidding ourselves
   if we think these are the same thing.
&lt;/p&gt;
&lt;p&gt;
   The main problem is that C# doesn’t support higher-kinded type parameters.&amp;nbsp; We
   haven’t yet seen a type class in Haskell that fully exploits this capability, but
   there are several.&amp;nbsp; The simplest one I know about in the Haskell Standard Prelude
   is the Functor type.&amp;nbsp; (Monad is also a great example, but is a bit more complicated
   (and sufficiently frightening) that this will be a topic for another day.)&amp;nbsp; Functor’s
   definition is:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;class
   Functor f where&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;fmap
   :: (a -&amp;gt; b) -&amp;gt; f a -&amp;gt; f b&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   The Functor type class offers a single function, fmap.&amp;nbsp;&amp;nbsp; It takes two things—a
   function that transforms a value of type a into a value of type b and some functor
   value of type f a—and returns some new functor value of type f b.&amp;nbsp; This looks
   like an ordinary type class, except for one funny (and subtle) aspect.&amp;nbsp; Functor
   abstracts over type f, but notice that we’re using f in fmap’s second argument and
   return type by actually constructing it with two other types a and b!&amp;nbsp; In case
   you’re having a hard time thinking in Haskell, it’s as though we tried to write this
   in C# using our interface trick from earlier:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;interface
   IFunctor&amp;lt;T&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;T&amp;lt;B&amp;gt;
   FMap&amp;lt;A, B&amp;gt;(Func&amp;lt;A, B&amp;gt; f, T&amp;lt;A&amp;gt; a);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   This won’t compile.&amp;nbsp; We can’t refer to T in the typing of FMap as T&amp;lt;B&amp;gt;
   and T&amp;lt;A&amp;gt;: it’s not expressible in C# and .NET’s type system.&amp;nbsp; Let’s pretend
   for a moment, however, that we could.&amp;nbsp; What is an example of class that might
   implement this?&amp;nbsp; How about something that deals in terms of Nullable&amp;lt;T&amp;gt;
   instances?
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;class
   NullableFunctor&amp;lt;T&amp;gt; : IFunctor&amp;lt;Nullable&amp;lt;&amp;gt;&amp;gt; {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Nullable&amp;lt;B&amp;gt;
   FMap&amp;lt;A, B&amp;gt;(Func&amp;lt;A, B&amp;gt; f, Nullable&amp;lt;A&amp;gt; a) {&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;return
   new Nullable&amp;lt;B&amp;gt;(f(a.Value));&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: Consolas; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 11.0pt; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   All you need to do is take a close look at a 1997 paper by Simon Peyton Jones, Mark
   Jones, and Erik Meijer, entitled &lt;em&gt;&lt;a href="http://research.microsoft.com/~simonpj/papers/type-class-design-space/"&gt;Type
   classes: an exploration of the design space&lt;/a&gt;&lt;/em&gt;, and you will find a plethora
   of even more complicated (and useful) examples that use an innocent-sounding aspect
   of Haskell’s type system called multi-parameter type classes.&amp;nbsp; All of the types
   are higher-order and are merely moved around and manipulated like abstract (higher-order)
   symbols.&amp;nbsp; The type system gracefully gets out of the way and allows you to drop
   abstract type parameters into any holes they fit in, without mandating that you say
   too much.&amp;nbsp; The secret sauce—as noted earlier—is kinds.
&lt;/p&gt;
&lt;p&gt;
   Kinds are used in the implementation of Haskell’s type system, and you won’t mention
   a whole lot about them anywhere.&amp;nbsp; They basically categorize what kind of types
   can appear anywhere a type is expected.&amp;nbsp; A great overview (with plenty of context)
   can be found in Mark P. Jones’s &lt;em&gt;&lt;a href="http://portal.acm.org/citation.cfm?id=647698.734150"&gt;Functional
   Programming with Overloading and Higher-Order Polymorphism&lt;/a&gt;&lt;/em&gt; paper and, of
   course, the &lt;a href="http://www.haskell.org/onlinereport/"&gt;&lt;em&gt;Haskell 98 Report&lt;/em&gt;&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
   Here’s a quick rundown.&amp;nbsp; Kinds appear in one of two forms:
&lt;/p&gt;
&lt;ol&gt;
   &lt;li&gt;
      the symbol * represents a concrete type (a.k.a. a monotype), and, 
   &lt;li&gt;
      if k1 and k2 are kinds, then k1 -&amp;gt; k2 is the kind of types that take a type of
      kind k1 and return a type of kind k2.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
   Kinds are formed in many ways: the primitive types (such as Char, Int, Float, Double,
   etc.) are an example of the former, and are of kind *.&amp;nbsp; They “bottom out.”&amp;nbsp;
   Type constructors, however, like Functor are an example of the latter, and are of
   kind * -&amp;gt; *.&amp;nbsp; That is, they take a kind k1 (the first *) and produce another
   kind k2 (the second *).&amp;nbsp; By giving some concrete type T (*) to Functor, we get
   back a Functor T (also *).&amp;nbsp; The latter is therefore a bit like a function mapping
   one kind to another.&amp;nbsp; Functions have a kind of * -&amp;gt; * -&amp;gt; *, because a function
   has two types: the type of arguments (the first *) and the type of its return value
   (the second *).&amp;nbsp; These compose, so that you might have (* -&amp;gt; *) -&amp;gt; * -&amp;gt;
   *.&amp;nbsp; And so on.&amp;nbsp; Thinking about kinds can take a bit of getting used to.
&lt;/p&gt;
&lt;p&gt;
   But the really useful thing here is that kinds allow you to write higher order type
   constructors like those we have begun to explore above, like Functors and Monads.&amp;nbsp;
   I.e., given a type t1 of kind k1 -&amp;gt; k2, and a type t2 of kind k1, then t1 t2 is
   a type expression of kind k2.&amp;nbsp; This can be applied to the occurrences of f a
   and f b in Functor’s fmap function.&amp;nbsp; In the type Functor f they are of kind *
   -&amp;gt; * -&amp;gt; *.&amp;nbsp; When a concrete Functor instance is specified, e.g., by substituting
   T for f, this turns fmap’s T a and T b arguments to kind * -&amp;gt; *.&amp;nbsp; That is,
   they still both expect another kind before bottoming out.&amp;nbsp; And therefore we can
   substitute some concrete U and V types for a and b, to reduce them from kind * -&amp;gt;
   * to kind *.
&lt;/p&gt;
&lt;p&gt;
   Now we’re done.&amp;nbsp; And, as if by magic, it all works.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=fdb30c7d-36a3-4b3d-a423-929fc9f6409a" /&gt;</content>
  </entry>
  <entry>
    <title>A new SysInternals tool for printing multicore architecture information</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/11/03/ANewSysInternalsToolForPrintingMulticoreArchitectureInformation.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,e1791031-e477-4b8c-b342-933f198ef137.aspx</id>
    <published>2008-11-03T02:36:22.3870000-05:00</published>
    <updated>2008-11-03T02:37:12.6339780-05:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      A few months back, while writing my <a href="http://www.amazon.com/exec/obidos/ASIN/032143482X/bluebytesoftw-20">new
      book</a>, I whipped together a tool to dump information about your processor layout
      using the <a href="http://msdn.microsoft.com/en-us/library/ms683194.aspx">GetLogicalProcessorInformation</a> function
      from C#.  You can find the code snippet in Chapter 5, Advanced Threads, of my
      book.  (A developer on the Windows Core OS team, Adam Glass, had also written
      a similar tool in C++.)  I will be posting code to the <a href="http://www.bluebytesoftware.com/books/winconc/winconc_book_resources.html">companion
      site</a> for my book in the coming weeks, at which point you can easily get your hands
      on it.
   </p>
        <p>
      Anyway, I sent the code to Mark Russinovich suggesting it might make a useful SysInternals
      tool, and he agreed.  Now it's up on microsoft.com for download, under the name
      of Coreinfo: <a href="http://technet.microsoft.com/en-us/sysinternals/cc835722.aspx">http://technet.microsoft.com/en-us/sysinternals/cc835722.aspx</a>. 
      When run, Coreinfo pretty prints information about the mapping from cores
      to sockets, cores to NUMA nodes, and what kinds of caches are shared on the machine. 
      Particularly for somebody like me who is always running code on different kinds of
      machines -- and given that parallel code performance heavily depends on memory hierarchy
      -- I've found this tool to be invaluable and very helpful.  Enjoy.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=e1791031-e477-4b8c-b342-933f198ef137" />
      </div>
    </content>
  </entry>
  <entry>
    <title>UWTV talk: Microsoft's Parallel Computing Platform, Applied Research in a Product Setting</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/10/31/UWTVTalkMicrosoftsParallelComputingPlatformAppliedResearchInAProductSetting.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,48567ef1-7f9e-4e1c-834c-9c2ab18510e3.aspx</id>
    <published>2008-10-31T18:10:58.9635936-04:00</published>
    <updated>2008-10-31T18:10:58.9635936-04:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Dan Grossman invited me to deliver a talk as part of the University of Washington's
      Computer Science and Engineering Colloquia series.  It was recorded and will
      eventually air on UWTV, but has also been posted online:
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p dir="ltr" style="MARGIN-RIGHT: 0px">
            <strong>Microsoft's Parallel Computing Platform: Applied Research in a Product Setting</strong>
          </p>
          <p dir="ltr" style="MARGIN-RIGHT: 0px">
            <em>The goal of Microsoft's Parallel Computing Platform (PCP) team is to enable the
      shift to modern, multi- and manycore hardware, by providing a runtime, programming
      models, libraries, and tools that make it easy for developers to construct correct,
      efficient, maintainable, and scalable programs through the use of parallelism. In
      doing so, tens of years of industry research has been combined and applied in a myriad
      of ways. This talk examines PCP's current progress, explicitly relating it to specific
      research of the past and present, in addition to surveying future efforts and possible
      research opportunities.</em>
          </p>
          <p dir="ltr" style="MARGIN-RIGHT: 0px">
            <a href="http://norfolk.cs.washington.edu/htbin-post/unrestricted/colloq/details.cgi?id=768">http://norfolk.cs.washington.edu/htbin-post/unrestricted/colloq/details.cgi?id=768</a>
          </p>
          <p dir="ltr" style="MARGIN-RIGHT: 0px">
      &lt;<a href="http://norfolk.cs.washington.edu/htbin-post/unrestricted/colloq/details.cgi?asx=mms://videosrv6.cs.washington.edu/talks/Colloquia/high/JDuffy_081021_OnDemand_100_1064K_640x480.wmv">WMV
      - streaming</a>, <a href="http://videosrv14.cs.washington.edu/wmedia/talks/Colloquia/high/JDuffy_081021_OnDemand_100_1064K_640x480.wmv">WMV
      - download</a>, ...&gt;
   </p>
        </blockquote>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
      If you're not aware of the work we're doing in Visual Studio 2010 -- both in .NET
      4.0 and C++ -- this talk gives a pretty good overview of all of it.  It has a
      researchy feel to it, with plenty of pointers to interesting prior research that has
      influenced our work along the way.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=48567ef1-7f9e-4e1c-834c-9c2ab18510e3" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Discussion of the book and VS 2010</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/10/30/DiscussionOfTheBookAndVS2010.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,d1eb4efb-5c71-4f44-81d1-8839547dfc85.aspx</id>
    <published>2008-10-30T14:30:01.4044535-04:00</published>
    <updated>2008-10-30T14:30:01.4044535-04:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I sat down last week to record a handful of interviews with some folks from Pearson
      Education.
   </p>
        <p>
      They are now live on the InformIT website:
   </p>
        <ul>
          <li>
            <a href="http://www.informit.com/podcasts/episode.aspx?e=34303b12-61af-452a-859d-b61babcf8404">Concurrent
         Programming on Windows (my book)</a>
          </li>
          <li>
            <a href="http://www.informit.com/podcasts/episode.aspx?e=f550df75-1ac9-474e-8b0e-674fcf96774a">Visual
         Studio 2010, Part 1 of 2 - Support for Parallelism</a>
          </li>
          <li>
            <a href="http://www.informit.com/podcasts/episode.aspx?e=73fb6274-7730-4b5d-b521-63c64534cf0d">Visual
         Studio 2010, Part 2 of 2 - Tooling Support for Concurrency and Parallelism</a>
          </li>
        </ul>
        <p>
      Apologies for the Quicktime-only format.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=d1eb4efb-5c71-4f44-81d1-8839547dfc85" />
      </div>
    </content>
  </entry>
  <entry>
    <title>A few thoughts on the role of software architects</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/10/02/AFewThoughtsOnTheRoleOfSoftwareArchitects.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,727ecd54-2ccf-4fa0-a0e0-f27ee125f7ae.aspx</id>
    <published>2008-10-02T11:47:17.8572624-04:00</published>
    <updated>2008-10-02T11:47:17.8572624-04:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      The word “architect” means different things to different people in the context of
      software engineering.  And it varies wildly depending on the kind of organization
      you’re in.  An architect at a medium sized IT shop might focus on connecting
      disparate business systems together at a high level, but without diving down into
      code.  An architect at a startup may be more like a tech lead, checking in code
      like mad, but also keeping the rest of the team in check.  And a software architect
      at Microsoft can play an even varied number of roles because the company is so large
      and diversity of projects so great.
   </p>
        <p>
      A colleague and mentor of mine who I respect greatly says that an architect is the
      guy (or gal) who is in charge of making those decisions which, if made incorrectly,
      could sink the project.
   </p>
        <p>
      There is a lot to be said for this.  These decisions are those with the broadest,
      deepest, and longest lasting impact.  The decisions themselves are often made
      by team members initially, but the architect is responsible for providing constant
      and rigorous technical oversight.  Architects set the high level technical agenda,
      look ahead several releases, and keep the team on course.  They are ultimately
      to blame if the technical foundation is unsound and/or final solution fails to meet
      expectations.  Their butt is on the line.
   </p>
        <p>
      On one hand, an architect is the lead engineer with most at stake in the project. 
      On the other hand, an architect is more like a member on the project’s board of directors,
      providing high level guidance and meddling as little as possible (but as much as is
      necessary) in the day-to-day details.
   </p>
        <p>
      An architect’s success is measured by what he or she ships to customers, and not by
      the amazing ideas that were ultimately never realized.  This necessarily means
      an architect’s success is deeply rooted in the team’s culture, work ethic, and ability. 
      He or she needs to work through others to get things done.
   </p>
        <p>
      There have been some great architects throughout the course of computer science, but
      who may not have been labeled as such.  Linus Torvalds is the architect of Linux,
      and David Cutler the architect of Windows NT.  John Backus was arguably the architect
      of FORTRAN, Niklaus Wirth the architect of Pascal, Bjarne Stroustrup the architect
      of C++, James Gosling the architect of Java, and Anders Hejlsberg the architect of
      C#.  Bill Gates was the architect of Microsoft BASIC, and Charles Simonyi the
      architect of the initial versions of Microsoft Office (Word and Excel).  In each
      case, you can see that the end result is very reflective of one person’s value system
      and ideas, but took a lot more than just that person to be successful.  Each
      of these people learned to let go of their project just enough that it could achieve
      the scale that it was meant to achieve, but not so much that the project veered off
      course.  Some projects have multiple architects, but the successful ones usually
      have one who is really in charge.
   </p>
        <p>
      Already you can see some subjective opinion being thrown into the mix, and some of
      it is apt to be controversial.  Although not comprehensive, I’ve put together
      seven guiding principles that I personally aspire to.  I’ve certainly not mastered
      them all, but have always looked up those people around me who seem to have. 
      Why seven?  No reason, really.  Over the past few years, I’ve tried to spend
      as much time as possible learning from successful architects, and these stand out
      in my mind as being the key common attributes that appear to be common among them.
   </p>
        <p>
          <strong>0. Inspire and empower people to do their best work.</strong>
        </p>
        <p>
      Architects ultimately succeed or fail based on the quality of people on their team. 
      Knowing how to inspire and empower these people, so that they can do their best work,
      is therefore one of the most important skills an architect needs in order to be successful.
   </p>
        <p>
      You can’t do it all yourself.  This can be frustrating at times, and at times
      you might think that you can (particularly in times of frustration).  I’ve personally
      hacked together 1,000s of lines of code that I’m incredibly proud of in a weekend,
      and that would have taken weeks or months to get done if I had to instead explain
      the idea to somebody else and wait for them to write those same 1,000s of lines of
      code.  And the 1,000s of lines they write of course wouldn’t end up being the
      same as the ones you’d have written.  And they may decide that they don’t like
      the design after all, start discussing it with colleagues, stage a mutiny, and ultimately
      overthrow what once seemed like a great idea.  This is a tough pill to swallow. 
      But it’s a sad fact of life that you need to learn to be comfortable with.
   </p>
        <p>
      The same thing would have happened if you were the one to implement the idea, of course;
      the difference is that somebody else needs to be empowered to take the kernel of an
      idea, and run with it.  That entails reshaping it as necessary to make it realistic
      and successful.
   </p>
        <p>
      I’m not suggesting architects don’t write code (quite the opposite: see #3 below),
      but you can’t write it all (except for very small projects).  If you buy the
      argument that an architect is just the leading senior engineer on the project, then
      by definition the architect is probably qualified to write quality code quickly. 
      But what about the code they don’t write?  Other people on the team need to write
      it, and the architect needs to have enough time (where he or she isn’t hacking code)
      to inspire those people to write the right code.  This takes energy and effort. 
      You need to paint a compelling picture of the future, but with enough open-endedness
      such that the team can flex their creative muscles and fill in the details.
   </p>
        <p>
      This is the only way to scale.  And architects need to scale to achieve broad
      impact.
   </p>
        <p>
      Architects should also welcome all ideas with open arms.  You want to foster
      an open and energetic environment on your team, where intellectual debate is the norm. 
      All ideas are fair game.
   </p>
        <p>
      That’s not to say all ideas are good ones, and ultimately the bad ones need to die
      a quick and painless death before going too far, but an architect who won’t even entertain
      new ideas from the team (typically because of NIH syndrome (i.e., Not Invented Here))
      often drive away the best engineers.  Great engineers hate to be told what to
      do.  They don’t want to feel like they are walking in the shadows of somebody
      else.  They want to use the skills that make them so great, which involves inventing
      bigger, badder, and more impactful designs.  And you want them to use these skills
      too, because that’s why you hired them: these skills are crucial to the success of
      your project.  Part of your role as the team’s architect is to recognize who
      on the team has the most potential, and to arrange for them to have as much leeway
      and creative freedom as possible.  You don’t want to end up with a bunch of lackeys
      whose job is to “just implement” your ideas, because you’ll get what you paid for.
   </p>
        <p>
      It’s a true sign of success when the culture you impart unto your team allows them
      to invent things in the spirit of your own design principles, but without you needing
      to do it yourself.  Jim Gray, for example, inspired countless people to do great
      things.  Does he get credit for each of those ideas?  Of course not. 
      But was he indirectly responsible for them to some degree, and do they all have a
      little Jim Gray in them?  Absolutely.  Being an architect on a team is similar;
      not every idea has to be your own.  In fact, it’s far more powerful if few of
      them are.
   </p>
        <p>
          <strong>1. Oversight, but not dictatorship.</strong>
        </p>
        <p>
      That brings me to technical oversight.  Because an architect is typically not
      a manager for his or her project (although in some cases he or she may be), arms-length
      influence needs to be used to get things done.  In fact, the architect may have
      very little to say over specific project management, scheduling, and budget decisions,
      but is typically on the senior leadership team for the project.  So when I talk
      about “leeway” above, I’m talking about the degree to which an architect monitors
      and attempts to meddle with the progress of the team.  While it’s tempting for
      an architect to set the ship sailing to sea, and then turn around to work on the next
      big thing, this almost never works.  The initial vision and idea is far from
      a shipping solution, and software engineering only gets interesting once you actually
      try to build something.  Ideas are cheap.  The architect needs to help the
      team work through the ramifications of certain technical decisions that were made
      up front, and help with the continual course correction.
   </p>
        <p>
      Because an architect’s butt is ultimately on the line, he or she needs to work as
      fast as possible to correct problems when something goes wrong.  This implies
      the architect is involved enough to notice when something goes wrong, hopefully well
      in advance of anybody else seeing it.  I’ve seen many models that work, ranging
      from the architect being the approver for all major design decisions, to the architect
      simply reviewing all major design decisions after-the-fact, to the architect delegating
      this responsibility to trusted advisers.  For example, Linus Torvalds for the
      longest time required that all checkins to the Linux code base be reviewed by him. 
      Anders Hejlsberg still effectively approves each C# language design change. 
      In my opinion, the closer to each major decision the architect can afford to be, the
      better.
   </p>
        <p>
      Left to its own devices, the team would veer off course in no time.  That’s not
      because of malicious intent, but rather because of the sheer diversity of software
      engineers.  This diversity is present on many levels: in skill level, taste (which
      is hard to measure: more on that in #2 below), motivation, work ethic, interpretation
      of the vision, personal beliefs and experience, and so on.  An architect acts
      as a low-pass signal filter, smoothing out any irregularities that deviate too far
      from the core design principles.
   </p>
        <p>
      In Tony Hoare’s ACM Turing Award paper of 1981, The Emperor’s Old Clothes, he explains
      the risk of not providing this kind of architectural oversight:
   </p>
        <p>
      “’You know what went wrong?’ he shouted - he always shouted – ‘You let your programmers
      do things which you yourself do not understand.’ I stared in astonishment. He was
      obviously out of touch with present day realities. How could one person ever understand
      the whole of a modern software product like the Elliott 503 Mark II software system?
      I realized later that he was absolutely right; he had diagnosed the true cause of
      the problem and he had planted the seed of its later solution.”
   </p>
        <p>
      Sadly, this responsibility often entails being “the bad guy”.  Sometimes you
      need to mercilessly kill an idea because it would put certain parts of the project
      at risk.  Other times you need to let somewhat bad (but not too impactful) ideas
      go.  There’s a tradeoff here, because each time you kill an idea you’re going
      to leave somebody feeling burned.  And you may waste peoples’ time, depending
      on how much time has already been invested in that idea.  Some battles are best
      left unfought.  There is an art to be learned here: if you can get those with
      the idea to firmly believe that there has to be a better way, you can avoid being
      seen as the bad guy.  “Sit back and wait” can work in some cases, but it can
      backfire too.
   </p>
        <p>
      The deep involvement in the technical design details unfortunately means that the
      architect can become the bottleneck if he or she is not careful.  This can slow
      the team down.  Some slowdown can admittedly be a good thing, because it has
      the effect of forcing more thoughtfulness in each and every decision.  But as
      the team grows, the granularity of decision oversight necessarily has to change to
      ensure the team is empowered to make progress.  In order for this to work, you
      need to have trusted individuals who are involved at a finer granularity and will
      use the same principles and values.  This takes trust and time.
   </p>
        <p>
          <strong>2. Taste is a hard thing to measure, but is invaluable.</strong>
        </p>
        <p>
      Software engineers like to measure.  Many people try to make design decisions
      based on quantitative data, even though they know that engineering is more of an art
      than a science.  But there is one common trait that, as far as I can tell, is
      impossible to measure, and yet common to all of the great software architects I know:
      good taste.  And because it’s impossible to measure, those who lack it have a
      hard time understanding the difference between a design with good taste and one with
      bad taste.
   </p>
        <p>
      There is a certain elegance and beauty to the designs created by architects with good
      taste.  When you see it from a distance, you know it, but when viewed under a
      microscope—the kind of microscope used when debating the finer points with other engineers
      on the team—it is much harder to detect.  Often it’s incredibly difficult to
      articulate why some particular design has good taste, which makes it even harder to
      justify.  Eventually people are willing to trust your judgment because they begin
      to see it too.
   </p>
        <p>
      In fact, good taste is perhaps one of the most important skills an architect needs
      to have.  Bad taste leads to clunky designs that nobody likes to use.  Steve
      Jobs knows this.  And yet taste is probably the most difficult skill for an architect
      to develop, and one of the subtler ones that few people recognize as being necessary. 
      Many managers think that throwing more engineers at a design problem will solve it,
      when in reality often all that is necessary is one person with very good taste and
      an eye for detail.
   </p>
        <p>
      I’m not certain where taste comes from: an innate skill?  Perhaps, but not exclusively. 
      In my best estimation, good taste can be learned from paying close attention to the
      right things, taking a step back and viewing designs from afar often enough, being
      learned in what kinds of software has been built and was successful in the past, and
      having a true love of the code.  That last part sounds cheesy, but is true enough
      to reemphasize: if you don’t feel a certain passion for your code and project, it’s
      a lot easier to let bad taste run rampant, because your care level isn’t as intense
      as it needs to be.
   </p>
        <p>
          <strong>3. Write code and get your hands dirty.</strong>
        </p>
        <p>
      The best architects realize that code is king.  It rules all else.  At the
      end of the day, Visio diagrams, high level vision documents, whiteboard works of art,
      design documents, emails, functional specifications, and so on, are all a means to
      an end, not the end itself.  The code is your product, and if you don’t understand
      the code, you don’t understand the state of the project.  And if you don’t understand
      that, you’re not in a position to know what’s working well, what isn’t working, and
      you can’t possibly have the deep understanding necessary to influence the engineers
      on the team.  You’ve lost control.
   </p>
        <p>
      The worst architects couldn’t code themselves out of a cardboard box.  If you’re
      not writing actual product code, you’re not an architect: you’re an ivory tower has-been,
      and probably doing more damage than you are helping matters.  Do your team a
      favor and move into management as quickly as possible.
   </p>
        <p>
      Writing code also has the benefit of ensuring that you maintain credibility with the
      team.  It’s easy to dictate crazy and grandiose ideas, but if you’re the one
      who has to implement such a grandiose idea, you’re apt to be more sympathetic with
      and mindful of the other engineers of the team.  You need to keep yourself grounded
      and writing real product code will help to ensure your technical decision making carefully
      considers the implementability and down-to-Earth ramifications of your decisions.
   </p>
        <p>
      Moreover, you need to be a programming expert.  People need to respect your abilities,
      and you want your team to look up to you.  You want them to come and ask for
      your advice because they want it, and enjoy it, and not force them to deal with you
      simply because of your position on the team.  All of the great architects I’ve
      worked with have inspired me to grow simply because they know so damn much, and because
      I learn something new every time I interact with them.  If they didn’t write
      code and understand the nitty gritty technical esoterica, this relationship would
      have been a shallow one.
   </p>
        <p>
          <strong>4. The power of the dyad: know your weaknesses.</strong>
        </p>
        <p>
      Architects need to play a dual role in understanding both business and technical needs
      and strategy.  The degree of business savviness varies greatly among architects,
      although the best architects I know have a unique ability to understand both sides
      of the coin.  But at the end of the day, they are first and foremost technology
      wonks, and the business angle is more of a curious hobby.  In music, two notes
      sounding together form dyad, while three or more form a chord.  The best architects
      I know realize their relative weakness on the business end of things and partner up
      with another senior leader with complementary skills, to fill in the gaps: this forms
      a harmonic interval.  A dyad.
   </p>
        <p>
      The partnership needn’t entirely be “business” vs. “technical”, although in commercial
      software that’s more often than not the two opposing forces.  For example, my
      impression of the development of Scheme is that Guy Steele played the role of the
      architect while Gerald Sussman was the more business-oriented advisor, looking at
      how Scheme might be used to advance the broader research agenda but not necessarily
      meddling in the technical design details of the project.
   </p>
        <p>
      If an architect is 80% technology and 20% business, partnering with somebody who is
      20% technology and 80% business can be a killer combination.  This allows you
      to bounce ideas off one another, and to get a certain level of objective feedback
      from a different perspective.  If you’ve got a great technical idea, and bounce
      it off another techno-nerd, you might spend hours or days debating technical details
      that ultimately boil down to a matter of taste.  But if you take that same idea
      and bounce it off your business partner, he or she is likely to provide more pertinent
      feedback: does it make sense from a business perspective, will customers need it,
      will it open up new product or revenue opportunities, are there more pressing matters
      to focus the team on, etc.  These are things that, being a technology guy (or
      gal), wouldn’t immediately come to mind.  But remember: it’s all about the customer.
   </p>
        <p>
          <strong>5. It's for the customer, not you.</strong>
        </p>
        <p>
      The best engineers often succeed because they focus on scratching a personal itch. 
      That’s what Linus Torvalds, Bjarne Stroustrup, and countless others did.  This
      is why Donald Knuth created TeX.  The idea for a new technology thus begins as
      a very personal and selfish act.  “Build something you’d use yourself, and the
      customers will come” is a common (cliché) idiom.  Although there is certainly
      truth to this, it’s true only because the very fact that it is bothersome to the founding
      engineer is likely indicative that it’s bothersome to a broader set of people. 
      It’s an example, where an example is just one element in a set that is used to demonstrate
      some common attribute among all elements in that set.  Those people are your
      customers.
   </p>
        <p>
      As a technology matures, it’s important to realize—particularly when building commercial
      software—that actual human beings will want to use the technology.  It’s important
      to understand and respect their needs.  It’s important to, at some point, realize
      that you’re not, in fact, building a system entirely for your own personal use. 
      Not realizing this point can blind you and make you neglect the need to partner with
      somebody who understands the business angle of things.  It can also lead to a
      feeling of needing to develop the perfect idealized solution and never ship to customers. 
      Hey, when there are endless technical problems to work on, who would want to ship
      anyway?  By its very definition, shipping software means that you’ve solved all
      of the major technical problems within a certain scope.  What fun is that?
   </p>
        <p>
      The fun is that you’re able to make an impact on your customers’ lives, hopefully
      for the better.  Your initial technical vision has come to fruition, and you
      can move on.  You get to prove your ideas by having real human beings to use
      the end product.  If you never get to that state, then you’ve done some possibly
      interesting research—which is hopefully documented and used by somebody someday in
      the future to actually impact people by delivering a system based on those ideas—but
      you haven’t architected a product.  You’re a researcher, not an architect.
   </p>
        <p>
          <strong>6. Admit when you're wrong, fall on your sword, and then fix it.</strong>
        </p>
        <p>
      You are going to be wrong sometimes.  Trying to do big and bold things necessarily
      involves some risk.  Being an architect requires a careful balance between sticking
      to your guns—your guiding principles and technical vision—and realizing when things
      aren’t working out and course correcting before it’s too late.  It’s hard to
      tell when things are beginning to go off course, but when they’ve already gone off
      course it’s usually obvious.  A common telltale sign that things are in trouble
      is when the team no longer believes in the vision.  This may translate into attrition
      (often of your best engineers first), or just hallway grumblings.  Listen carefully. 
      If you’re not involved in the design decisions, writing code, and actually playing
      a significant role in your team’s daily lives, then you’re apt to miss this. 
      As the architect, you are responsible for responding as quickly as possible to such
      situations before the shit hits the fan.
   </p>
        <p>
      Some architects can fall into the trap of using dogma over intellect.  Firm principles
      are of course something I’ve stressed throughout this article.  But you need
      to be honest with yourself and admit when things are not going well.  An architect
      who stands at the helm of a sinking ship, proclaiming that the ship stay its course
      because the brave new world lies ahead, will only drown (alone) when the ship finally
      goes underwater.  Although this architect can then go around blaming his team
      for the failure (“if they had only seen the vision and stuck around, we would have
      succeeded”), the project will be long gone by then.  It’s harder, but more noble,
      to recognize the problems proactively and do your best to fix them.
   </p>
        <p>
      For example, Tony Hoare describes in the same ACM Turing Award paper mentioned above,
      how he felt responsible for the failure of the Elliot 503 Mark II project:
   </p>
        <p>
      “There was no escape: The entire Elliott 503 Mark II software project had to be abandoned,
      and with it, over thirty man-years of programming effort, equivalent to nearly one
      man’s active working life, and I was responsible, both as designer and as manager,
      for wasting it.”
   </p>
        <p>
      It can be particularly disturbing to realize that a large number of people have been
      going off in the wrong direction on your watch.  Yes, you wasted their time. 
      But you have to learn what went wrong, internalize it, and commit to never making
      the same mistake twice.  You owe it to them to respond promptly.  Everybody
      on the team will have learned and grown from the circumstances, and if you’re lucky
      the situation is salvageable.  Sometimes it won’t be.  But in any case you
      will gain the respect of many around you by making the right decision; particularly
      if you’re the only person with the broad technical responsibility, understanding,
      and insight necessary to make such a decision, people will feel relieved when you
      make it.  And if you don’t make it, people will curse you for it.
   </p>
        <p>
          <strong>In conclusion</strong>
        </p>
        <p>
      I’m sure there are many other laundry lists of skills people might come up with that
      are necessary to be an effective architect, but these are a few of the things
      I see and respect in the people I look up to.  I’ve named some of these
      people throughout this article.  The most common trait is that they have
      done great things and left their mark on the industry.  Being an architect, in
      the end, is all about helping others to succeed.  If you’re a really good architect,
      you’ll inspire people and rub off on them.  You’ll gain a certain level of respect
      that is unmistakable and priceless.  And that, in my opinion, is far more fulfilling
      than anything you could accomplish on your own working in a vacuum.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=727ecd54-2ccf-4fa0-a0e0-f27ee125f7ae" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Some books that I really enjoy(ed)</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/10/02/SomeBooksThatIReallyEnjoyed.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,e4a3a1f5-87d3-4012-9b50-ee06e33ddf9c.aspx</id>
    <published>2008-10-02T03:13:55.9430000-04:00</published>
    <updated>2008-10-02T03:17:26.9934649-04:00</updated>
    <category term="Books" label="Books" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      It's been quite some time since I blogged about what I've been reading.  That's
      not because I haven't been reading -- au contraire! -- but rather because I've been
      busy doing so.  I find these posts interesting for myself, so that I can look
      back and see where my interests were at a particular point in time.  Given
      the sheer number of additions, I can’t properly rate them like I have in the past. 
      Here are the more interesting ones, those that stick out in my mind:
   </p>
        <p>
          <strong>Music</strong>
        </p>
        <ul>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0520049446/bluebytesoftw-20">Theory
         of Harmony</a>, Arnold Schoenberg. 1922. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/1436697891/bluebytesoftw-20">Psychology
         of Music</a>, Carl E. Seashore. 1938. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0393002772/bluebytesoftw-20">Study
         of Counterpoint</a>, John J. Fux. 1965. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0486254399/bluebytesoftw-20">The Study
         of Fugue</a>, Alfred Mann. 1987. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/048627036X/bluebytesoftw-20">Counterpoint:
         The Polyphonic Vocal Style of the Sixteenth Century</a>, Knud Jeppessen. 1992. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0393322564/bluebytesoftw-20">Johann
         Sebastian Bach: The Learned Musician</a>, Christoph Wolff. 2001. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0306815141/bluebytesoftw-20">Guitar
         Man: A Six-String Oddyssey, or, You Love that Guitar More than You Love Me</a>, Will
         Hodgkinson. 2006. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/1400033535/bluebytesoftw-20">Musicophilia:
         Tales of Music and the Brain</a>, Oliver Sacks. 2008.</li>
        </ul>
        <p>
          <strong>Mathematics</strong>
        </p>
        <ul>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/1888009195/bluebytesoftw-20">Euclid's
         Elements</a> (Books 1 - 13). 300 BC. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0548968675/bluebytesoftw-20">The Principia
         : Mathematical Principles of Natural Philosophy</a>, Isaac Newton and Andrew Motte. 
         1846. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0691029067/bluebytesoftw-20">Introduction
         to Mathematical Logic</a>, Alonzo Church.  1944. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/B000X7O2RM/bluebytesoftw-20">Foundations
         of Algebraic Topology</a>, Samuel Eilenberg and Norman Steenrod.  1952.  
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0486634620/bluebytesoftw-20">Foundations
         of Mathematical Logic</a>, Haskell B. Curry.  1963. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/1406763144/bluebytesoftw-20">Diophantus
         Of Alexandria -A Study In The History Of Greek Algebra</a>, Sir Thomas L. Heath. 
         1964. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/1568812736/bluebytesoftw-20">From
         Zero to Infinity: What Makes Numbers Interesting</a>, Constance Reid.  1964. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0452287839/bluebytesoftw-20">Euclid
         in the Rainforest: Discovering Universal Truth in Logic and Math</a>, Joseph Mazur. 
         2006. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0452288533/bluebytesoftw-20">Unknown
         Quantity: A Real and Imaginary History of Algebra</a>, John Derbyshire.  2007. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/B001FA23KE/bluebytesoftw-20">God Created
         the Integers: The Mathematical Breakthroughs that Changed History</a>, Stephen Hawking. 
         2007. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0812978714/bluebytesoftw-20">Infinite
         Ascent: A Short History of Mathematics (Modern Library Chronicles)</a>, David Berlinski. 
         2008.</li>
        </ul>
        <p>
          <strong>Computers</strong>
        </p>
        <ul>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0262130114/bluebytesoftw-20">LISP
         1.5 Programmer's Manual</a>, John McCarthy. 1962. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/B0006BQD4U/bluebytesoftw-20">Computation:
         Finite and Infinite Machines</a>, Marvin Lee Minsky. 1967. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0139145567/bluebytesoftw-20">The Theory
         of Parsing, Translation, and Compiling (Volume I: Parsing)</a>, Alfred V. Aho and
         Jeffrey D. Ullman. 1972. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0139145648/bluebytesoftw-20">The Theory
         of Parsing, Translation, and Compiling (Volume II: Compiling)</a>, Alfred V. Aho and
         Jeffrey D. Ullman. 1973. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0130224189/bluebytesoftw-20">Algorithms
         + Data Structures = Programs</a>, Niklaus Wirth 1976. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/013215871X/bluebytesoftw-20">A Discipline
         of Programming</a>, Edsger W. Dijkstra. 1976. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0130446289/bluebytesoftw-20">Architecture
         of Concurrent Programs</a>, Per Brinch Hansen. 1977. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0070342075/bluebytesoftw-20">The Elements
         of Programming Style</a>, Brian W. Kernighan and P. J. Plauger. 1978. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0465046746/bluebytesoftw-20">Mindstorms:
         Children, Computers, And Powerful Ideas</a>, Seymour Papert. 1980. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0387906525/bluebytesoftw-20">Selected
         Writings on Computing: A Personal Perspective</a>, Edsger W. Dijkstra. 1982. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/354010836X/bluebytesoftw-20">CLU:
         Reference Manual (Lecture Notes in Computer Science)</a>, B. Liskov, et al. 1983. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0130220051/bluebytesoftw-20">Algorithms
         and Data Structures</a>, Niklaus Wirth.  1985. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0131532715/bluebytesoftw-20">Communicating
         Sequential Processes</a>, C. A. R. Hoare. 1985. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0023397632/bluebytesoftw-20">The Little
         LISPer, Third Edition</a>, Daniel P. Friedman and Matthias Felleisen. 1989. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/1555580416/bluebytesoftw-20">Common
         LISP, The Language, Second Edition</a>, Guy Steele. 1990. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0262610949/bluebytesoftw-20">The High
         Performance FORTRAN Handbook</a>, Charles H. Koelbel, et. Al. 1993. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0070158401/bluebytesoftw-20">201 Principles
         of Software Development</a>, Alan M. Davis. 1995. 
      </li>
          <li>
            <a href="http://www.amazon.com/exec/obidos/ASIN/0817638806/bluebytesoftw-20">Algol-like
         Languages (Progress in Theoretical Computer Science)</a>, Peter O’Hearn and Robert
         Tennent.  1996.</li>
        </ul>
        <p>
      Based on this list, you might surmise that I read a lot.  ;)  In fact, I
      typically have between 3 and 5 books going simultaneously (how parallel of me), so
      I use the term "read" somewhat nontraditionally.  I prefer to absorb the information
      by immersing myself in many books in the same genre simultaneously, instead of committing
      to a single one.  This seems to be effective, but is also slightly odd and perhaps
      quite esoteric to other people; the result is that every room in my home is littered
      with books each in some possibly long-forgotten state of being "read" (along with
      tattered academic papers, language manuals, etc).  I like it, but some people
      believe this is an indication that I’m a tad insane.  C’est la vie.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=e4a3a1f5-87d3-4012-9b50-ee06e33ddf9c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Overdose on parallelism goodness in MSDN Magazine</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/10/02/OverdoseOnParallelismGoodnessInMSDNMagazine.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,fe25f51a-c8b4-4839-99cc-1537a436d42f.aspx</id>
    <published>2008-10-02T00:25:50.1393343-04:00</published>
    <updated>2008-10-02T00:25:50.1393343-04:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      The October 2008 MSDN Magazine issue just went live with <a href="http://msdn.microsoft.com/en-us/magazine/cc992993.aspx">5
      articles on concurrency</a>, plus the <a href="http://msdn.microsoft.com/en-us/magazine/cc966710.aspx">editor's
      note</a>.  Four of the articles are written by members of the Parallel Computing
      team here at Microsoft, including one by me:
   </p>
        <ul>
          <li>
            <a href="http://msdn.microsoft.com/en-us/magazine/cc872852.aspx">
              <strong>Paradigm
         Shift: Design Considerations for Parallel Programming</strong>
            </a>, by David Callahan. 
         David is the dinstinguished engineer responsible for setting the overall direction
         for the Parallel Computing team (a group of ~100 people) and indeed the whole company
         vis-a-vis parallelism.</li>
          <li>
            <a href="http://msdn.microsoft.com/en-us/magazine/cc817396.aspx">
              <strong>Coding Tools:
         Improved Support for Parallelism In the Next Version of Visual Studio</strong>
            </a>,
         by Stephen Toub and Hazim Shafi.  Yes, we'll actually have IDE support for all
         of the cool new stuff we're shipping.</li>
          <li>
            <a href="http://msdn.microsoft.com/en-us/magazine/cc817398.aspx">
              <strong>Concurrency
         Hazards: Solving 11 Likely Problems in Your Multithreaded Code</strong>
            </a>, by yours
         truly.  Although we make things simpler in many regards, there are still some
         gotchas to be aware of when writing parallel code.</li>
          <li>
            <a href="http://msdn.microsoft.com/en-us/magazine/cc872851.aspx">
              <strong>.NET Matters:
         False Sharing</strong>
            </a>, by Stephen Toub, Igor Ostrovsky, and Huseyin Yildiz. 
         It's surprising sometimes how much of a bottleneck the memory system can become in parallel
         programs, and this article offers some insight and tips about how to deal with it.</li>
        </ul>
        <p>
      Enjoy the text, and be careful not to overdose on the excess of parallelism goodness.
      This edition was timed intentionally to coincide with the PDC.  I'm hoping to
      see you there, because we have a plethora of exciting things to show, spanning managed
      .NET and native C++ programming.  These articles are really just teasers.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=fe25f51a-c8b4-4839-99cc-1537a436d42f" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Upcoming talks</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/09/26/UpcomingTalks.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,f9c31afc-bd38-482f-9eb3-cfd04fe15f97.aspx</id>
    <published>2008-09-26T15:12:01.9735848-04:00</published>
    <updated>2008-09-26T15:12:01.9735848-04:00</updated>
    <category term="Miscellaneous" label="Miscellaneous" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I just returned from TechEd Australia, which was a lot of fun.
   </p>
        <p>
      I have a fair number of additional speaking engagements coming up:
   </p>
        <ul>
          <li>
         JAOO in Aarhus, Denmark (next week) [<a href="http://jaoo.dk/conference/">http://jaoo.dk/conference/</a>]:
         Parallel Extensions</li>
          <li>
         PDC in LA (precon on Oct 26) [<a href="http://www.microsoftpdc.com/">http://www.microsoftpdc.com/</a>]:
         Concurrency pre-con</li>
          <li>
         TechEd EMEA in Barcelona (Nov 10-14) [<a href="http://www.microsoft.com/emea/teched2008/">http://www.microsoft.com/emea/teched2008/</a>]:
         Parallel Extensions</li>
          <li>
         QCON in San Francisco, (Nov 19-21) [<a href="http://qconsf.com/sf2008/conference/">http://qconsf.com/sf2008/conference/</a>]:
         Functional programming and parallelism</li>
        </ul>
        <p>
      As of the PDC <a href="http://www.bluebytesoftware.com/books/winconc/winconc_book_resources.html">the
      book</a> will also be readily available.  Wahoo!
   </p>
        <p>
      If you'll be at any of the conferences and want to meet up, please drop me a
      line.
   </p>
        <img width="0" height="0" src="http://www.bluebytesoftware.com/blog/aggbug.ashx?id=f9c31afc-bd38-482f-9eb3-cfd04fe15f97" />
      </div>
    </content>
  </entry>
  <entry>
    <title>The cost of enumerating in .NET</title>
    <link rel="alternate" type="text/html" href="http://www.bluebytesoftware.com/blog/2008/09/21/TheCostOfEnumeratingInNET.aspx" />
    <id>http://www.bluebytesoftware.com/blog/PermaLink,guid,04dace30-6d35-4be0-b0e7-60d6d6ce9b2a.aspx</id>
    <published>2008-09-21T03:14:58.0400000-04:00</published>
    <updated>2008-09-21T03:25:16.8385504-04:00</updated>
    <category term="Technology" label="Technology" scheme="dasBlog" />
    <content type="html">&lt;p&gt;
   The enumeration pattern in .NET unfortunately implies some overhead that makes it
   difficult to compete with ordinary for loops.&amp;nbsp; In fact, the difference between
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;T[]
   a = …;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;for
   (int i = 0, c = a.Length; i &amp;lt; c; i++) …action(a[i])…;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   and
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;T[]
   a = …;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IEnumerator&amp;lt;int&amp;gt;
   ae = ((IEnumerable&amp;lt;T&amp;gt;)a).GetEnumerator();&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;while
   (ae.MoveNext()) …action(ae.Current)…;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;p&gt;
   is about 3X.&amp;nbsp; That is, the former is 1/3rd the expense of the latter, in terms
   of raw enumeration overhead.&amp;nbsp; Clearly as action becomes more expensive the significance
   of this overhead lessens.&amp;nbsp; But if your plan is to invoke a small action over
   a large number of elements, using an enumerator instead of indexing directly into
   the array could in fact cause your algorithm to&amp;nbsp;take 3X longer to finish.
&lt;/p&gt;
&lt;p&gt;
   There are many reasons for this problem.&amp;nbsp; They are probably obvious.&amp;nbsp; Using
   an enumerator requires at least two interface method calls just to extract a single
   element from the array.&amp;nbsp; Because there are O(length) number of these operations,
   the overhead imposed will be O(length) as well.&amp;nbsp; Contrast that with the nice,
   compact for loop, which emits ldarg IL instructions that access the array directly.&amp;nbsp;
   This will end up computing some offset (e.g., i * sizeof(T)) and dereferencing right
   into the array memory.&amp;nbsp; The enumerator needs to do that, of course, but only
   after the two interface calls are made.&amp;nbsp; Additionally, it is possible for the
   JIT compiler to omit the bounds check on the array access if it knows ‘c’ in the predicate
   ‘i &amp;lt; c’ was computed from ‘a.Length’, because arrays in .NET are immutable and
   their size cannot change.
&lt;/p&gt;
&lt;p&gt;
   (Strangely, it appears going through IList&amp;lt;T&amp;gt; is even slower than enumeration.&amp;nbsp;
   In fact, it appears to be more than 3X the cost of going through IList&amp;lt;T&amp;gt;’s
   enumerator, and over 10X that of indexing into the array using true ldarg instructions
   instead of interface calls to IList&amp;lt;T&amp;gt;’s element indexer.)
&lt;/p&gt;
&lt;p&gt;
   All of this actually makes it somewhat difficult for those on my team building PLINQ
   to compete with hand written programs.&amp;nbsp; That’s true of LINQ generally.&amp;nbsp;
   In fact, LINQ tends to be worse, because you string several enumerators together to
   form a query, often leading to even more overhead attributed to enumeration.&amp;nbsp;
   So you might reasonably wonder: if people care about performance, then why would they
   willingly start off 3X “in the hole” in hopes that they will eventually gain it back
   when they use machines with &amp;gt;= 4 cores?&amp;nbsp; It’s a completely fair criticism
   (although you must recall that everything I’m talking about is “pure overhead” and
   once you begin to have sizable computations in the per-element action it matters less
   and less).&amp;nbsp; We continually do a lot of work to try to recoup these costs.
&lt;/p&gt;
&lt;p&gt;
   There are actually many alternative enumeration models, and I think .NET needs to
   change direction in the future.&amp;nbsp; In addition to the overhead associated with
   the pattern, .NET’s enumeration pattern is a “pull” model (versus “push”), which makes
   it incredibly hard to tolerate blocking within calls to MoveNext.&amp;nbsp; Over time,
   I think we will need to pursue the push model more seriously.
&lt;/p&gt;
&lt;p&gt;
   I’ve thrown together a few different examples of alternative enumeration techniques.&amp;nbsp;
   To cut to the chase, here is a simple micro-benchmark test that enumerates over 1,000,000
   elements 25 times, invoking an empty (non-inlineable) method for each element.&amp;nbsp;
   The per-element work here is quite small (although not empty) and so the results are
   a bit more extreme than a real workload would show:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;739255
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;% of baseline&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (IList&amp;lt;int&amp;gt;)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;7534609
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1019.216%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;ForEach
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;829617 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;112.2234%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;int[]
   IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;2152414 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;291.1599%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;2062876
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;279.048%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IFastEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1758992
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;237.9412%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [s]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1103745 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;149.305%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [i] &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;976742 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;132.1252%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable2&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;957883
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;129.5741%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
   These are:
&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;
      “For loop (int[])” is an ordinary for loop over the array directly. 
   &lt;li&gt;
      “For loop (IList&amp;lt;int&amp;gt;)” is an ordinary for loop over the array’s IList&amp;lt;T&amp;gt;
      interface. 
   &lt;li&gt;
      “ForEach loop (int[])” is an ordinary foreach loop over the array directly. 
   &lt;li&gt;
      “int[] IEnumerator&amp;lt;int&amp;gt;” uses the array’s implementation of IEnumerator&amp;lt;T&amp;gt;. 
   &lt;li&gt;
      “IEnumerator&amp;lt;int&amp;gt;” is a custom IEnumerator&amp;lt;T&amp;gt; implementation. 
   &lt;li&gt;
      “IFastEnumerator&amp;lt;int&amp;gt;” is an implementation of new pull interface (defined below). 
   &lt;li&gt;
      “IForEachable&amp;lt;int&amp;gt;” is an implementation of a new push interface (defined below)
      that uses delegates to represent the per-element action.&amp;nbsp; The only difference
      between the “[s]” and “[i]” variants are that the delegate is bound to a static method
      for “[s]” and an instance method for “[i]”. 
   &lt;li&gt;
      “IForEachable2&amp;lt;int&amp;gt;” is a slight variant of IForEachable&amp;lt;T&amp;gt; (also defined
      below).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   Notice that with IForEachable2&amp;lt;T&amp;gt;, we’ve gotten within 30% of the efficient
   for loop.&amp;nbsp; Unfortunately, I do get somewhat different numbers when compiling
   with the /o+ switch:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;777746
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;% of baseline&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (IList&amp;lt;int&amp;gt;)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;7569517
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;973.2634%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;ForEach
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;735846 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;94.61264%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;int[]
   IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;2340361 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;300.9159%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;2063039
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;265.2587%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IFastEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1806568
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;232.2825%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [s]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1090644 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;140.2314%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [i]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;946090 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;121.6451%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable2&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1234201
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;158.6895%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;p&gt;
   For comparison purposes, I get numbers like this if the loop body is completely empty
   except for accessing the current element:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;452039
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;% of baseline&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (IList&amp;lt;int&amp;gt;)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;422732
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;93.51671%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;ForEach
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;461274 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;102.043%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;int[]
   IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;1958711 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;433.3058%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1730502
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;382.8214%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IFastEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1372421
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;303.6068%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [s]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1091720 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;241.5101%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [i]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;958401 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;212.0173%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable2&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;664572
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;147.0165%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;p&gt;
   And this (with /o+):
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;262146
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;% of baseline&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;For
   loop (IList&amp;lt;int&amp;gt;)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;263302
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;100.441%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;ForEach
   loop (int[])&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;372924 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;142.2581%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;int[]
   IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;1889132 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;720.6412%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1635837
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;624.0175%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IFastEnumerator&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1479579
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;564.4103%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [s]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;1096712 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;418.3592%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable&amp;lt;int&amp;gt;
   [i]&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;962261 tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;367.0706%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;IForEachable2&amp;lt;int&amp;gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;698340
   tcks&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;266.3935%&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;p&gt;
   These numbers aren’t quite as meaningful because we have no idea what’s being optimized
   away by the C# and JIT compilers.&amp;nbsp; For example, they may notice we’re not using
   the current element at all and therefore eliminate the access altogether.&amp;nbsp; Nevertheless,
   the relative ranking of efficiency has remained nearly the same (with the notable
   exception of the array’s IList&amp;lt;T&amp;gt; test being much less worse).
&lt;/p&gt;
&lt;p&gt;
   (All of these numbers were gathered on a 32-bit OS on a 64-bit machine.&amp;nbsp; Because
   the JIT compilers for 32-bit and 64-bit are so different, you can expect vastly different
   results across architectures.)
&lt;/p&gt;
&lt;p&gt;
   Anyway, here is what IFastEnumerator&amp;lt;T&amp;gt;, IForEachable&amp;lt;T&amp;gt;, and IForEachable2&amp;lt;T&amp;gt;
   look like:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;interface
   IFastEnumerable&amp;lt;T&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;IFastEnumerator&amp;lt;T&amp;gt;
   GetEnumerator();&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;interface
   IFastEnumerator&amp;lt;T&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;bool
   MoveNext(ref T elem);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;interface
   IForEachable&amp;lt;T&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;void
   ForEach(Action&amp;lt;T&amp;gt; action);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;
   &lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;interface
IForEachable2&amp;lt;T&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: Consolas; mso-bidi-font-family: Tahoma"&gt;&lt;font color=#000000&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span