<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jon Skeet: Coding Blog : General</title><link>http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx</link><description>Tags: General</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Where do you benefit from dynamic typing?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/17/where-do-you-benefit-from-dynamic-typing.aspx</link><pubDate>Tue, 17 Nov 2009 07:31:48 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1740168</guid><dc:creator>skeet</dc:creator><slash:comments>48</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1740168</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1740168</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/17/where-do-you-benefit-from-dynamic-typing.aspx#comments</comments><description>&lt;p&gt;Disclaimer: I don&amp;#39;t want this to become a flame war in the comments. I&amp;#39;m coming from a position of ignorance, and well aware of it. While I&amp;#39;d like this post to provoke &lt;em&gt;thought&lt;/em&gt;, it&amp;#39;s not meant to be provocative in the common use of the term.&lt;/p&gt;  &lt;p&gt;Chapter 14 of C# in Depth is about dynamic typing in C#. A couple of reviewers have justifiably said that I&amp;#39;m fairly keen on the mantra of &amp;quot;don&amp;#39;t use dynamic typing unless you need it&amp;quot; – and that possibly I&amp;#39;m doing dynamic typing a disservice by not pointing out more of its positive aspects. I completely agree, and I&amp;#39;d love to be more positive – but the problem is that I&amp;#39;m not (yet) convinced about why dynamic typing is something I &lt;em&gt;would&lt;/em&gt; want to embrace.&lt;/p&gt;  &lt;p&gt;Now I want to start off by making something clear: this is meant to be about dynamic typing. Often advocates for dynamically typed languages will mention:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Read-eval-print_loop"&gt;REPL&lt;/a&gt; (read-eval-print-loop) abilities which allow for a very fast feedback loop while experimenting&lt;/li&gt;    &lt;li&gt;Terseness – the lack of type names everywhere makes code shorter&lt;/li&gt;    &lt;li&gt;Code evaluated at execution time (so config files can be scripts etc)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I don&amp;#39;t count any of these as benefits of dynamic typing per se. They&amp;#39;re benefits which often come alongside dynamic typing, but they&amp;#39;re not dependent on dynamic typing. The terseness argument is the one most closely tied to their dynamic nature, but various languages with powerful type inference show that being statically typed doesn&amp;#39;t mean having to specify type names everywhere. (C#&amp;#39;s &lt;em&gt;var&lt;/em&gt; keyword is a very restricted form of type inference, compared with – say – that of F#.)&lt;/p&gt;  &lt;p&gt;What I&amp;#39;m talking about is binding being performed at execution time and &lt;em&gt;only&lt;/em&gt; at execution time. That allows for:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Duck typing&lt;/li&gt;    &lt;li&gt;Dynamic reaction to previously undeclared messages&lt;/li&gt;    &lt;li&gt;Other parts of dynamic typing I&amp;#39;m unaware of (how could there not be any?)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;What I&amp;#39;m interested in is how often these are used within &lt;em&gt;real world&lt;/em&gt; (rather than demonstration) code. It may well be that I&amp;#39;m suffering from &lt;a href="http://c2.com/cgi/wiki?BlubParadox"&gt;Blub&amp;#39;s paradox&lt;/a&gt; – that I can&amp;#39;t see the valid uses of these features simply because I haven&amp;#39;t used them enough. Just to be clear, I&amp;#39;m not saying that I &lt;em&gt;never&lt;/em&gt; encounter problems where I would welcome dynamic typing – but I don&amp;#39;t run into them every day, whereas I get help from the compiler every day.&lt;/p&gt;  &lt;p&gt;Just as an indicator of how set in my statically typed ways I am, at the recent Stack Overflow DevDays event in London, Michael Sparks went through &lt;a href="http://norvig.com/spell-correct.html"&gt;Peter Norvig&amp;#39;s spelling corrector&lt;/a&gt;. It&amp;#39;s a neat piece of code (and yes, I&amp;#39;ll finish that port some time) but I kept finding it hard to understand simply because the types weren&amp;#39;t spelled out. Terseness can certainly be beneficial, but in this case I would personally have found it simpler if the variable and method types had been explicitly declared.&lt;/p&gt;  &lt;p&gt;So, for the dynamic typing fans (and I&amp;#39;m sure several readers will come into that category):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;How often do you take advantage of dynamic typing in a way that really wouldn&amp;#39;t be feasible (or would be very clunky) in a statically typed language?&lt;/li&gt;    &lt;li&gt;Is it usually the same single problem which crops up regularly, or do you find a wide variety of problems benefit from dynamic typing?&lt;/li&gt;    &lt;li&gt;When you declare a variable (or first assign a value to a variable, if your language doesn&amp;#39;t use explicit declarations) how often do you really either not know its type or want to use some aspect of it which wouldn&amp;#39;t typically have been available in a statically typed environment?&lt;/li&gt;    &lt;li&gt;What balance do you find in your use of duck typing (the same method/member/message has already been declared on multiple types, but there&amp;#39;s no common type or interface) vs truly dynamic reaction based on introspection of the message within code (e.g. building a query based on the name of the method, such as FindBooksByAuthor(&amp;quot;Josh Bloch&amp;quot;))?&lt;/li&gt;    &lt;li&gt;What aspects of dynamic typing do I appear to be completely unaware of?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Hopefully someone will be able to turn the light bulb on for me, so I can be more genuinely enthusiastic about dynamic typing, and perhaps even diversify from my comfort zone of C#…&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1740168" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category></item><item><title>Just how spiky is your traffic?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/16/just-how-spiky-is-your-traffic.aspx</link><pubDate>Mon, 16 Nov 2009 19:48:19 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1740046</guid><dc:creator>skeet</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1740046</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1740046</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/16/just-how-spiky-is-your-traffic.aspx#comments</comments><description>&lt;p&gt;No, this isn&amp;#39;t the post about dynamic languages I promise. That will come soon. This is just a quick interlude. This afternoon, while answering a question on Stack Overflow&lt;sup&gt;1&lt;/sup&gt; about the difference between using an array and a Dictionary&amp;lt;string, string&amp;gt; (where each string was actually the string representation of an integer) I posted the usual spiel about preferring readable code to micro-optimisation. The response in a comment - about the performance aspect - was:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Well that&amp;#39;s not so easily said for a .com where performance on a site that receives about 1 million hits a month relies on every little ounce of efficiency gains you can give it.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;A million hits a month, eh? That sounds quite impressive, until you actually break it down. Let&amp;#39;s take a month of 30 days - that has 30 * 24 * 60 * 60 = 2,592,000 seconds&lt;sup&gt;2&lt;/sup&gt;. In other words, a million hits a month is less than one hit every two seconds. Not so impressive. At Google we tend to measure traffic in QPS (queries per second, even if they&amp;#39;re not really queries - the search terminology becomes pervasive) so this is around 0.39 QPS. Astonished that someone would make such a claim in favour of micro-optimisation at that traffic level, I &lt;a href="http://twitter.com/jonskeet/status/5767353745"&gt;tweeted about it&lt;/a&gt;. Several of the replies were along the lines of &amp;quot;yeah, but traffic&amp;#39;s not evenly distributed.&amp;quot; That&amp;#39;s entirely true. Let&amp;#39;s see how high we can make the traffic without going absurd though.&lt;/p&gt;  &lt;p&gt;Let&amp;#39;s suppose this is a site which is only relevant on weekdays - that cuts us down to 20 days in the month. Now let&amp;#39;s suppose it&amp;#39;s only relevant for one hour per day - it&amp;#39;s something people look at when they get to work, and most of the users are in one time zone. That&amp;#39;s a pretty massive way of spiking. We&amp;#39;ve gone down from 30 full days of traffic to 20 hours - or 20 * 60 * 60 = 72000 seconds, giving 14 QPS. Heck, let&amp;#39;s say the peak of the spike is double that - a whopping 28 QPS.&lt;/p&gt;  &lt;p&gt;Three points about this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;28 QPS is still not a huge amount of traffic.&lt;/li&gt;    &lt;li&gt;If you&amp;#39;re &lt;em&gt;really&lt;/em&gt; interested in handling peak traffic of ~28 QPS without latency becoming huge, it&amp;#39;s worth quoting &lt;em&gt;that&lt;/em&gt; figure rather than &amp;quot;a million hits a month&amp;quot; because the latter is somewhat irrelevant, and causes us to make wild (and probably wildly inaccurate) guesses about your load distribution.&lt;/li&gt;    &lt;li&gt;If you&amp;#39;re going to bring the phrase &amp;quot;a .com&amp;quot; into the picture, attempting to make it sound particularly important, you really shouldn&amp;#39;t be thinking about hosting your web site on one server - so the QPS gets diluted again.&lt;/li&gt;    &lt;li&gt;Even at 28 QPS, the sort of difference that would be made here is tiny. A quick microbenchmark (with all the associated caveats) showed that on my laptop (hardly a server-class machine) I could build the dictionary and index into it 3 times 2.8 &lt;em&gt;million&lt;/em&gt; times in about 5 seconds. If every request needed to do that 100 times, then the cost of doing it 28 requests per second on my laptop would still only be 0.5% of that second - not a really significant benefit, despite the hugely exaggerated estimates of how often we needed to do that.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are various other ways in which it&amp;#39;s not a great piece of code, but the charge against premature optimization still stands. You &lt;em&gt;don&amp;#39;t&lt;/em&gt; need to get every little ounce of efficiency out of your code. Chances are, if you start guessing at where you can get efficiency, you&amp;#39;re going to be wrong. Measure, measure, measure - profile, profile, profile. Once you&amp;#39;ve done all of that and proved that a change reducing clarity has a significant benefit, go for it - but until then, write the most readable code you can. Likewise work out your performance goals in a &lt;em&gt;meaningful&lt;/em&gt; fashion before you worry too much - and hits per months isn&amp;#39;t a meaningful figure.&lt;/p&gt;  &lt;p&gt;Performance is important - too important to be guessed about instead of measured.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; I&amp;#39;m not linking to it because the Streisand effect would render this question more important than it really is. I&amp;#39;m sure you can find it if you really want to, but that&amp;#39;s not the point of the post.&lt;/p&gt;  &lt;p&gt;&lt;sup&gt;2&lt;/sup&gt; Anyone who wants to nitpick and talk about months which are a bit longer or shorter than that due to daylight saving time changes (despite still being 30 days) can implement that logic for me in Noda Time.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1740046" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Noda Time gets its own blog</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/13/noda-time-gets-its-own-blog.aspx</link><pubDate>Fri, 13 Nov 2009 19:54:48 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1739567</guid><dc:creator>skeet</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1739567</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1739567</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/13/noda-time-gets-its-own-blog.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve decided it&amp;#39;s probably not a good idea to make general Noda Time posts on my personal blog. I&amp;#39;ll still post anything that&amp;#39;s particularly interesting in a &amp;quot;general coding&amp;quot; kind of way here, even if I discover it in Noda Time, but I thought it would be good for the project to have a &lt;a href="http://noda-time.blogspot.com/"&gt;blog of its very own&lt;/a&gt;, which other team members can post to.&lt;/p&gt;  &lt;p&gt;I still have plenty of things I want to blog about here. Next up is likely to be a request for help: I want someone to tell me why I should love the &amp;quot;dynamic&amp;quot; bit of dynamic languages. Stay tuned for more details :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1739567" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category></item><item><title>What's in a name (again)?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/11/05/what-s-in-a-name-again.aspx</link><pubDate>Thu, 05 Nov 2009 20:01:05 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1737867</guid><dc:creator>skeet</dc:creator><slash:comments>54</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1737867</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1737867</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/11/05/what-s-in-a-name-again.aspx#comments</comments><description>&lt;p&gt;I have possibly foolishly decided to stop resisting the urge to port &lt;a href="http://joda-time.sf.net"&gt;Joda Time&lt;/a&gt; to .NET. For those of you who are unaware, &amp;quot;use Joda Time&amp;quot; is almost always the best answer to any question involving &amp;quot;how do I achieve X with java.util.Date/Calendar?&amp;quot; It&amp;#39;s a Java library for handling dates and times, and it rocks. There is a plan to include a somewhat redesigned version in some future edition of Java (&lt;a href="https://jsr-310.dev.java.net/"&gt;JSR-310&lt;/a&gt;) but it&amp;#39;s uncertain whether this will ever happen.&lt;/p&gt;  &lt;p&gt;Now, .NET only gained the ability to work with time zones other than UTC and the local time zone (using only managed code) – it has a bit of catching up to do. It&amp;#39;s generally easier to work with the .NET BCL than the Java built-in libraries, but it&amp;#39;s still not a brilliant position to be in. I think .NET deserves good date/time support, and as no-one else appears to be porting Joda Time, I&amp;#39;m going to do it. (A few people have already volunteered to help. I don&amp;#39;t know how easily we&amp;#39;ll be able to divvy up the work, but we&amp;#39;ll see. I suspect the core may need to be done first, and then people can jump in to implement different chronologies etc. As a side-effect, I may try to use this project as a sort of case in terms of porting, managing an open source project, and properly implementing a .NET library with useful versioning etc.)&lt;/p&gt;  &lt;p&gt;The first two problems, however, are to do with naming. First, the project name. Contenders include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Joda Time.NET (sounds like it would be an absolutely direct port; while I intend to port all the tricky bits directly, it&amp;#39;s going to be an idiomatic port with appropriate .NET bits. It&amp;#39;s also a bit of a mouthful.) &lt;/li&gt;    &lt;li&gt;Noda Time (as suggested in the comments and in email)&lt;/li&gt;    &lt;li&gt;TonyTime (after &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/11/02/omg-ponies-aka-humanity-epic-fail.aspx"&gt;Tony the Pony&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;CoffeeTime &lt;/li&gt;    &lt;li&gt;TeaTime &lt;/li&gt;    &lt;li&gt;A progression of BreakfastTime, CoffeeTime, LunchTime, TeaTime, DinnerTime and SupperTime for different versions (not a serious contender) &lt;/li&gt;    &lt;li&gt;ParsleySageRosemaryAndThyme (not a serious contender) &lt;/li&gt;    &lt;li&gt;A few other silly ones too &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I suspect I&amp;#39;m going to go for CoffeeTime, but we&amp;#39;ll see.&lt;/p&gt;  &lt;p&gt;The second problem is going to prove more awkward. I want to mostly copy the names given in Joda Time – aside from anything else, it&amp;#39;ll make it familiar to anyone who uses Joda Time in Java (such as me). Now one of the most commonly used classes in Joda is &amp;quot;&lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/DateTime.html"&gt;DateTime&lt;/a&gt;&amp;quot;. Using that name in my port would be a Bad Idea. Shadowing a name in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.aspx"&gt;System&lt;/a&gt; namespace is likely to lead to very disgruntled users who may prove hard to regruntle before they abandon the library.&lt;/p&gt;  &lt;p&gt;So what do I do? Go for the subtly different DateAndTime? Tie it to the library with CoffeeDateTime? Change it to Instant? (It&amp;#39;ll derive from AbstractInstant anyway – assuming I keep the same hierarchy instead of moving to a composition model and value types.)&lt;/p&gt;  &lt;p&gt;Obviously this is a decision which the &amp;quot;team&amp;quot; can make, when we&amp;#39;ve got one… but it feels like a decision which is lurking round the corner in a hostile way.&lt;/p&gt;  &lt;p&gt;What I find interesting is that these are two very different naming problems: one is trying to name something in a relatively arbitrary way – I know I want something reasonably short and memorable for the overall name, but beyond that it doesn&amp;#39;t matter too much. The other is trying to nail a very specific name which really &lt;em&gt;has&lt;/em&gt; to convey its meaning clearly… but where the obvious name is already taken. Also interestingly, neither is a particularly good example of my most common issue with naming: attempting to come up with a two or three word noun for something that actually needs a whole sentence to describe it adequately.&lt;/p&gt;  &lt;p&gt;Oh well – we&amp;#39;ll see what happens. In another blog post I&amp;#39;ll suggest some of the goals I have in terms of what I&amp;#39;m hoping to learn from the project, and how I&amp;#39;d like it to progress. In other words, expect a work of complete fiction…&lt;/p&gt;  &lt;p&gt;If you&amp;#39;re interested in helping out with the project, please &lt;a href="mailto:skeet@pobox.com"&gt;mail me directly&lt;/a&gt; (rather than adding comments here) and as soon as I&amp;#39;ve set the project up, I&amp;#39;ll invite you to the mailing list.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;UPDATE: &lt;/strong&gt;I&amp;#39;ve already got a few interested names, which is great. Rather than be dictatorial about this, I&amp;#39;ll put it to a vote of the people who are willing to help out on it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1737867" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category></item><item><title>MVP Again</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/10/30/mvp-again.aspx</link><pubDate>Fri, 30 Oct 2009 21:14:09 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1736410</guid><dc:creator>skeet</dc:creator><slash:comments>28</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1736410</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1736410</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/10/30/mvp-again.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m delighted to be able to announce that I&amp;#39;m now an MVP again.&lt;/p&gt;  &lt;p&gt;Google has reconsidered the situation and worked out a compromise: I now receive no significant gifts from Microsoft, and I&amp;#39;m not under NDA with them. While that precludes me from a lot of MVP activities, it removes any concerns to do with Google&amp;#39;s &lt;a href="http://investor.google.com/conduct.html#III"&gt;Code of Conduct&lt;/a&gt;. Basically my MVP status is truly just a token of Microsoft&amp;#39;s recognition of what I&amp;#39;ve done in the C# community - and that&amp;#39;s fine by me.&lt;/p&gt;  &lt;p&gt;When I &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/10/01/mvp-no-more.aspx"&gt;announced&lt;/a&gt; that I&amp;#39;d been advised not to seek renewal, I was amazed at the scale of the reaction in the comments, other blog posts, Twitter and personal email. I was touched by the response of the community. I really love working at Google, and the fact that we could figure out a solution to this situation is definitely one of the things that makes Google such an awesome place to work. Oh, and did I mention that &lt;a href="http://www.google.co.uk/intl/en/jobs/index.html"&gt;we&amp;#39;re hiring&lt;/a&gt;? :)&lt;/p&gt;  &lt;p&gt;Anyway, the basic message of this post is: thanks to the community for caring, thanks to Google for reconsidering, and thanks to Microsoft for renewing my award. And they all lived happily ever after...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1736410" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Google/default.aspx">Google</category></item><item><title>MVP no more</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/10/01/mvp-no-more.aspx</link><pubDate>Thu, 01 Oct 2009 05:21:27 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1728625</guid><dc:creator>skeet</dc:creator><slash:comments>84</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1728625</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1728625</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/10/01/mvp-no-more.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s with some sadness that I have to announce that as of the start of October, I&amp;#39;m no longer a Microsoft MVP.&lt;/p&gt;  &lt;p&gt;As renewal time came round again, I asked my employer whether it was okay for me to renew, and was advised not to do so. As a result, while I enjoyed being awarded as an MVP, I&amp;#39;ve asked not to be considered for renewal this year.&lt;/p&gt;  &lt;p&gt;This doesn&amp;#39;t mean I&amp;#39;m turning my back on that side of software development, of course. I&amp;#39;m still going to be an active member of the C# community. I&amp;#39;m still writing the second edition of C# in Depth. I&amp;#39;m still going to post on Stack Overflow. I&amp;#39;m still going to blog here about whatever interesting and wacky topics crop up.&lt;/p&gt;  &lt;p&gt;I just won&amp;#39;t be doing so as an MVP.&lt;/p&gt;  &lt;p&gt;Thanks to all the friends I&amp;#39;ve made in the MVP community and Microsoft over the last 6 years, and I wish you all the best.&lt;/p&gt;  &lt;p&gt;Keep in touch.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1728625" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category></item><item><title>Recent activities</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/09/04/recent-activities.aspx</link><pubDate>Thu, 03 Sep 2009 23:08:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1720570</guid><dc:creator>skeet</dc:creator><slash:comments>15</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1720570</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1720570</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/09/04/recent-activities.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s been a little while since I&amp;#39;ve blogged, and quite a lot has been going on. In fact, there are a few things I&amp;#39;d have blogged about already if it weren&amp;#39;t for &amp;quot;things&amp;quot; getting in the way.&lt;/p&gt;
&lt;p&gt;Rather than writing a whole series of very short blog posts, I thought I&amp;#39;d wrap them all up here...&lt;/p&gt;
&lt;h3&gt;C# in Depth: next MEAP drop available soon - Code Contracts&lt;/h3&gt;
&lt;p&gt;Thanks to everyone who gave feedback on my &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/08/05/tricky-decisions-code-contracts-and-parallel-extensions-in-c-in-depth-2nd-edition.aspx"&gt;writing dilemma&lt;/a&gt;. For the moment, the plan is to have a whole chapter about Code Contracts, but &lt;em&gt;not&lt;/em&gt; include a chapter about Parallel Extensions. My argument for making this decision is that Code Contracts really change the &lt;em&gt;feel&lt;/em&gt; of the code, making it almost like a language feature - and its applicability is almost ubiquitous, unlike PFX.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;may&lt;/em&gt; write a PFX chapter as a separate download, but I&amp;#39;m sensitive to those who (like me) appreciate slim books. I don&amp;#39;t want to &amp;quot;bulk out&amp;quot; the book with extra topics.&lt;/p&gt;
&lt;p&gt;The Code Contracts chapter is in the final stages before becoming available to MEAP subscribers. (It&amp;#39;s been &amp;quot;nearly ready&amp;quot; for a couple of weeks, but I&amp;#39;ve been on holiday, amongst other things.) After that, I&amp;#39;m going back to the existing chapters and revising them.&lt;/p&gt;
&lt;h3&gt;Talking in Dublin - C# 4 and Parallel Extensions&lt;/h3&gt;
&lt;p&gt;Last week I gave two talks in Dublin at &lt;a href="http://epicenter.ie/"&gt;Epicenter&lt;/a&gt;. One was on C# 4, and the other on Code Contracts and Parallel Extensions. Both are now available in a slightly odd form on the &lt;a href="http://csharpindepth.com/Talks.aspx"&gt;Talks page&lt;/a&gt; of the C# in Depth web site. I no longer write &amp;quot;formal&amp;quot; PowerPoint slides, so the downloads are for simple bullet points of text, along with silly hand-drawn slides. No code yet - I want to tidy it up a bit before including it.&lt;/p&gt;
&lt;h3&gt;Podcasting with The Connected Show&lt;/h3&gt;
&lt;p&gt;I recently recorded a &lt;a href="http://www.lyalin.com/Blog/archive/2009/09/01/connected-show-15-ndash-c-4-it-ainrsquot-that-complex.aspx"&gt;podcast episode&lt;/a&gt; with &lt;a href="http://www.connectedshow.com/"&gt;The Connected Show&lt;/a&gt;. I&amp;#39;m &amp;quot;on&amp;quot; for the second 2/3 of the show - about an hour of me blathering on about the new features of C# 4. If you can understand generic variance just by listening to me talking about it, you&amp;#39;re a smart cookie ;)&lt;/p&gt;
&lt;p&gt;(Oh, and if you like it, please express your amusement on &lt;a href="http://digg.com/microsoft/Connected_Show_15_Jon_Skeet_goes_DEEP_on_C_4_0"&gt;Digg&lt;/a&gt; / &lt;a href="http://www.dzone.com/links/connected_show_15_jon_skeet_goes_deep_on_c_40.html"&gt;DZone&lt;/a&gt; / &lt;a href="http://dotnetshoutout.com/Connected-Show-15-Jon-Skeet-goes-DEEP-on-C-40"&gt;Shout&lt;/a&gt; / &lt;a href="http://www.dotnetkicks.com/csharp/Connected_Show_15_Jon_Skeet_goes_DEEP_on_C_4_0"&gt;Kicks&lt;/a&gt;.)&lt;/p&gt;
&lt;h3&gt;Finishing up with Functional Programming for the Real World&lt;/h3&gt;
&lt;p&gt;Well, this hasn&amp;#39;t been taking much of my time recently (I bowed out of all the indexing etc!) but &lt;a href="http://manning.com/petricek"&gt;Functional Programming for the Real World&lt;/a&gt; is nearly ready to go. Hard copy should be available in the next couple of months... it&amp;#39;ll be really nice to see how it fares. Much kudos to Tomas for all his hard work - I&amp;#39;ve really just been helping out a little.&lt;/p&gt;
&lt;h3&gt;Starting on Groovy in Action, 2nd edition&lt;/h3&gt;
&lt;p&gt;No sooner does one book finish than another one starts. The &lt;a href="http://manning.com/koenig2/"&gt;second edition of Groovy in Action&lt;/a&gt; is in the works, which should prove interesting. To be honest, I haven&amp;#39;t played with Groovy much since the first edition of the book was finished, so it&amp;#39;ll be interesting to see what&amp;#39;s happened to the language in the meantime. I&amp;#39;ll be applying the same sort of spit and polish that I did in the first edition, and asking appropriately ignorant questions of the other authors.&lt;/p&gt;
&lt;h3&gt;Tech Reviewing C# 4.0 in a Nutshell&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/03/31/book-review-c-3-0-in-a-nutshell.aspx"&gt;I liked C# 3.0 in a Nutshell&lt;/a&gt;, and I feel honoured that Joe asked me to be a tech reviewer for the next edition, which promises to be even better. There&amp;#39;s not a lot more I can say about it at the moment, other than it&amp;#39;ll be out in 2010 - and I still feel that C# in Depth is a good companion book.&lt;/p&gt;
&lt;h3&gt;MoreLINQ now at 1.0 beta&lt;/h3&gt;
&lt;p&gt;A while ago I started the &lt;a href="http://code.google.com/p/morelinq/"&gt;MoreLINQ project&lt;/a&gt;, and it gained some developers with more time than I&amp;#39;ve got available :) Basically the idea is to add some more useful LINQ extension methods to LINQ to Object. Thanks to Atif Aziz, the first beta version has been released. This doesn&amp;#39;t mean we&amp;#39;re &amp;quot;done&amp;quot; though - just that we think we&amp;#39;ve got something useful. Any suggestions for other operators would be welcome.&lt;/p&gt;
&lt;h3&gt;Manning Pop Quiz and discounts&lt;/h3&gt;
&lt;p&gt;While I&amp;#39;m plugging books etc, it&amp;#39;s worth mentioning the &lt;a href="http://www.manning.com/popquiz/"&gt;Manning Pop Quiz&lt;/a&gt; - multiple choice questions on a wide variety of topics. Fabulous prizes available, as well as one-day discounts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monday, Sept 7th: 50% of all print books (code: pop0907)&lt;/li&gt;
&lt;li&gt;Monday, Sept 14: 50% off all ebooks&amp;nbsp; (code: pop0914)&lt;/li&gt;
&lt;li&gt;Thursday, Sept 17: $25 for C# in Depth, 2nd Edition MEAP print version (code: pop0917) + C# Pop Quiz question&lt;/li&gt;
&lt;li&gt;Monday, Sept 21: 50% off all books&amp;nbsp; (code: pop0921)&lt;/li&gt;
&lt;li&gt;Thursday, Sept 24: $12 for C# in Depth, 2nd Edition MEAP ebook (code: pop0924) + another C# Pop Quiz question&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Future speaking engagements&lt;/h3&gt;
&lt;p&gt;On September 16th I&amp;#39;m going to be speaking to &lt;a href="http://edgeug.net/"&gt;Edge UG&lt;/a&gt; (formerly Vista Squad) in London about Code Contracts and Parallel Extensions. I&amp;#39;m already &lt;em&gt;very&lt;/em&gt; much looking forward to the &lt;a href="http://stackoverflow.carsonified.com/events/london/"&gt;Stack Overflow DevDays London conference&lt;/a&gt; on October 28th, at which I&amp;#39;ll be talking about how humanity has screwed up computing.&lt;/p&gt;
&lt;h3&gt;Future potential blog posts&lt;/h3&gt;
&lt;p&gt;Some day I may get round to writing about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Revisiting StaticRandom with ThreadLocal&amp;lt;T&amp;gt;&lt;/li&gt;
&lt;li&gt;Volatile doesn&amp;#39;t mean what I thought it did&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;#39;s a lot more writing than coding in that list... I&amp;#39;d like to spend some more time on &lt;a href="http://code.google.com/p/minibench/"&gt;MiniBench&lt;/a&gt; at some point, but you know what deadlines are like.&lt;/p&gt;
&lt;p&gt;Anyway, that&amp;#39;s what I&amp;#39;ve been up to and what I&amp;#39;ll be doing for a little while...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1720570" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Books/default.aspx">Books</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+4/default.aspx">C# 4</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Language proliferation</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/05/12/language-proliferation.aspx</link><pubDate>Tue, 12 May 2009 16:54:47 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1692248</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1692248</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1692248</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/05/12/language-proliferation.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve always been aware that .NET supports multiple languages (obviously) and that Microsoft has been experimenting with this to some extent. It&amp;#39;s only recently struck me just to what extent this is the case though.&lt;/p&gt;  &lt;p&gt;Here&amp;#39;s a list - almost certainly incomplete - of .NET languages &lt;em&gt;from Microsoft alone&lt;/em&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vcsharp/default.aspx"&gt;C#&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/vbasic/default.aspx"&gt;VB&lt;/a&gt; (or VB.NET if you wish) &lt;/li&gt;    &lt;li&gt;C++/CLI &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/fsharp"&gt;F#&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://codeplex.com/ironpython"&gt;IronPython&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.codeplex.com/ironruby"&gt;IronRuby&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://research.microsoft.com/en-us/projects/specsharp/"&gt;Spec#&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-gb/library/dd129519.aspx"&gt;M&lt;/a&gt; (with &lt;a href="http://msdn.microsoft.com/en-us/oslo/default.aspx"&gt;Oslo&lt;/a&gt;) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/devlabs/dd795202.aspx"&gt;Axum&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/jscript/archive/2007/05/04/managed-jscript-announced.aspx"&gt;Managed JScript&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;PowerShell&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://research.microsoft.com/en-us/um/cambridge/projects/comega/"&gt;Cω&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;J# (not shipping any more, I believe)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Some of these are research languages which are more important for the ideas they&amp;#39;ve contributed to more mainstream ones at a later date than for anything else – but there&amp;#39;s still a lot of effort represented in the list.&lt;/p&gt;  &lt;p&gt;In addition, there are third party languages targeting .NET, such as &lt;a href="http://boo.codehaus.org"&gt;Boo&lt;/a&gt;, &lt;a href="http://www.codeplex.com/IronScheme"&gt;IronScheme&lt;/a&gt; and &lt;a href="http://www.scala-lang.org/node/168"&gt;Scala&lt;/a&gt;. (Wikipedia &lt;a href="http://en.wikipedia.org/wiki/List_of_.NET_languages"&gt;lists loads of them&lt;/a&gt;.)&lt;/p&gt;  &lt;p&gt;Now, think back to the time before .NET. Was Microsoft actively experimenting with languages back then? Plenty of people were trying things against the JVM, but Sun was pretty much absent from that party. .NET seems to be a &amp;quot;missing ingredient&amp;quot; that has allowed smart folk at Microsoft to let their imaginations loose in ways which they couldn&amp;#39;t previously. (Of course, not everyone in the language business at MS started there: Jim Hugunin was hired by Microsoft precisely &lt;em&gt;because&lt;/em&gt; of his work on IronPython.)&lt;/p&gt;  &lt;p&gt;I wonder how long this will continue.&lt;/p&gt;  &lt;h3&gt;Tower of Babel, or land of polyglots?&lt;/h3&gt;  &lt;p&gt;What does this mean for the average developer? Currently, if you&amp;#39;re writing a non-web application in .NET, you really only need to know a single language – and any of them will do. (Plus potentially SQL of course…) Compare this with web developers who have to be intimately familiar with HTML, CSS and JavaScript – and the differences between various implementations.&lt;/p&gt;  &lt;p&gt;How long will it be before backend developers are expected to know a dynamic language, a static OO language and a functional language? Does the benefit of mixing several languages in a project worth the impedance mismatch and the increased skillset requirements? I&amp;#39;m not going to make any predictions on that front – I can certainly see the benefits of each of these approaches in certain situations. They&amp;#39;ve been designed to play well together, but there are bound to be limitations and oddities: times when you need to change how you write your F# so that it&amp;#39;s easily callable from C#, for example.&lt;/p&gt;  &lt;p&gt;Whether or not you learn multiple languages to a professional level is one thing, but becoming &lt;em&gt;familiar&lt;/em&gt; with them is a different matter. In the course of co-authoring &lt;a href="http://manning.com/petricek/"&gt;Functional Programming for the Real World&lt;/a&gt; (where &amp;quot;co-author&amp;quot; is a bit of a stretch title - I&amp;#39;ve played more of an editorial role really, with the added bonus of picking on Tomas whenever I felt he was perhaps a little harsh towards C#) I&amp;#39;ve learned to appreciate many of F#&amp;#39;s qualities, but I don&amp;#39;t really &lt;em&gt;know&lt;/em&gt; the language. If someone asked me to write a complete application in it (rather than just a toy experiment) I&amp;#39;d be reaching for books every other minute. I hope I&amp;#39;ll learn more over the course of time, but I doubt that I&amp;#39;ll ever be sufficiently experienced in it to put it on my CV. The same goes for IronPython, although I&amp;#39;m considerably more likely to need Python at work than I am F#. (Python is one of the three &amp;quot;approved&amp;quot; languages at Google, along with Java and C++.) None of this means that time spent in these languages is wasted: I&amp;#39;ll be able to apply a lot of what I&amp;#39;ve learned about F# to my C# coding, even if it will make me pine for things like pattern matching and asynchronous workflows periodically.&lt;/p&gt;  &lt;p&gt;I think it&amp;#39;s pretty much a given that these days we all need to bring a wide range of technologies to bear in most jobs. While it used to be just about feasible in the .NET 1.1 days to have a pretty good grasp of all the major aspects (ASP.NET for sites and web services, ADO.NET, WinForms, Windows services, class libraries, interop) it&amp;#39;s just impossible these days. We learn something new when we need to - but usually against the background of a familiar language. How well would we cope if we had to learn whole new languages (to the level of being able to use them for production code) as often as we have to learn new libraries?&lt;/p&gt;  &lt;p&gt;This worries me a little. I&amp;#39;m pleased to see that C# 4 is a much smaller change than the previous versions were. Admittedly I&amp;#39;d rather have had immutability support than dynamic, but that&amp;#39;s just me... and that&amp;#39;s the problem, too. While I worry about our ability to actually learn everything that&amp;#39;s becoming available, it&amp;#39;s all good stuff. Can there be &amp;quot;too much of a good thing&amp;quot;?&lt;/p&gt;  &lt;p&gt;What I really &lt;em&gt;don&amp;#39;t &lt;/em&gt;want to see is developers having to know multiple languages, and everyone knowing them poorly. I&amp;#39;m a big believer in having a thorough understanding of your language, so that even if everything else is new, you can rely on your understanding of that aspect of your code. It would be a shame if the pressure of knowing many languages turned many of us into &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/03/01/82168.aspx"&gt;cargo cult programmers&lt;/a&gt;. The utopia would be for us all to turn into &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=332"&gt;language renaissance&lt;/a&gt; developers. I suspect the reality will be somewhere between the two.&lt;/p&gt;  &lt;p&gt;Still, as long as I get to keep helping authors write about languages I know almost nothing about, I&amp;#39;m sure I&amp;#39;ll be happy...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1692248" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/F_2300_/default.aspx">F#</category></item><item><title>Breaking Liskov</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/03/16/breaking-liskov.aspx</link><pubDate>Mon, 16 Mar 2009 17:48:04 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1678395</guid><dc:creator>skeet</dc:creator><slash:comments>32</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1678395</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1678395</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/03/16/breaking-liskov.aspx#comments</comments><description>&lt;p&gt;Very recently, &lt;a href="http://news.bbc.co.uk/1/hi/technology/7937010.stm"&gt;Barbara Liskov won the Turing award&lt;/a&gt;, which makes it a highly appropriate time to ponder when it&amp;#39;s reasonable to ignore her most famous piece of work, the &lt;a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;Liskov Substitution (or Substitutability) Principle&lt;/a&gt;. This is not idle speculation: I&amp;#39;ve had a feature request for &lt;a href="http://pobox.com/~skeet/csharp/miscutil"&gt;MiscUtil&lt;/a&gt;. The request makes sense, simplifies the code, and is good all round - but it breaks substitutability &lt;em&gt;and&lt;/em&gt; documented APIs.&lt;/p&gt; &lt;p&gt;The substitutability principle is in some ways just common sense. It says (in paraphrase) that if your code works for some base type T, it should be able to work with subtype of T, S. If it doesn&amp;#39;t, S is breaking substitutability. This principle is at the heart of inheritance and polymorphism - I should be able to use a Stream without knowing the details of what its underlying storage is, for example.&lt;/p&gt; &lt;p&gt;Liskov&amp;#39;s formulation is:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;i&gt;Let &lt;i&gt;q&lt;/i&gt;(&lt;i&gt;x&lt;/i&gt;) be a property provable about objects &lt;i&gt;x&lt;/i&gt; of type &lt;i&gt;T&lt;/i&gt;. Then &lt;i&gt;q&lt;/i&gt;(&lt;i&gt;y&lt;/i&gt;) should be true for objects &lt;i&gt;y&lt;/i&gt; of type &lt;i&gt;S&lt;/i&gt; where &lt;i&gt;S&lt;/i&gt; is a subtype of &lt;i&gt;T&lt;/i&gt;.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So, that&amp;#39;s the rule. Sounds like a good idea, right?&lt;/p&gt; &lt;h3&gt;Breaking BinaryReader&amp;#39;s contract&lt;/h3&gt; &lt;p&gt;My case in point is EndianBinaryReader (and EndianBinaryWriter, but the arguments will all be the same - it&amp;#39;s better to focus on a single type). This is simply an equivalent to &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx"&gt;System.IO.BinaryReader&lt;/a&gt;, but it lets you specify the endianness to use when converting values.&lt;/p&gt; &lt;p&gt;Currently, EndianBinaryReader is a completely separate class to BinaryReader. They have no inheritance relationship. However, as it happens, BinaryReader isn&amp;#39;t sealed, and all of the appropriate methods are virtual. So, can we make EndianBinaryReader derive from BinaryReader and use it as a drop-in replacement? Well... that&amp;#39;s where the trouble starts.&lt;/p&gt; &lt;p&gt;There&amp;#39;s no difficulty &lt;em&gt;technically&lt;/em&gt; in doing it. The implementation is fairly straightforward - indeed, it means we can drop a bunch of methods from EndianBinaryReader and let BinaryReader handle it instead. (This is particularly handy for text, which is fiddly to get right.) I currently have the code in another branch, and it works fine.&lt;/p&gt; &lt;h3&gt;And I would have gotten away with it if it weren&amp;#39;t for that pesky inheritance...&lt;/h3&gt; &lt;p&gt;The problem is whether or not it&amp;#39;s the right thing to do. To start with, it breaks Liskov&amp;#39;s substitutability principle, if the &amp;quot;property&amp;quot; we consider is &amp;quot;the result of calling ReadInt32 when the next four bytes of the underlying stream are 00, 00, 00, 01&amp;quot; for example. Not having read Liskov&amp;#39;s paper for myself (I really should, some time) I&amp;#39;m not sure whether this is the intended kind of use or not. More on that later.&lt;/p&gt; &lt;p&gt;The second problem is that it contradicts the documentation for BinaryReader. For example, the &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.readint32.aspx"&gt;docs for ReadInt32&lt;/a&gt; state: &amp;quot;&lt;a href="http://msdn.microsoft.com/en-us/library/system.io.binaryreader.aspx"&gt;BinaryReader&lt;/a&gt; reads this data type in little-endian format.&amp;quot; That&amp;#39;s a tricky bit of documentation to understand precisely - it&amp;#39;s correct for BinaryReader itself, but does that mean it should be true for all subclasses too?&lt;/p&gt; &lt;p&gt;When I&amp;#39;ve written in various places about the problems of inheritance, and why if you design a class to be unsealed that means doing more design work, this is the kind of thing I&amp;#39;ve been talking about. How much detail does it make sense to specify here? How much leeway is there for classes overriding ReadInt32? Could a different implementation read a &amp;quot;compressed&amp;quot; Int32 instead of always reading four bytes, for example? Should the client care, if they make sure they&amp;#39;ve obtained an appropriate BinaryReader for their data source in the first place? This is basically the same as asking how strictly we should apply Liskov&amp;#39;s substitutability principle. If two types are the same in &lt;em&gt;every&lt;/em&gt; property, surely we can&amp;#39;t distinguish between them at all.&lt;/p&gt; &lt;p&gt;I wonder whether most design questions of inheritance basically boil down to defining which properties should obey Liskov&amp;#39;s substitutability principle and which needn&amp;#39;t, for the type you&amp;#39;re designing. Of course, it&amp;#39;s not just black and white - there will always be exceptions and awkward points. Programming is often about nuance, even if we might wish that not to be the case.&lt;/p&gt; &lt;h3&gt;Blow it, let&amp;#39;s do it anyway...&lt;/h3&gt; &lt;p&gt;Coming back to BinaryReader, I &lt;em&gt;think&lt;/em&gt; (unless I can be persuaded otherwise) that the benefits from going against the documentation (and strict substitutability) outweigh the downsides. In particular, BinaryReaders don&amp;#39;t tend to be passed around in my experience - the code which creates it is usually the code which uses it too, or it&amp;#39;s at least closely related. The risk of breaking code by passing it a BinaryReader using an unexpected endianness is therefore quite low, even though it&amp;#39;s theoretically possible.&lt;/p&gt; &lt;p&gt;So, am I miles off track? This is for a class library, after all - should I be more punctilious about playing by the rules? Or is pragmatism the more important principle here?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1678395" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category></item><item><title>What's in a name?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/02/27/what-s-in-a-name.aspx</link><pubDate>Fri, 27 Feb 2009 11:29:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1674533</guid><dc:creator>skeet</dc:creator><slash:comments>23</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1674533</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1674533</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/02/27/what-s-in-a-name.aspx#comments</comments><description>&lt;p&gt;T.S. Eliot had the right idea when he wrote &lt;a href="http://www.americanpoems.com/poets/tseliot/5536"&gt;&amp;quot;The naming of cats&amp;quot;&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Naming of Cats is a difficult matter,&lt;br /&gt;It isn&amp;#39;t just one of your holiday games&lt;br /&gt;...&lt;br /&gt;When you notice a cat in profound meditation,&lt;br /&gt;The reason, I tell you, is always the same:&lt;br /&gt;His mind is engaged in a rapt contemplation&lt;br /&gt;Of the thought, of the thought, of the thought of his name:&lt;br /&gt;His ineffable effable&lt;br /&gt;Effanineffable&lt;br /&gt;Deep and inscrutable singular Name.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Okay, so developers may not contemplate their &lt;em&gt;own&lt;/em&gt; names much, but I know I&amp;#39;ve certainly spent a significant amount of time recently trying to work out the &lt;em&gt;right&lt;/em&gt; name for various types and methods.&amp;nbsp; It always feels like it&amp;#39;s just out of reach; tauntingly, tantalisingly close.&lt;/p&gt;
&lt;p&gt;Recently I&amp;#39;ve been thinking a bit about what the goals might be in coming up with a good name. In particular, I seem to have been plagued with the naming problem more than usual in the last few weeks.&lt;/p&gt;
&lt;h3&gt;Operations on immutable types&lt;/h3&gt;
&lt;p&gt;A while ago I asked &lt;a href="http://stackoverflow.com/questions/521893/"&gt;a question on Stack Overflow&lt;/a&gt; about naming a method which &amp;quot;adds&amp;quot; an item to an immutable collection. Of course, when I say &amp;quot;adds&amp;quot; I mean &amp;quot;returns a new collection whose contents is the old collection and the new item.&amp;quot; There&amp;#39;s a really wide range of answers (currently 38 of them) which mostly seem to fall into four categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Add because it&amp;#39;s idiomatic for .NET collections. Developers should know that the type is immutable and act accordingly.  &lt;/li&gt;
&lt;li&gt;Use Cons because that&amp;#39;s the term functional programming has used for this exact operation for decades.  &lt;/li&gt;
&lt;li&gt;Use a new method name (Plus being my favourite at the moment) which will be obvious to non-functional developers, but without being so familiar that it suggests mutability.  &lt;/li&gt;
&lt;li&gt;Use a constructor taking the old collection and the new item.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Part of the reasoning for Add being okay is that I originally posted the question purely about &amp;quot;an immutable collection&amp;quot; - e.g. a type which would have a name like ImmutableList&amp;lt;T&amp;gt;. I then revealed my &lt;em&gt;true&lt;/em&gt; intention (which I should have done from the start) - to use this in &lt;a href="http://code.google.com/p/minibench/"&gt;MiniBench&lt;/a&gt;, where the &amp;quot;collection&amp;quot; would actually be a TestSuite. Everything in MiniBench is immutable (it&amp;#39;s partly an exploration in functional programming, as it seems to fit very nicely) but I don&amp;#39;t want to have to name every single type as Immutable[Whatever]. There&amp;#39;s the argument that a developer should know at least a &lt;em&gt;little&lt;/em&gt; bit about any API they&amp;#39;re using, and the immutability aspect is one of the first things they should know. However, MiniBench is arguably an extreme case, because it&amp;#39;s &lt;em&gt;designed&lt;/em&gt; for sharing test code with people who&amp;#39;ve never seen it before.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m pretty sure I&amp;#39;m going to go with Plus in the end:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It&amp;#39;s close enough to Add to be familiar  &lt;/li&gt;
&lt;li&gt;It&amp;#39;s different enough to Add to suggest that it&amp;#39;s not &lt;em&gt;quite&lt;/em&gt; the same thing as adding to a normal collection  &lt;/li&gt;
&lt;li&gt;It sounds like it returns something - a statement which &lt;em&gt;just&lt;/em&gt; calls Plus without using the result sounds like it&amp;#39;s wrong (and indeed it would be)  &lt;/li&gt;
&lt;li&gt;It&amp;#39;s meaningful to everyone  &lt;/li&gt;
&lt;li&gt;I have a precedent in the &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time&lt;/a&gt; API&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another option is to overload the + operator, but I&amp;#39;m not really sure I&amp;#39;m ready to do that &lt;em&gt;just&lt;/em&gt; yet. It would certainly leave brief code, but is that really the most important thing?&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s look at a situation with some of the same issues...&lt;/p&gt;
&lt;h3&gt;LINQ operators&lt;/h3&gt;
&lt;p&gt;Work on &lt;a href="http://code.google.com/p/morelinq/"&gt;MoreLINQ&lt;/a&gt; has progressed faster than expected, mostly because the project now has four members, and they&amp;#39;ve been expending quite a bit of energy on it. (I must do a proper consistency review at some point - in particular it would be nice to have the docs refer to the same concepts in the same way each time. I digress...)&lt;/p&gt;
&lt;p&gt;Most of the discussion in the project hasn&amp;#39;t been about functionality - it&amp;#39;s been about naming. In fact, LINQ is particularly odd in this respect. If I had to guess at how the time has been spent (at least for the operators I&amp;#39;ve implemented) I&amp;#39;d go for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;15% designing the behaviour  &lt;/li&gt;
&lt;li&gt;20% writing the tests  &lt;/li&gt;
&lt;li&gt;10% implementation  &lt;/li&gt;
&lt;li&gt;5% writing the documentation (just XML docs)  &lt;/li&gt;
&lt;li&gt;50% figuring out the best name&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It really is that brutal - and for a lot of the operators we still haven&amp;#39;t got the &amp;quot;right&amp;quot; name yet, in my view. There&amp;#39;s generally too much we want to convey in a word or two. As an example, we&amp;#39;ve got an operator similar to the oft-implemented ForEach one, but which yields the input sequence back out again. Basically it takes an action, and for each element it calls the action and then yields the element. The use case is something like logging. We&amp;#39;ve gone through several names, such as Pipe, Tee, Via... and just this morning I asked a colleague who suggested Apply, just off the top of his head. It&amp;#39;s better than anything we&amp;#39;d previously thought of, but does it convey both the &amp;quot;apply an action&amp;quot; and &amp;quot;still yield the original sequence&amp;quot; aspects?&lt;/p&gt;
&lt;p&gt;The old advice of &amp;quot;each method should only do one thing&amp;quot; is all very well, and it clearly helps to make naming simpler, but with situations like this one there are just &lt;em&gt;naturally&lt;/em&gt; more concepts which you want to get across in the name.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s stay on the LINQ topic, but stray a bit further from the well-trodden path...&lt;/p&gt;
&lt;h3&gt;The heart of Push LINQ: IDataProducer&lt;/h3&gt;
&lt;p&gt;I&amp;#39;ve probably bored most of you with &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/01/04/quot-push-quot-linq-revisited-next-attempt-at-an-explanation.aspx"&gt;Push LINQ&lt;/a&gt; by now, and I&amp;#39;m not actively developing it at the moment, but there&amp;#39;s still one aspect which I&amp;#39;m deeply uncomfortable with: the core interface. IDataProducer represents a stream of data which can be observed. Basically clients subscribe to events, and their event handlers will be called when data is &amp;quot;produced&amp;quot; and when the stream ends.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;know&lt;/em&gt; IDataProducer is an awful name - but so far I haven&amp;#39;t found anything better. IObservable? Ick. Overused and isn&amp;#39;t descriptive. IPushEnumerable? Sounds like the client can iterate over the data, which they can&amp;#39;t. The actual event names (DataProduced/EndOfData) are okay but there &lt;em&gt;must&lt;/em&gt; be something better than IDataProducer. (Various options have been suggested in the past - none of them have been so obviously &amp;quot;right&amp;quot; as to stick in my head...)&lt;/p&gt;
&lt;p&gt;This situation is slightly different to the previous ones, however, simply because it&amp;#39;s such a pivotal type. You would think that the more important the type, the more important the name would be - but in some ways the reverse is true. You see, Push LINQ isn&amp;#39;t a terribly &amp;quot;obvious&amp;quot; framework. I say that without shame - it&amp;#39;s great at what it does, but it takes a few mental leaps before you really grok it. You&amp;#39;re really going to &lt;em&gt;have&lt;/em&gt; to read some documentation or examples before you write your own queries.&lt;/p&gt;
&lt;p&gt;Given that constraint, it doesn&amp;#39;t matter too much what the interface is called - it&amp;#39;s going to be explained to you before you need it. It doesn&amp;#39;t need to be discoverable - whereas when you&amp;#39;re picking method names to pop up in Intellisense, you really want the developer to be able to &lt;em&gt;guess&lt;/em&gt; its purpose even before they hover over it and check the documentation.&lt;/p&gt;
&lt;p&gt;I haven&amp;#39;t given up on IDataProducer (and I hope to be moving Push LINQ into MoreLINQ, by the way - working out a better name is one of the blockers) but it doesn&amp;#39;t feel like &lt;em&gt;quite&lt;/em&gt; as much of a problem.&lt;/p&gt;
&lt;h3&gt;Read-only or not read-only?&lt;/h3&gt;
&lt;p&gt;This final example came up at work, just yesterday - after I&amp;#39;d started writing this post. I wanted to refactor some code to emphasize which methods only use the read-only side of an interface. This was purely for the sake of readability - I wanted to make it easier to reason about which areas of the code modified an object and which didn&amp;#39;t. It&amp;#39;s a custom collection - the details don&amp;#39;t matter, but for the sake of discussion let&amp;#39;s call it House and pretend we&amp;#39;re modelling the various things which might be in a house. (This is Java, hence House rather than IHouse.)&lt;/p&gt;
&lt;p&gt;I&amp;#39;m explicitly &lt;em&gt;not&lt;/em&gt; doing this for safety - I don&amp;#39;t mind the fact that the reference could be cast to a mutable interface. The point is just to make it self-documenting that if a method only has a parameter in the non-mutating form, it&amp;#39;s not going to change the contents of the house.&lt;/p&gt;
&lt;p&gt;So, we have two interfaces, like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Type"&gt;interface&lt;/span&gt; NameMePlease&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Color getDoorColor();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Type"&gt;int&lt;/span&gt; getWindowCount();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="InlineComment"&gt;// This already returned a read-only collection&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set&amp;lt;Furniture&amp;gt; getFurniture();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span class="Type"&gt;interface&lt;/span&gt; House extends NameMePlease&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Type"&gt;void&lt;/span&gt; setDoorColor(Color doorColor);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Type"&gt;void&lt;/span&gt; setWindowCount(&lt;span class="Type"&gt;int&lt;/span&gt; windows);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="Type"&gt;void&lt;/span&gt; addFurniture(Furniture item);&lt;br /&gt;} &lt;/div&gt;
&lt;p&gt;Obviously the challenge is to find a name for NameMePlease. One option is to use something like ImmutableHouse or ReadOnlyHouse - but the inheritance hierarchy makes liars of both of those names. How can it be a ReadOnlyHouse if there are methods in an implementation which change it? The interface should say what you &lt;em&gt;can&lt;/em&gt; do with the type, rather than specifying what you &lt;em&gt;can&amp;#39;t&lt;/em&gt; do - unless part of the contract of the interface is that the implementation will genunely prohibit changes.&lt;/p&gt;
&lt;p&gt;Thinking of this &amp;quot;positive&amp;quot; aspect led me to ReadableHouse, which is what I&amp;#39;ve gone with for the moment. It states what you can do with it - read information. Again, this is a concept which Joda Time uses.&lt;/p&gt;
&lt;p&gt;Another option is to make it just House, and change the mutable interface to MutableHouse or something similar. In this particular situation the refactoring involved would have been enormous. Simple to automate, but causing a huge check-in for relatively little benefit. Almost all uses are &lt;em&gt;actually&lt;/em&gt; mutating ones. The consensus within the Google Java mailing list seems to be that this would have been the preferred option, all things being equal. One interesting data point was that although Joda Time uses ReadableInstant etc, the current proposals for the new date/time API which will be included in Java 7, designed by the author of Joda Time, &lt;em&gt;don&amp;#39;t&lt;/em&gt; use this convention. Presumably the author found it didn&amp;#39;t work quite as well as he&amp;#39;d hoped, although I don&amp;#39;t have know of any specific problems.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;You&amp;#39;ll probably be unsurprised to hear that I don&amp;#39;t have a recipe for coming up with good names. However, in thinking about naming I&amp;#39;ve at least worked out a few points to think about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Context is important: how discoverable does this need to be? Is accuracy more important than brevity? Do you have any example uses (e.g. through tests) which can help to see whether the code feels right or not?  &lt;/li&gt;
&lt;li&gt;Think of your audience. How familiar will they be with the rest of the code you&amp;#39;re writing? Are they likely to have a background in other areas of computer science where you could steal terminology? Can you make your name consistent with other common frameworks they&amp;#39;re likely to use? The reverse is true too: are you reusing a familiar name for a &lt;em&gt;different&lt;/em&gt; concept, which could confuse readers?  &lt;/li&gt;
&lt;li&gt;Work out the information the name is trying to convey. For types, this includes working out how it participates in inheritance. Is it trying to advertise capabilities or restrictions?  &lt;/li&gt;
&lt;li&gt;Is it possible to make correct code look correct, and buggy code look wrong? This is rarely feasible, but it&amp;#39;s one of the main attractions of &amp;quot;Plus&amp;quot; in the benchmark case. (I believe this is one of the main selling points of true Hungarian Notation for variable naming, by the way. I&amp;#39;m not generally a fan, but I like this aspect.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I may expand this list over time...&lt;/p&gt;
&lt;p&gt;I think it&amp;#39;s fitting to close with a &lt;a href="http://people.famouswhy.com/phil_karlton/"&gt;quote from Phil Karlton&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Almost all of us have to handle naming things. Let&amp;#39;s hope most of us don&amp;#39;t have to mess with cache invalidation as well.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1674533" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Java/default.aspx">Java</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/LINQ/default.aspx">LINQ</category></item><item><title>Answering technical questions helpfully</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx</link><pubDate>Tue, 17 Feb 2009 17:50:11 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1672745</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1672745</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1672745</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/02/17/answering-technical-questions-helpfully.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m unsure of whether this should be a &lt;a href="http://msmvps.com/jon.skeet"&gt;blog post&lt;/a&gt; or an &lt;a href="http://pobox.com/~skeet/csharp"&gt;article&lt;/a&gt;, so I&amp;#39;ll probably make it both. I&amp;#39;ve probably written most of it before in Stack Overflow answers, but as I couldn&amp;#39;t find anything when I was looking earlier (to answer a &lt;a href="http://stackoverflow.com/questions/527962"&gt;question about Stack Overflow answers&lt;/a&gt;) I figured it was time to write something in a medium I had more control over.&lt;/p&gt; &lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; a guide to getting huge amounts of reputation on Stack Overflow. As it happens, following the guidelines here is likely to result in decent rep,&amp;nbsp; but I&amp;#39;m sure there are various somewhat underhand ways of gaining reputation without actually being helpful. In other words, I&amp;#39;m not going to explain how you might game the system, but just share my views on how to work &lt;em&gt;with&lt;/em&gt; the system for the benefit of all involved. A lot of this isn&amp;#39;t specific to Stack Overflow, but some of the advice isn&amp;#39;t applicable to some forums.&lt;/p&gt; &lt;p&gt;Hypocrisy warning: I&amp;#39;m not going to claim I always follow everything in this list. I try, but that&amp;#39;s not the same thing - and quite often time pressures will compromise the quality of an answer. Oh, and don&amp;#39;t read anything into the ordering here. It&amp;#39;s how it happened to come out, that&amp;#39;s all.&lt;/p&gt; &lt;h3&gt;Read the question&lt;/h3&gt; &lt;p&gt;All too often I&amp;#39;ve written what I thought was a &lt;em&gt;great&lt;/em&gt; answer... only to reread the question and find out that it wasn&amp;#39;t going to help the questioner at all.&lt;/p&gt; &lt;p&gt;Now, questions are often written pretty badly, leaving out vital information, being vague about the problem, including lots of &lt;em&gt;irrelevant&lt;/em&gt; code but leaving out the crucial bit which probably contains the bug, etc. It&amp;#39;s at least worth commenting on the question to ask for more information, but just occasionally you can apply psychic debugging to answer the question anyway. If you &lt;em&gt;do&lt;/em&gt; have to make assumptions when writing an answer, state them explicitly. That will not only reduce the possibility of miscommunication, but will also point out the areas which need further clarification.&lt;/p&gt; &lt;h3&gt;Code is king&lt;/h3&gt; &lt;p&gt;I can&amp;#39;t believe I nearly posted this article without mentioning sample code.&lt;/p&gt; &lt;p&gt;Answers with sample code are gold... if the code is appropriate. A few rules of thumb:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Make sure it compiles, assuming it&amp;#39;s meant to. This isn&amp;#39;t always possible - for example, I often post at work from a machine without .NET on it, or on the train from a laptop without Java. If you can&amp;#39;t get a compiler to make sure your code is valid, be extra careful in terms of human inspection.  &lt;li&gt;Snippets are okay, but complete programs rock. If you&amp;#39;re not already comfortable with writing short console apps, practise it. Often you can write a complete app in about 15 lines which doesn&amp;#39;t just give the solution, but shows it working. Imagine the level of confidence that gives to anyone reading your answer. Get rid of anything you don&amp;#39;t need - brevity is really helpful. (In C# for example that usually means getting rid of [STAThread], namespace declarations and unused using directives.)  &lt;li&gt;Take a bit of care over formatting. If possible, try to prevent the code wrapping. That&amp;#39;s not always realistically feasible, but it&amp;#39;s a nice ideal. Make sure the spacing at least looks okay - you may want to use a 2-space indent if your code involves a lot of nesting.  &lt;li&gt;If you skip best practices, add a comment. For example, you might include &lt;code&gt;// Insert error handling here&lt;/code&gt; to indicate that production code really should check the return value etc. This doesn&amp;#39;t include omitting the STAThread attribute and working without a namespace - those are just reasonable assumptions and unlikely to be copied wholesale, whereas the main body of the code may well be. If your code leaks resources, someone&amp;#39;s production code may do so as well...&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Code without an explanation is rarely useful, however. At least provide a sentence or two to explain what&amp;#39;s going on.&lt;/p&gt; &lt;h3&gt;Answer the question &lt;em&gt;and&lt;/em&gt; highlight side-issues&lt;/h3&gt; &lt;p&gt;Other developers don&amp;#39;t always do things the way we&amp;#39;d like them to. Questions often reflect this, basically asking how to do something which (in our view) shouldn&amp;#39;t be attempted in the first place. It may completely infeasible, or it may just be a really bad idea.&lt;/p&gt; &lt;p&gt;Occasionally, the idea is so awful - and possibly harmful to users, especially when it comes to security questions - that the best response is &lt;em&gt;just&lt;/em&gt; to explain (carefully and politely) why this is a really bad thing to do. Usually, however, it&amp;#39;s better to answer the question&lt;em&gt; &lt;/em&gt;and give details of better alternatives at the same time. Personally I prefer to give these alternatives &lt;em&gt;before&lt;/em&gt; the answer to the question asked, as I suspect it makes it more likely that the questioner will read the advice and take it on board. Don&amp;#39;t forget that the more persuasive you can be, the more likely it is they&amp;#39;ll abandon their original plans. In other words, &amp;quot;Don&amp;#39;t do this!&amp;quot; isn&amp;#39;t nearly as useful as &amp;quot;Don&amp;#39;t do this because...&amp;quot;&lt;/p&gt; &lt;h3&gt;It&amp;#39;s okay to guess, but be honest&lt;/h3&gt; &lt;p&gt;This may be controversial. I&amp;#39;ve certainly been downvoted twice on SO for having the temerity to post an answer without being 100% sure that it&amp;#39;s the right one - and (worse?) for admitting as much.&lt;/p&gt; &lt;p&gt;Sometimes there are questions which are slightly outside your own area of expertise, but they feel an awful lot like a situation you&amp;#39;ve been in before. In this kind of case, you can often write an answer which may well help - and would &lt;em&gt;at least&lt;/em&gt; suggest something for the questioner to investigate a a &lt;em&gt;possible&lt;/em&gt; answer to their problem. Sometimes you may be way off base, which is why it&amp;#39;s worth explaining in your answer that you &lt;em&gt;are&lt;/em&gt; applying a bit of educated guesswork. If another answer is posted by an expert in the topic, it may well be worth the questioner trying their solution first... but at least you&amp;#39;re providing an alternative if they run out of other possibilities.&lt;/p&gt; &lt;p&gt;Now, somewhat contradictory...&lt;/p&gt; &lt;h3&gt;Raise the overall accuracy level&lt;/h3&gt; &lt;p&gt;It should go without saying that a correct answer is more helpful than an incorrect one. There are plenty of entirely inaccurate answers on Stack Overflow - and on newsgroups, and basically every online community-based resource I&amp;#39;ve ever seen. This isn&amp;#39;t surprising, but the best ways to counter it are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Challenge inaccurate information  &lt;li&gt;Provide accurate information yourself&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;One of the key aspects of this is to provide evidence. If you make an objective statement without any sort of disclaimer about your uncertainty, that &lt;em&gt;should&lt;/em&gt; mean you&amp;#39;ve got good reason to believe you&amp;#39;re correct. That doesn&amp;#39;t necessarily mean you need to provide evidence, but as soon as there&amp;#39;s disagreement, evidence is king. If you want to assert that your code is faster than some other code, write a benchmark (carefully!). If you want to prove that an object &lt;em&gt;can&lt;/em&gt; be collected at a certain point in time, write a test to show it. &lt;a href="http://pobox.com/~skeet/csharp/complete.html"&gt;Short but complete programs&lt;/a&gt; are great for this, and can stop an argument dead in its tracks.&lt;/p&gt; &lt;p&gt;Another source of evidence is documentation and specifications. Be aware that they&amp;#39;re not always accurate, but I generally believe documentation unless I have a specific reason to doubt it.&lt;/p&gt; &lt;h3&gt;Provide links to related resources&lt;/h3&gt; &lt;p&gt;There have been a few questions on Stack Overflow as to whether it&amp;#39;s appropriate to link to other resources on the web. My own opinion is that it&amp;#39;s &lt;em&gt;absolutely&lt;/em&gt; appropriate and can add a lot of value to an answer. In particular, I like to link to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;MSDN and JavaDoc documentation, or the equivalent for other platforms. With MSDN URLs, if they end in something like http://msdn.microsoft.om/foo(VS80).aspx, take the bit in brackets out of the URL (leaving http://msdn.microsoft.om/foo.aspx in this case). That way the link will always be to the most recent version of the documentation, and it doesn&amp;#39;t give WMD as many problems either.  &lt;li&gt;Language specifications, in particular those for &lt;a href="http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a8-75351c669b09/CSharp%20Language%20Specification.doc"&gt;C#&lt;/a&gt; and &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html"&gt;Java&lt;/a&gt;. I generally link to the Word document for the C# spec, which has the disadvantage that I can&amp;#39;t link to a specific section, and it won&amp;#39;t just open in the browser. On the other hand, I find it easier to navigate than the MSDN version, and I&amp;#39;ve seen inaccuracies in MSDN.  &lt;li&gt;My own articles and blog posts (unsurprisingly :)  &lt;li&gt;Wikipedia  &lt;li&gt;Other resources which are unlikely to become unavailable&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The point about the resources not becoming unavailable is important - one of the main arguments against linking is that the page might go away in the future. That&amp;#39;s not a particularly compelling argument for most reference material IMO, but it &lt;em&gt;is&lt;/em&gt; relevant in other cases. Either way, it&amp;#39;s worth including some sort of summary of what you&amp;#39;re linking to - a link on its own doesn&amp;#39;t really invite the reader to follow it, whereas a quick description of what they&amp;#39;ll find there provides more incentive.&lt;/p&gt; &lt;p&gt;One quick tip: In Chrome I have an MSDN &amp;quot;search engine&amp;quot; set up and in Firefox a keyword bookmark. In both cases the URL is http://msdn.microsoft.com/en-us/library/%s.aspx - this makes it easier to get to the MSDN page for a particular namespace, type or member. For example, by typing &amp;quot;msdn system.io.fileinfo&amp;quot; I get straight to &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx"&gt;the FileInfo page&lt;/a&gt;. It doesn&amp;#39;t work for generics, however. At some point I&amp;#39;d like to make this simpler somehow...&lt;/p&gt; &lt;h3&gt;Care about your reader: spelling, grammar and style matter&lt;/h3&gt; &lt;p&gt;I&amp;#39;m lucky: I&amp;#39;m a native English speaker, and I have a reasonably good natural command of English. Having said that, I still take a certain amount of care when writing answers: I&amp;#39;ll often rewrite a sentence several times until I feel it works. I&amp;#39;ve noticed that answers with correct spelling and grammar are generally upvoted more than ones with essentially the same content but less careful presentation.&lt;/p&gt; &lt;p&gt;I&amp;#39;m not recommending style &lt;em&gt;over&lt;/em&gt; substance; I&amp;#39;m saying that both are important. You could be putting forward the most insightful comment in the world, but if you can&amp;#39;t communicate it effectively to your readers, it&amp;#39;s not going to help anyone. Having said that...&lt;/p&gt; &lt;h3&gt;A time-limited answer may be better than no answer at all&lt;/h3&gt; &lt;p&gt;I answer Stack Overflow questions in whatever spare time I have: waiting for a build, on the train, taking a break from editing etc. I frequently see a question which would take a good 15 minutes or more to answer properly - but I only have 30 seconds. If the question already has answers, there&amp;#39;s probably no sensible contribution I can make, but if the question is completely unanswered, I sometimes add a very short answer with the most important points I can think of at the time.&lt;/p&gt; &lt;p&gt;Ideally, I&amp;#39;d then go back later and edit the answer to make it more complete - but at least I may have given the questioner something to think about or an option to try. Usually these &amp;quot;quickies&amp;quot; are relatively fruitless, but occasionally I&amp;#39;ll come back to find that the answer was accepted: the slight nudge in the answer was all that was required. If I&amp;#39;m feeling diligent at that point I&amp;#39;ll still complete the answer, but the point is that a brief answer is usually better than nothing.&lt;/p&gt; &lt;h3&gt;Don&amp;#39;t be afraid to delete (or edit heavily) useless answers&lt;/h3&gt; &lt;p&gt;It&amp;#39;s almost inevitable that if you post enough answers, one of them will be less than helpful. It may start off being a good one, but if a later answer includes all the information from your answer and more, or explains it in a better way, it&amp;#39;s just clutter.&lt;/p&gt; &lt;p&gt;Likewise if you make a wild stab in the dark about the cause of a problem, and that guess turns out to be wrong, your answer could become actively unhelpful. Usually the community will let you know this in comments or voting, but sometimes you have to recognise it on your own.&lt;/p&gt; &lt;h3&gt;Be polite&lt;/h3&gt; &lt;p&gt;It&amp;#39;s a shame that I have to include this, and it&amp;#39;s even more of a shame that I need to take better notice of it myself. However boneheaded a question is, there&amp;#39;s no need to be rude. You can express your dismay at a question, and even express dismay at someone failing to read your answer properly, without resorting to inflammatory language. In the end, no-one really wins from a flame war. Remember that there&amp;#39;s a real person at the other end of the network connection, and they&amp;#39;re probably just as frustrated with you as you are with them. If things are getting out of hand, just write a polite note explaining that you don&amp;#39;t think it&amp;#39;s productive to discuss the topic any more, and walk away. (This can be surprisingly difficult advice to heed.)&lt;/p&gt; &lt;p&gt;Next time I get too &amp;quot;involved&amp;quot; in a question, could someone please direct me to this point? And don&amp;#39;t take &amp;quot;But I&amp;#39;m &lt;em&gt;right&lt;/em&gt;, darnit!&amp;quot;&amp;nbsp; as an excuse.&lt;/p&gt; &lt;h3&gt;Don&amp;#39;t &amp;quot;answer and run&amp;quot;&lt;/h3&gt; &lt;p&gt;Sometimes an answer is very, very nearly spot on - but that final 1% is all the difference between the reader understanding fully and having a dangerous misunderstanding of the topic.&lt;/p&gt; &lt;p&gt;Stack Overflow makes it pretty easy to see comments to your answers: monitor this carefully so you can respond and clarify where appropriate. Many web forums have an &amp;quot;email me if this thread is upated&amp;quot; option - again, this is useful. It&amp;#39;s really frustrating (as a questioner) to be left hanging with an answer which looks like it &lt;em&gt;might&lt;/em&gt; solve a real headache, if only you could just get the ear of the author for a moment.&lt;/p&gt; &lt;p&gt;Having said all of this:&lt;/p&gt; &lt;h3&gt;Have fun&lt;/h3&gt; &lt;p&gt;In my experience the most useful users are the ones who are obviously passionate about helping others. Don&amp;#39;t do it out of some misguided sense of &amp;quot;duty&amp;quot; - no-one&amp;#39;s paying you to do this (I assume) and no-one can reasonably complain if you just haven&amp;#39;t got the time or energy to answer their question. Save yourself for a time when you can be more enthusiastic and enjoy what you&amp;#39;re doing. Go ahead, have a cup of coffee and watch a Youtube video or something instead. You don&amp;#39;t &lt;em&gt;have&lt;/em&gt; to check whether there are any new questions!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1672745" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Benchmarking: designing an API with unusual goals</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/02/02/benchmarking-designing-an-api-with-unusual-goals.aspx</link><pubDate>Mon, 02 Feb 2009 20:10:21 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1668242</guid><dc:creator>skeet</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1668242</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1668242</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/02/02/benchmarking-designing-an-api-with-unusual-goals.aspx#comments</comments><description>&lt;p&gt;In a couple of recent posts I&amp;#39;ve written about a &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/01/26/benchmarking-made-easy.aspx"&gt;benchmarking framework&lt;/a&gt; and the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/for-vs-foreach-on-arrays-and-lists.aspx"&gt;results it produced for using for vs foreach in loops&lt;/a&gt;. I&amp;#39;m pleased with what I&amp;#39;ve done so far, but I don&amp;#39;t think I&amp;#39;ve gone far enough yet. In particular, while it&amp;#39;s good at testing multiple algorithms against a single input, it&amp;#39;s not good at trying several different inputs to demonstrate the complexity vs input size. I wanted to rethink the design at three levels - what the framework would be capable of, how developers would use it, and then the fine-grained level of what the API would look like in terms of types, methods etc. These may all sound quite similar on the face of it, but this project is somewhat different to a lot of other coding I&amp;#39;ve done, mostly because I want to lower the barrier to entry as far as humanly possible.&lt;/p&gt;  &lt;p&gt;Before any of this is meaningful, however, I really needed an idea of the fundamental goal. Why was I writing yet another benchmarking framework anyway? While I normally cringe at mission statements because they&amp;#39;re so badly formulated and used, I figured this time it would be helpful.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Minibench makes it &lt;strong&gt;easy&lt;/strong&gt; for &lt;strong&gt;developers&lt;/strong&gt; to &lt;strong&gt;write&lt;/strong&gt; and &lt;strong&gt;share&lt;/strong&gt; tests to &lt;strong&gt;investigate&lt;/strong&gt; and &lt;strong&gt;measure&lt;/strong&gt; code &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The words in bold (or for the semantically inclined, the strong words) are the real meat of it. It&amp;#39;s quite scary that even within a single sentence there are seven key points to address. Some are quite simple, others cause grief. Now let&amp;#39;s look at each of the areas of design in turn.&lt;/p&gt;  &lt;p&gt;Each element of the design should either clearly contribute to the mission statement or help in a non-functional way (e.g. make the project feasible in a reasonable timeframe, avoid legal issues etc). I&amp;#39;m aware that with the length of this post, it sounds like I&amp;#39;m engaging in &amp;quot;big upfront design&amp;quot; but I&amp;#39;d like to think that it&amp;#39;s at least informed by my recent attempt, and that the design criteria here are statements of intent rather than implementation commitments. (Aargh, buzzword bingo... please persevere!)&lt;/p&gt;  &lt;h3&gt;What can it do?&lt;/h3&gt;  &lt;p&gt;As we&amp;#39;ve already said, it&amp;#39;s got to be able to measure code performance. That&amp;#39;s a pretty vague definition, however, so I&amp;#39;m going to restrict it a bit - the design is as much about saying what &lt;em&gt;isn&amp;#39;t&lt;/em&gt; included as what &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Each test will take the form of a single piece of code which is executed many times by the framework. It will have an input and an expected output. (Operations with no natural output can return a constant; I&amp;#39;m not going to make any special allowance for them.) &lt;/li&gt;    &lt;li&gt;The framework should take the tedium out of testing. In particular I don&amp;#39;t want to have to run it several times to get a reasonable number of iterations. I &lt;em&gt;suspect&lt;/em&gt; it won&amp;#39;t be feasible to get the framework to guess appropriate inputs, but that would be lovely if possible. &lt;/li&gt;    &lt;li&gt;Only wall time is measured. There are loads of different metrics which &lt;em&gt;could&lt;/em&gt; be applied: CPU execution time, memory usage, IO usage, lock contention - all kinds of things. Wall time (i.e. actual time elapsed, as measured by a clock on the wall) is by far the simplest to understand and capture, and it&amp;#39;s the one most frequently cited in newsgroup and forum questions in my experience. &lt;/li&gt;    &lt;li&gt;The benchmark is uninstrumented. I&amp;#39;m not going to start rewriting your code dynamically. Frankly this is for reasons of laziness. A really professional benchmarking system might take your IL and wrap it in a timing loop within a single method, somehow enforcing that the result of each iteration is used. I don&amp;#39;t believe that&amp;#39;s worth my time and energy, as well as quite possibly being beyond my capabilities. &lt;/li&gt;    &lt;li&gt;As a result of the previous bullet, the piece of code to be run lots of times needs to be non-trivial. The reality is that it&amp;#39;ll end up being called as a delegate. This is pretty quick, but if you&amp;#39;re just testing &amp;quot;is adding two doubles faster or slower than adding two floats&amp;quot; then you&amp;#39;ll need to put a bit more work in (e.g. having a loop in your own code as well). &lt;/li&gt;    &lt;li&gt;As well as the use case of &amp;quot;which of these algorithms performs the best with this input?&amp;quot; I want to support &amp;quot;how does the performance vary as a function of the input?&amp;quot; This should support multiple algorithms at the same time as multiple inputs. &lt;/li&gt;    &lt;li&gt;The output should be flexible but easy to describe in code. For single-input tests simple text output is fine (although the exact figures to produce can be interesting); for multiple inputs against multiple tests a graph would often be ideal. If I don&amp;#39;t have the energy to write a graphing output I should at least support writing to CSV or TSV so that a spreadsheet or graphing tool can do the heavy lifting. &lt;/li&gt;    &lt;li&gt;The output should be &lt;em&gt;useful&lt;/em&gt; - it should make it easy to compare the performance of different algorithms and/or inputs. It&amp;#39;s clear from the previous post here that &lt;em&gt;just&lt;/em&gt; including the scaled score doesn&amp;#39;t give an obvious meaning. Some careful wording in the output, as well as labeled columns, may be required. This is emphatically &lt;em&gt;not&lt;/em&gt; a dig at anyone confused by the last post - any confusion was my own fault.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Okay, that doesn&amp;#39;t sound too unreasonable. The next area is much harder, in my view.&lt;/p&gt;  &lt;h3&gt;How does a developer use it?&lt;/h3&gt;  &lt;p&gt;Possibly the most important word in the mission statement is &lt;strong&gt;share&lt;/strong&gt;. The reason I started this project at all is that I was fed up with spending ages writing timing loops for benchmarks which I&amp;#39;d then post on newsgroups or Stack Overflow. That means there are two (overlapping) categories of user:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A developer writing a test. This needs to be easy, but that&amp;#39;s an aspect of design that I&amp;#39;m reasonably familiar with. I&amp;#39;m not saying I&amp;#39;m &lt;em&gt;good&lt;/em&gt; at it, but at least I have some prior experience. &lt;/li&gt;    &lt;li&gt;A developer reading a newsgroup/forum post, and wanting to run the benchark for themselves. This distribution aspect is the hard bit - or at least the bit requiring imagination. I want the barrier to running the code to be really, &lt;em&gt;really&lt;/em&gt; low. I suspect that there&amp;#39;ll be a &amp;quot;fear of the unknown&amp;quot; to start with which is hard to conquer, but if the framework becomes widely used I want the reader&amp;#39;s reaction to be: &amp;quot;Ah, there&amp;#39;s a MiniBench for this. I&amp;#39;m confident that I can download and run this code with almost no effort.&amp;quot; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This second bullet is the one that my friend Douglas and I have been discussing over the weekend, in some ways playing a game of one-upmanship: &amp;quot;I can think of an idea which is &lt;em&gt;even easier&lt;/em&gt; than yours.&amp;quot; It&amp;#39;s a really fun game to play. Things we&amp;#39;ve thought about so far:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A web page which lets you upload a full program (without the framework) and spits out a URL which can be posted onto Stack Overflow etc. The user would then choose from the following formats: &lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Single .cs file containing the whole program - just compile and run. (This would also be shown on the download page.) &lt;/li&gt;      &lt;li&gt;Test code only - for those whole already have the framework &lt;/li&gt;      &lt;li&gt;Batch file - just run it to extract/build/run the C# code. &lt;/li&gt;      &lt;li&gt;NAnt project file containing the C# code embedded in it - just run NAnt &lt;/li&gt;      &lt;li&gt;MSBuild project file - ditto but with msbuild. &lt;/li&gt;      &lt;li&gt;Zipped project – open the project to load the test in one file and the framework code in other (possibly separate) .cs files &lt;/li&gt;      &lt;li&gt;Zipped solution – open to load two projects: the test code in one and the framework in the other &lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;A web page which which lets you upload your results and browse the results of others &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Nothing&amp;#39;s finalised here, but I like the general idea. I&amp;#39;ve managed (fairly easily) to write a &amp;quot;self-building&amp;quot; batch file, but I haven&amp;#39;t tried with NAnt/MSBuild yet. I can&amp;#39;t imagine it&amp;#39;s that hard - but then I&amp;#39;m not sure how much value there is either. What I &lt;em&gt;do&lt;/em&gt; want to try to aim for is users running the tests properly, first time, without much effort. Again, looking back at the last post, I want to make it obvious to users if they&amp;#39;re running under a debugger, which is almost always the wrong thing to be doing. (I&amp;#39;m pretty sure there&amp;#39;s an API for this somewhere, and if there&amp;#39;s not I&amp;#39;m sure I can work out an evil way of detecting it anyway.)&lt;/p&gt;  &lt;p&gt;The main thing is the ease of downloading and running the benchmark. I can&amp;#39;t see how it could be much easier than &amp;quot;follow link; choose format and download; run batch file&amp;quot; - unless the link itself was to the batch file, of course. (That would make it harder to use for people who wanted to get the source in a more normal format, of course.)&lt;/p&gt;  &lt;p&gt;Going back to the point of view of the developer writing the test, I need to make sure it&amp;#39;s easy enough for &lt;em&gt;me&lt;/em&gt; to use from home, work and on the train. That &lt;em&gt;may&lt;/em&gt; mean a web page where I can just type in code, the input and expected output, and let it fill in the rest of the code for me. It &lt;em&gt;may&lt;/em&gt; mean compiling a source file against a library from the command line. It &lt;em&gt;may&lt;/em&gt; mean compiling a source file against the source code of the framework from the command line, with the framework code all in one file. It &lt;em&gt;may&lt;/em&gt; mean building in Visual Studio. I&amp;#39;d like to make all of these cases as simple as possible - which is likely to make it simple for other developers as well. I&amp;#39;m not planning on optimising the experience when it comes to writing a benchmark on my mobile though - that might be a step too far!&lt;/p&gt;  &lt;h3&gt;What should the API look like?&lt;/h3&gt;  &lt;p&gt;When we get down to the nitty-gritty of types and methods, I think what I&amp;#39;ve got is a good starting point. There are still a few things to think about though:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We &lt;em&gt;nearly&lt;/em&gt; have the functionality required for running a suite with different inputs already - the only problem is that we&amp;#39;re specifying the input (and expected output) in the constructor rather than as parameters to the RunTests method. I could change that... but then we lose the benefit of type inference when creating the suite. I haven&amp;#39;t resolved this to my satisfaction yet :(&lt;/li&gt;    &lt;li&gt;The idea of having the suite automatically set up using attributed methods appeals, although we&amp;#39;d still need a Main method to create the suite and format the output. The suite creation can be simplified, but the chances of magically picking the most appropriate output are fairly slim. I suppose it could go for the &amp;quot;scale to best by number of iterations and show all columns&amp;quot; option by default... that still leaves the input and expected output, of course. I&amp;#39;m sure I&amp;#39;ll have &lt;em&gt;something&lt;/em&gt; like this as an option, but I don&amp;#39;t know how far it will go.&lt;/li&gt;    &lt;li&gt;The &amp;quot;configuration&amp;quot; side of it is expressed as a couple of constants at the moment. These control the minimum amount of time to run tests for before we believe we&amp;#39;ll be able to guess how many iterations we&amp;#39;ll need to get close to the target time, and the target time itself. These are currently set at 2 seconds and 30 seconds respectively - but when running tests just to check that you&amp;#39;ve got the right output format etc, that&amp;#39;s far too long. I suspect I should make a test suite have a configuration, and &lt;em&gt;default&lt;/em&gt; to those constants but allow them to be specified on the command line as well, or explicitly in code.&lt;/li&gt;    &lt;li&gt;Why do we need to set the expected output? In many cases you can be pretty confident that at least &lt;em&gt;one&lt;/em&gt; of the test cases will be correct - so it&amp;#39;s probably simpler just to run each test once and check that the results are the same for all of them, and take that as the expected output. If you don&amp;#39;t have to specify the expected output, it becomes easier to specify a sequence of inputs to test.&lt;/li&gt;    &lt;li&gt;Currently BenchmarkResult is nongeneric. This makes things simpler internally - but should a result know the input that it was derived from? Or should the ResultSuite (which is also nongeneric) know the input that has been applied to all its functions? The information will certainly need to be &lt;em&gt;somewhere&lt;/em&gt; so that it can be output appropriately in the multiple input case.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;My main points of design focus around three areas:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is it easy to pick up? The more flexible it is, with lots of options, the more daunting it may seem.&lt;/li&gt;    &lt;li&gt;Is it flexible enough to be useful in a variety of situations? I don&amp;#39;t know what users will want to benchmark - and I don&amp;#39;t build the right tool, it will be worthless to them.&lt;/li&gt;    &lt;li&gt;Is the resulting test code easy and brief enough to include in a forum post, with a link to the full program? Will readers understand it?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As you can see, these are aimed at three slightly different people: the first time test writer, the veteran test writer, and the first time test reader. Getting the balance between the three is tricky.&lt;/p&gt;  &lt;h3&gt;What&amp;#39;s next?&lt;/h3&gt;  &lt;p&gt;I haven&amp;#39;t started rewriting the framework yet, but will probably do so soon. This time I hope to do it in a rather more test-driven way, although of course the timing-specific elements will be tricky unless I start using a programmatic clock etc. I&amp;#39;d really like comments around this whole process:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Is this worth doing?&lt;/li&gt;    &lt;li&gt;Am I asking the right questions?&lt;/li&gt;    &lt;li&gt;Are my answers so far headed in the right direction?&lt;/li&gt;    &lt;li&gt;What else haven&amp;#39;t I thought of?&lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1668242" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Benchmarking/default.aspx">Benchmarking</category></item><item><title>Programming is hard</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/programming-is-hard.aspx</link><pubDate>Thu, 29 Jan 2009 20:28:22 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1667051</guid><dc:creator>skeet</dc:creator><slash:comments>22</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1667051</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1667051</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/29/programming-is-hard.aspx#comments</comments><description>&lt;p&gt;One of the answers to my &amp;quot;controversial opinions&amp;quot; question on Stack Overflow claims that &amp;quot;&lt;a href="http://stackoverflow.com/questions/406760/whats-your-most-controversial-programming-opinion/479007#479007"&gt;programming is so easy a five year old can do it.&lt;/a&gt;&amp;quot;&lt;/p&gt; &lt;p&gt;I&amp;#39;m sure there are some aspects of programming which a five year old can do. Other parts are apparently very hard though. Today I came to the following conclusion:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If your code deals with arbitrary human text, it&amp;#39;s probably broken. (Have you taken the &lt;a href="http://www.moserware.com/2008/02/does-your-code-pass-turkey-test.html"&gt;Turkey test&lt;/a&gt; recently?)  &lt;li&gt;If your code deals with floating point numbers, it&amp;#39;s probably broken.  &lt;li&gt;If your code deals with concurrency (whether that means database transactions, threading, whatever), it&amp;#39;s probably broken.  &lt;li&gt;If your code deals with dates, times and time zones, it&amp;#39;s probably broken. (Time zones in particular are hideous.) &lt;li&gt;If your code has a user interface with anything other than a fixed size and a fixed set of labels (no i18n), it&amp;#39;s probably broken.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;You know what I like working with? Integers. They&amp;#39;re nice and predictable. Give me integers, and I can pretty much predict how they&amp;#39;ll behave. So long as they don&amp;#39;t overflow. Of have an architecture-and-processor-dependent size.&lt;/p&gt; &lt;p&gt;Maybe you think I&amp;#39;m too cynical. I think I&amp;#39;m rather bullish, actually. After all, I used the word &amp;quot;probably&amp;quot; on all of those bullet points.&lt;/p&gt; &lt;p&gt;The thing that amazes me is that despite all this hardness, despite us never really achieving perfection, programs seem to work well enough most of the time. It&amp;#39;s a bit like a bicycle - it really shouldn&amp;#39;t work. I mean, if you&amp;#39;d never seen one working, and someone told you that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can&amp;#39;t really balance when it&amp;#39;s stationary. You have to go at a reasonable speed to stay stable.&lt;/li&gt; &lt;li&gt;Turning is a lot easier if you lean towards the ground.&lt;/li&gt; &lt;li&gt;The bit of the bike which is actually in contact with the ground is always stationary, even when the bike itself is moving.&lt;/li&gt; &lt;li&gt;You stop by squeezing bits of rubber onto the wheels.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Would you not be a touch skeptical? Likewise when I see the complexity of software and our collective failure to cope with it, I&amp;#39;m frankly astonished that I can even write this blog post.&lt;/p&gt; &lt;p&gt;It&amp;#39;s been a hard day. I achieved a small victory over one of the bullet points in the first list today. It took hours, and I pity my colleague who&amp;#39;s going to code review it (I&amp;#39;ve made it as clear as I can, but some things are just designed to mess with your head) - but it&amp;#39;s done. I feel simultaneously satisfied in a useful day&amp;#39;s work, and depressed at the need for it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1667051" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>RFID: What I really want it for</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/24/rfid-what-i-really-want-it-for.aspx</link><pubDate>Sat, 24 Jan 2009 19:28:40 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1665601</guid><dc:creator>skeet</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1665601</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1665601</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/24/rfid-what-i-really-want-it-for.aspx#comments</comments><description>&lt;p&gt;This isn&amp;#39;t really coding related, but it&amp;#39;s &lt;em&gt;technology&lt;/em&gt; related at least. There&amp;#39;s been a lot of fuss made about how great or awful RFID is and will be in the future, in terms of usefuless and privacy invasion respectively. There&amp;#39;s one use which I haven&amp;#39;t seen discussed, but which seems pretty obvious to me - but with further enhancements available.&lt;/p&gt; &lt;p&gt;Basically, I want RFID on clothes to tell me useful stuff. Suppose each item of clothing were uniquely tagged, and you had a bunch of scanners in your home linked up to one system which stored metadata about the clothes. Suddenly the following tasks become easier:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Working out which wash cycle to use for a whole washing basket. Can&amp;#39;t see the dark sock hidden in the white wash? The RFID scanner could alert you to it. Likewise tumbledrying - no need to check each item separately, just attach the scanner over the tumbledryer door and wait for it to beep as you try to put something in which shouldn&amp;#39;t be tumbled.&lt;/li&gt; &lt;li&gt;Separating clothes to put them away after they&amp;#39;re clean and dry. Admittedly this is more of a chore for our household than others (with twin boys and an older brother, where some items of clothing could belong to any of them) but it would be really, &lt;em&gt;really&lt;/em&gt; useful for us.&lt;/li&gt; &lt;li&gt;Remembering who you&amp;#39;ve borrowed which clothes from. Kids grow out of clothes very quickly; we have a number of friends who lend us clothes from their children, and likewise we lend plenty of clothes to them and others. You&amp;#39;ve then got to remember what you borrowed from who, which can become tricky when you&amp;#39;ve got a loft full of bags of clothing. Wouldn&amp;#39;t it be nice to just &amp;quot;label&amp;quot; all the clothes in a bag with the owner&amp;#39;s name when you first receive them, and then just pass a scanner near everything quickly later on?&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The privacy issues of all of this would have to be worked out carefully (as the simplest solution would allow your movements to be traced just by which clothes you&amp;#39;re wearing) but if it &lt;em&gt;does&lt;/em&gt; end up being possible, I&amp;#39;ll be hugely grateful for this.&lt;/p&gt; &lt;p&gt;(Next up, benchmarking of for vs foreach in various situations. In other words, back to our regular schedule :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1665601" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category></item><item><title>Quick rant: why isn't there an Exception(string, params object[]) constructor?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/23/quick-rant-why-isn-t-there-an-exception-string-params-object-constructor.aspx</link><pubDate>Fri, 23 Jan 2009 21:42:52 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1665160</guid><dc:creator>skeet</dc:creator><slash:comments>26</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1665160</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1665160</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/23/quick-rant-why-isn-t-there-an-exception-string-params-object-constructor.aspx#comments</comments><description>&lt;p&gt;This &lt;a href="http://stackoverflow.com/questions/474564"&gt;Stack Overflow question&lt;/a&gt; has reminded me of something I often wish existed in common exception constructors - an overload taking a format string and values. For instance, it would be really nice to be able to write:&lt;/p&gt; &lt;div class="code"&gt;&lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span class="Keyword"&gt;new&lt;/span&gt; IOException(&lt;span class="String"&gt;&amp;quot;Expected to read {0} bytes but only {1} were available&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requiredSize, bytesRead); &lt;/div&gt; &lt;p&gt;Of course, with no way of explicitly inheriting constructors (which I almost always want for exceptions, and almost never want for anything else) it would mean yet another overload to copy and paste from another exception, but the times when I&amp;#39;ve actually written it in my own exceptions it&amp;#39;s been &lt;em&gt;hugely&lt;/em&gt; handy, particularly for tricky cases where you&amp;#39;ve got a lot of data to include in the message. (You&amp;#39;d also want an overload taking a nested exception first as well, adding to the baggage...)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1665160" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>Stack Overflow reputation and being a micro-celebrity</title><link>http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-and-being-a-micro-celebrity.aspx</link><pubDate>Thu, 15 Jan 2009 22:39:18 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1662339</guid><dc:creator>skeet</dc:creator><slash:comments>44</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1662339</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1662339</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2009/01/15/stack-overflow-reputation-and-being-a-micro-celebrity.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve considered writing a bit about this before, but not done so for fear of looking like a jerk. I still think I may well end up looking like a jerk, but this is all stuff I&amp;#39;m interested in and I&amp;#39;ll enjoy writing about it, so on we go. Much of this is based on experiences at and around &lt;a href="http://pobox.com/~skeet/csharp"&gt;Stack Overflow&lt;/a&gt;, and it&amp;#39;s more likely to be interesting to you if you&amp;#39;re a regular there or at least know the basic premises and mechanics. Even then you may well not be particularly interested - as much as anything, this post is to try to get some thoughts out of my system so I can stop thinking about how I &lt;em&gt;would&lt;/em&gt; blog about it. If you don&amp;#39;t want the introspection, but want to know how to judge my egotism, skipping to the summary is probably a good plan. If you really don&amp;#39;t care at all, that&amp;#39;s probably a healthy sign. Quit now while you&amp;#39;re ahead.&lt;/p&gt; &lt;h3&gt;What is a micro-celebrity?&lt;/h3&gt; &lt;p&gt;A couple of minutes ago, I thought I might have been original with the term &amp;quot;micro-celebrity&amp;quot; but &lt;a href="http://www.google.co.uk/search?q=micro-celebrity"&gt;I&amp;#39;m clearly not&lt;/a&gt;. I may well not use the term the same way other people do, however, so here&amp;#39;s my rough definition solely for the purposes of this post:&lt;/p&gt; &lt;blockquote&gt;A micro-celebrity is someone who gains a significant level of notoriety within a relatively limited community on the internet, usually with a positive feedback loop.&lt;/blockquote&gt; &lt;p&gt;Yes, it&amp;#39;s woolly. Not to worry.&lt;/p&gt; &lt;p&gt;I would consider myself to have been a micro-celebrity in five distinct communities over the course of the last 14 years:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The alt.books.stephen-king newsgroup&lt;/li&gt; &lt;li&gt;The mostly web-based community around Team17&amp;#39;s series of &amp;quot;Worms&amp;quot; games (well, the first few, on the PC only)&lt;/li&gt; &lt;li&gt;The comp.lang.java.* newsgroups&lt;/li&gt; &lt;li&gt;The microsoft.public.dotnet.languages.csharp newsgroup&lt;/li&gt; &lt;li&gt;Stack Overflow&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The last has been far and away the most blatant case. This is roughly how it goes - or at least how it&amp;#39;s gone in each of the above cases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Spend some time in the community, post quite a lot. Shouting loudly works remarkably well on the internet - if you&amp;#39;re among the most prolific writers in a group, you &lt;em&gt;will&lt;/em&gt; get noticed. Admittedly it helps to try hard to post well-written and interesting thoughts.&lt;/li&gt; &lt;li&gt;After a while, a few people will refer to you in their other conversations. For instance, if someone in the Java newsgroup was talking about &amp;quot;objects being passed by reference&amp;quot;, another poster might say something like &amp;quot;Don&amp;#39;t let Jon Skeet hear you talking like that.&amp;quot;&lt;/li&gt; &lt;li&gt;Play along with it, just a bit. Don&amp;#39;t blow your own trumpet, but equally don&amp;#39;t discourage it. A few wry comments to show that you don&amp;#39;t mind often go down well.&lt;/li&gt; &lt;li&gt;Sooner or later, you will find yourself not just mentioned in another topic, but being the topic of conversation yourself. At this point, it&amp;#39;s no longer an inside joke that just the core members of the group &amp;quot;get&amp;quot; - you&amp;#39;re now communal property, and almost &lt;em&gt;any&lt;/em&gt; regular will be part of the joke.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;One interesting thing you might have noticed about the above is that it doesn&amp;#39;t really take very much skill. It takes a fair amount of time, and ideally you should have some reasonable thoughts and the ability to express yourself clearly, but you certainly don&amp;#39;t have to be a genius. Good job, really.&lt;/p&gt; &lt;h3&gt;How much do you care?&lt;/h3&gt; &lt;p&gt;This is obviously very personal, and I&amp;#39;m only speaking for myself (as ever).&lt;/p&gt; &lt;p&gt;It&amp;#39;s undeniably an ego boost. Just about every day there&amp;#39;s &lt;em&gt;something&lt;/em&gt; on Stack Overflow to laugh about in reference to me. How could I &lt;em&gt;not&lt;/em&gt; enjoy that? How could it not inflate my sense of self-worth just a little bit? I could dismiss it as being entirely silly and meaningless - which it is, ultimately - but it&amp;#39;s still &lt;em&gt;fun&lt;/em&gt; and I get a kick out of it. And yes, I&amp;#39;m sorry to say I bore/annoy my colleagues and wife with the latest Stack Overflow news, because I&amp;#39;ve always been the selfish kind of person who wants to talk about what &lt;em&gt;they&amp;#39;re&lt;/em&gt; up to instead of asking the other person about their interests. This is an unfortunate trait which has relatively little to do with the micro-celebrity business.&lt;/p&gt; &lt;p&gt;One very good thing for keeping my ego in check is that at Google, I converse with people who are smarter than me every day, whether at coffee, breakfast, lunch or just while coding. There&amp;#39;s no sense of anyone trying to make anyone else feel small, but it&amp;#39;s pretty obvious that I&amp;#39;m nothing special when it comes to Google. Now, I don&amp;#39;t want to put on too much false modesty - I know I have a reasonable amount of experience, and I happen to know two very popular platforms reasonably well (which really helps on Stack Overflow- being the world&amp;#39;s greatest guru on MUMPS isn&amp;#39;t going to get you much love), and perhaps most importantly I can communicate pretty well. All of these are good things, and I&amp;#39;m proud of my career and particularly C# in Depth...&lt;/p&gt; &lt;p&gt;... but let&amp;#39;s get real here. The &lt;a href="http://stackoverflow.com/questions/305223/jon-skeet-facts"&gt;Jon Skeet Facts&lt;/a&gt; page isn&amp;#39;t really about me. It&amp;#39;s about making geek jokes where the exact subject is largely irrelevant. It could very easily have been about someone else with little change in the humour. Admittedly the funniest answers (to my mind) are the ones which &lt;em&gt;do&lt;/em&gt; have some bearing on me (particularly the one about having written a book on C# 5.0 already) - but that doesn&amp;#39;t mean there&amp;#39;s anything really serious in it. I hope it&amp;#39;s pretty obvious to everyone that I&amp;#39;m &lt;em&gt;not&lt;/em&gt; a genius programmer. I&amp;#39;d like to think I&amp;#39;m pretty good, but I&amp;#39;m not off-the-charts awesome by any means. (In terms of computer science, I&amp;#39;m nothing special &lt;em&gt;at all&lt;/em&gt; and I have a really limited range of languages/paradigms. I&amp;#39;m trying to do something about those, but it&amp;#39;s hard when there&amp;#39;s always another question to answer.)&lt;/p&gt; &lt;p&gt;It&amp;#39;s worth bearing in mind the &amp;quot;micro&amp;quot; part of micro-celebrity. I suspect that if we somehow got all the C# developers in the world together and asked them whether they&amp;#39;d heard of Jon Skeet, fewer than 0.1% would say yes. (That&amp;#39;s a &lt;em&gt;complete&lt;/em&gt; guess, by the way. I have really no idea. The point is I&amp;#39;m pretty sure it&amp;#39;s a small number.) Compared with the sea of developers, the set of Stack Overflow &lt;em&gt;regulars&lt;/em&gt; is a very small pond.&lt;/p&gt; &lt;p&gt;What I care far more about than praise and fandom is the idea of actually &lt;em&gt;helping&lt;/em&gt; people and making a difference. A couple of days ago I had an email from someone saying that C# in Depth had helped them in an interview: they were able to write more elegant code because now they grok lambda expressions. How cool is that? Yes, I know it&amp;#39;s all slightly sickening in a &lt;a href="http://uk.youtube.com/watch?v=JAIWTLal9e4"&gt;&amp;quot;you do a lot of good work for charity&amp;quot;&lt;/a&gt; kind of way - but I suspect it&amp;#39;s what drives most Stack Overflow regulars. Which leads me on to reputation...&lt;/p&gt; &lt;h3&gt;What does Stack Overflow reputation mean to you?&lt;/h3&gt; &lt;p&gt;In virtually every discussion about the Stack Overflow reputation system and its caps, I try to drop in the question of &amp;quot;what&amp;#39;s the point of reputation? What does it mean to you?&amp;quot; It&amp;#39;s one of those questions which everyone needs to answer for themselves. Jeff Atwood&amp;#39;s answer is that reputation is &lt;a href="http://stackoverflow.com/faq"&gt;how much the system trusts you&lt;/a&gt;. My own answers:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It&amp;#39;s a daily goal. Making sure I always get to 200 is a fun little task, and then trying to get accepted answers is a challenge.&lt;/li&gt; &lt;li&gt;It&amp;#39;s measurable data, and you can play with graphs and stats. Hey we&amp;#39;re geeks - it&amp;#39;s fun to play with numbers, however irrelevant they are.&lt;/li&gt; &lt;li&gt;It&amp;#39;s an indication of helpfulness &lt;em&gt;to some extent&lt;/em&gt;. It plays to my ego in terms of both pride of knowledge and the fulfillment of helping people.&lt;/li&gt; &lt;li&gt;It&amp;#39;s useful as an indicator of community trust for the system to use, which is probably more important to Jeff than it is to me.&lt;/li&gt; &lt;li&gt;&lt;em&gt;It&amp;#39;s a game&lt;/em&gt;. This is the most important aspect. I love games. I&amp;#39;m &lt;em&gt;fiercely&lt;/em&gt; competitive, and will always try to work out all the corners of a game&amp;#39;s system - things like it being actually somewhat useless getting accepted answers before you&amp;#39;ve reached the 200 limit. I don&amp;#39;t necessarily &lt;em&gt;play&lt;/em&gt; to the corners of the game (I would rather post a useful but unpopular answer than a popular but harmful one, for serious questions) but I enjoy working them out. I would be interested to measure my levels of testosterone when typing furiously away at an answer, hoping to craft something useful before anyone else does. I&amp;#39;m never going to be &amp;quot;macho&amp;quot; physically, but I can certainly be an alpha geek. So long as it doesn&amp;#39;t go too far, I think it&amp;#39;s a positive thing.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I sometimes sense (perhaps inaccurately) that Jeff and Joel are frustrated with people getting too hung up about reputation. It&amp;#39;s really unimportant in the grand scheme of things - rep in itself isn&amp;#39;t as much of a net contribution to the world&amp;#39;s happiness as the way that Stack Overflow connects people with questions to people with relevant answers really, really quickly. But rep is one of the things that makes Stack Overflow so &amp;quot;sticky&amp;quot; as a website. It&amp;#39;s not that I wouldn&amp;#39;t answer questions if the reputation system went down - after all, I&amp;#39;ve been answering questions on newsgroups for years, for the other reasons mentioned - but the reputation system certainly &lt;em&gt;helps&lt;/em&gt;. Yes, it&amp;#39;s probably taking advantage of a competitive streak which is in some ways ugly... but the &lt;em&gt;result&lt;/em&gt; is a good one.&lt;/p&gt; &lt;p&gt;One downside of the whole micro-celebrity thing - and in particular of being the top rep earner - is that various suggestions (such as &lt;a href="http://stackoverflow.uservoice.com/pages/general/suggestions/35824-change-the-reputation-limit-algorithm"&gt;changing the rep limit algorithm&lt;/a&gt; and &lt;a href="http://stackoverflow.uservoice.com/pages/general/suggestions/95721-monthly-league-for-reputation"&gt;introducing a monthly league&lt;/a&gt;) make me look really selfish. It&amp;#39;s undeniable that both of the suggestions work in my favour. I happen to believe that both work in the community&amp;#39;s favour too, but I can certainly see why people might get the wrong idea about my motivation. I don&amp;#39;t remember thinking of any suggestions which would work &lt;em&gt;against&lt;/em&gt; my personal interests but in the interests of the community. If I do, I&amp;#39;m pretty sure I&amp;#39;ll post them with no hesitation.&lt;/p&gt; &lt;h3&gt;Summary&lt;/h3&gt; &lt;p&gt;Yes, I like the attention of being a micro-celebrity. It would be ridiculous to deny it, and I don&amp;#39;t think it says much more about me than the fact that I&amp;#39;m human.&lt;/p&gt; &lt;p&gt;Yes, I like competing for reputation, even though it&amp;#39;s blatantly obvious that the figure doesn&amp;#39;t reflect programming prowess. It&amp;#39;s &lt;em&gt;part&lt;/em&gt; of the fuel for my addiction to Stack Overflow.&lt;/p&gt; &lt;p&gt;With this out of the way, I hope to return to more technical blog posts. If anything interesting comes up in the comments, I&amp;#39;ll probably edit this post rather than writing a new one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1662339" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item><item><title>How much do you care about blog tags?</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/11/07/how-much-do-you-care-about-blog-tags.aspx</link><pubDate>Fri, 07 Nov 2008 17:09:50 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1653416</guid><dc:creator>skeet</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1653416</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1653416</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/11/07/how-much-do-you-care-about-blog-tags.aspx#comments</comments><description>&lt;p&gt;Occasionally I feel that my collection of tags is somewhat lacking. For instance, I&amp;#39;ve been thinking of adding &amp;quot;language design&amp;quot; and &amp;quot;public speaking&amp;quot; tags - and then going through previous posts and retagging where appropriate.&lt;/p&gt; &lt;p&gt;However, I&amp;#39;d rather not do this if no-one actually uses tags in the first place. I know that I find the tags on Eric Lippert&amp;#39;s blog incredibly handy when I&amp;#39;m going back to look for a particular article, but I suspect that&amp;#39;s mostly because Eric&amp;#39;s blog is so quotable in the first place.&lt;/p&gt; &lt;p&gt;Would it help &lt;em&gt;any&lt;/em&gt; of you for me to be more comprehensive and historically accurate with my tags? If so, I&amp;#39;ll go ahead... otherwise I&amp;#39;ll waste some more time on Stack Overflow :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1653416" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category></item><item><title>Jaffa bugs</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/11/06/jaffa-bugs.aspx</link><pubDate>Thu, 06 Nov 2008 17:15:57 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1653278</guid><dc:creator>skeet</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1653278</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1653278</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/11/06/jaffa-bugs.aspx#comments</comments><description>&lt;p&gt;Currently I&amp;#39;m working on a problem found by one of our testers. Unfortunately, it&amp;#39;s hard to reproduce. Inspired by the fact that yesterday our micro-kitchen had jaffa cakes in, I propose that if we&amp;#39;re going to be frustrated by bugs like this, we might as well at least mock them.&lt;/p&gt; &lt;p&gt;I propose that we call them jaffa bugs, and will work hard to promote this jargon until it takes over the world. Insert evil laugh here.&lt;/p&gt; &lt;p&gt;(Just in case the etymology here isn&amp;#39;t clear, see the &lt;a href="http://en.wikipedia.org/wiki/Only_Fools_and_Horses"&gt;Wikipedia &amp;quot;Only Fools and Horses&amp;quot; entry&lt;/a&gt;.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1653278" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category></item><item><title>DotNetRocks interview</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/10/07/dotnetrocks-interview.aspx</link><pubDate>Tue, 07 Oct 2008 16:33:49 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1650011</guid><dc:creator>skeet</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1650011</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1650011</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/10/07/dotnetrocks-interview.aspx#comments</comments><description>&lt;p&gt;Last Monday evening I had a chat with the guys from &lt;a href="http://dotnetrocks.com"&gt;DotNetRocks&lt;/a&gt;, and today &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=383"&gt;the show has gone live&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I wouldn&amp;#39;t claim to have said anything &lt;em&gt;particularly&lt;/em&gt; earth-shattering, and regular readers will probably be familiar with many of the themes anyway, but I thoroughly enjoyed it and hope you will too. Amongst other things, we talked about:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Protocol buffers&lt;/li&gt; &lt;li&gt;Implicit typing and anonymous types&lt;/li&gt; &lt;li&gt;Why it doesn&amp;#39;t bother me that Office hasn&amp;#39;t been ported to .NET&lt;/li&gt; &lt;li&gt;C# 4&lt;/li&gt; &lt;li&gt;My wishlist for C#&lt;/li&gt; &lt;li&gt;Threading and Parallel Extensions&lt;/li&gt; &lt;li&gt;Working for Google&lt;/li&gt; &lt;li&gt;How to learn LINQ&lt;/li&gt; &lt;li&gt;C# in Depth&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Feedback welcome. And yes, I know I sound somewhat like a stereotypical upper-class idiot at times. Unfortunately there&amp;#39;s not a lot I can do about that. Only the &amp;quot;idiot&amp;quot; part is accurate :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1650011" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+4/default.aspx">C# 4</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Parallelisation/default.aspx">Parallelisation</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Google/default.aspx">Google</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Protocol+Buffers/default.aspx">Protocol Buffers</category></item><item><title>New addiction: Stack Overflow</title><link>http://msmvps.com/blogs/jon_skeet/archive/2008/09/28/new-addiction-stack-overflow.aspx</link><pubDate>Sun, 28 Sep 2008 07:23:08 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1649078</guid><dc:creator>skeet</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1649078</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1649078</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2008/09/28/new-addiction-stack-overflow.aspx#comments</comments><description>&lt;p&gt;This may be old news to many readers, but there&amp;#39;s a relatively new development Q&amp;amp;A site called &lt;a href="http://stackoverflow.com"&gt;Stack Overflow&lt;/a&gt;. I&amp;#39;m not generally a fan of web forums as opposed to newsgroups, but Stack Overflow &lt;em&gt;just works&lt;/em&gt;. In particular, the post/answer editor is better than anything similar that I&amp;#39;ve seen. I&amp;#39;ll readily admit that the reputation side of things appeals to my ego - which and I suspect it&amp;#39;s one of the main reasons it&amp;#39;s so popular. Developers tend to be somewhat egotistical :)&lt;/p&gt; &lt;p&gt;One of the aims of the site is to end up as the pseudo-canonical resource for development questions: sort of a development Wikipedia. Only time will tell whether or not that will actually happen. In particular the fact that early answers are more likely to be read (and voted on) than later ones which have perhaps taken a lot of research and cover the topic more thoroughly. It&amp;#39;s still in public beta, so there&amp;#39;s lots of room for tweaking (and even after launch things could still change, of course).&lt;/p&gt; &lt;p&gt;Just another site to suck up my time...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1649078" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category></item></channel></rss>