<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.pluralsight-training.net/community/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>CraigBlog</title><link>http://www.pluralsight-training.net/community/blogs/craig/default.aspx</link><description>Craig Andera&amp;#39;s Weblog</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Clojure Concurrency Tutorial Available</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/04/09/clojure-concurrency-tutorial-available.aspx</link><pubDate>Fri, 09 Apr 2010 18:45:14 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:76023</guid><dc:creator>craig-andera</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=76023</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=76023</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/04/09/clojure-concurrency-tutorial-available.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;all six parts are now available. That’s over two and a half hours of Clojurey goodness. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; There are now downloadable versions available in wmv and mp4 formats in a variety of resolutions. Just click the download button by each module. Also, the refs module is now up. &lt;/p&gt;  &lt;p&gt;A while back, I wrote up some slides on concurrent programming in &lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; that I used at &lt;a href="http://codebetter.com/blogs/matthew.podwysocki/archive/2010/01/14/ann-dc-alt-net-1-27-2010-clojure.aspx"&gt;a DC ALT.NET presentation&lt;/a&gt;. Since I had them ready, and since Pluralsight has a great infrastructure for doing online training (it’s called &lt;a href="http://www.pluralsight-training.net/microsoft/default.aspx"&gt;Pluralsight On-Demand!&lt;/a&gt;&lt;em&gt;&lt;/em&gt;), it made sense for me to record the content and make it available. So I have. &lt;/p&gt;  &lt;p&gt;I’m happy to announce the immediate availability of the first four parts of my six-part Clojure concurrency tutorial, a screencast. You can find it &lt;a href="http://link.pluralsight.com/clojure"&gt;here&lt;/a&gt;. It is freely available, and no registration is required. The final two parts will be available in less than a week. &lt;/p&gt;  &lt;p&gt;I wrote the tutorial from the perspective of a .NET programmer who is new to Clojure. I don’t focus on the language itself, but rather the concurrency support in it. However, I don’t assume any prior knowledge of Clojure, so we start by covering just enough language syntax to get us through the demos. From there we dive into vars, atoms, agents, refs, promises, futures, and all sorts of good stuff. &lt;/p&gt;  &lt;p&gt;If you’ve been reading my blog, you’ll know I’m a big fan of Clojure. One of the reasons for this - but not the only reason - is its fantastic support for concurrent programming. I like to say that it provides “sanity in the face of concurrency”. If you’re interested to learn more, check out &lt;a href="http://link.pluralsight.com/clojure"&gt;the tutorial&lt;/a&gt;, and please – let me know what you think!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=76023" width="1" height="1"&gt;</description></item><item><title>The Zero-Argument Overload of Any</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/04/02/the-zero-argument-overload-of-any.aspx</link><pubDate>Fri, 02 Apr 2010 20:23:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:75873</guid><dc:creator>craig-andera</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=75873</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=75873</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/04/02/the-zero-argument-overload-of-any.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m a pretty big fan of Linq. I use it all the time in my C# code. But it&amp;#39;s a relatively big library, and I&amp;#39;ve never studied it exhaustively, so from time to time I come across some neat corner of it I&amp;#39;ve never seen before. In fact, that happened just the other day.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I find that I&amp;#39;ll frequently write test code that looks like this:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Assert.AreEqual(0, collection.Count());&amp;nbsp;&lt;/p&gt;
&lt;p&gt;or the inverse:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Assert.AreNotEqual(0, collection.Count());&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve done it often enough that I have thought I ought to write a pair of extension methods on Assert called IsEmpty and IsNotEmpty. That&amp;#39;s probably still a good idea, but it also turns out that the Linq extension method Any (normally used to test if at least one element of an enumeration meets some criteria) also has a zero-overload method that simply returns true if the enumeration has any elements at all. So I could rewrite the above tests as:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Assert.IsFalse(collection.Any());&lt;/p&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;p&gt;Assert.IsTrue(collection.Any());&lt;/p&gt;
&lt;p&gt;respectively. While having Assert.IsEmpty and Assert.IsNotEmpty extension methods would be better (perhaps your test framework already provides them), this is still a handy little thing to know about.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=75873" width="1" height="1"&gt;</description></item><item><title>Implementations of Slideshow in C# and Clojure</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/17/implementations-of-slideshow-in-c-and-clojure.aspx</link><pubDate>Wed, 17 Mar 2010 15:44:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:75489</guid><dc:creator>craig-andera</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=75489</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=75489</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/17/implementations-of-slideshow-in-c-and-clojure.aspx#comments</comments><description>&lt;p&gt;As I promised I would &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2010/03/10/creating-a-lazy-enumeration-of-directory-descendants-in-c.aspx"&gt;the other day&lt;/a&gt;, I went ahead and implemented my stupid little slideshow app in both C# and &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt;. It was an interesting exercise, the more so because I&amp;rsquo;m not entirely sure what conclusions to draw. I may have more to say about this at some point in the future, but for now I thought I&amp;rsquo;d just put up the code and share some general observations. So, you can find the C# version &lt;a href="http://gist.github.com/335331"&gt;here&lt;/a&gt;, and the Clojure version &lt;a href="http://gist.github.com/335332"&gt;here&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The app is pretty simple. It starts a low-priority thread that lazily populates a list of filenames that are descendants of a particular directory. Meanwhile, a timer procedure randomly selects one of the filenames out of the ones that have been found so far and invalidates the screen. The repaint simply draws the image centered on a fullscreen window with a black background. If no images have been found yet, then it prints &amp;ldquo;Working&amp;hellip;&amp;rdquo; on the screen instead. &lt;/p&gt;
&lt;p&gt;The Clojure version isn&amp;rsquo;t really an app, because I wrote all this code really quickly and didn&amp;rsquo;t bother giving it a main() function, but other than that they&amp;rsquo;re about as similar as I could make them, given that one is running against Swing on the JVM and the other against Windows Forms on the CLR. I suppose I could have written the Clojure one against Windows Forms as well using &lt;a href="http://github.com/richhickey/clojure-clr"&gt;ClojureCLR&lt;/a&gt;, but honestly it was simply more interesting to me to use Swing, as I&amp;rsquo;m not familiar with it. And this is anything but a scientific experiment. &lt;/p&gt;
&lt;p&gt;For the C# version, I eschewed the Forms designer to keep it closer to the spirit of the Clojure one. And for something like this, where I&amp;rsquo;m just blasting raw pixels at the screen, I think that was a reasonable choice. &lt;/p&gt;
&lt;p&gt;I wrote the Clojure version first. Perhaps that was a bad choice, since it meant I spent a lot more time on the Clojure one, since I had to figure out all the little details, like how to center an image in a region. It certainly made the C# version a lot easier to write, since I was pretty much just translating. But the C# version probably would have been easier for to write in any event, since I&amp;rsquo;ve been writing C# professionally for almost 10 years, and Clojure in my spare time for less than two.&lt;/p&gt;
&lt;p&gt;One thing that surprised me a bit is that the Clojure version turned out to be not much shorter than the C# version. Indeed, if I had put closing braces on the same line as the statement they close (which is like the Clojure style I use), I&amp;rsquo;d bet they&amp;rsquo;re about the same. I had expected it to be quite a bit more compact, since, as I&amp;rsquo;ve said before, my experience with Clojure has been that it generally lets you be more concise. In this case, I suspect it has to do with the fact that I had a lot of Swing-related code, which doesn&amp;rsquo;t lend itself strongly to the sorts of concision that Clojure supports. Or it could be the fact that I&amp;rsquo;m a Clojure n00b, and just don&amp;rsquo;t know how to structure the code to hit a good balance of terseness with readability. Certainly, I could make it a bit shorter by inlining calls to things like make-frame. Other recommendations as to how better to write either version would be more than welcome. &lt;/p&gt;
&lt;p&gt;Both versions of the code are pretty rough, as I wrote them essentially while I was waiting for stuff to install on a VM. I&amp;rsquo;d definitely clean them up more if I were going to do anything with them, but I figured it was better to get it up here than to wait potentially forever to get it polished. Really, I&amp;rsquo;m just trying to point out that not all my code looks this crappy. :) &lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll note that in the Clojure version, I use an atom to store the list of filenames. That&amp;rsquo;s not because I&amp;rsquo;m taking advantage of Clojure&amp;rsquo;s awesome concurrency support, it&amp;rsquo;s because it was a convenient thing to do. Note that the C# version doesn&amp;rsquo;t bother with synchronization at all, since I&amp;rsquo;ve only got two threads, and one is only reading, and one is only appending. If I wanted to get fancier with the threads (e.g. have another thread doing look-ahead loading of the next image), then I might have to start doing synchronization. I&amp;rsquo;d be in good shape on the Clojure side then, since not much would have to change, and the fact that Clojure values are immutable really helps. I don&amp;rsquo;t think the C# version wouldn&amp;rsquo;t need too much work, but I&amp;rsquo;d have to think about it more to be sure, and it would depend on exactly what I was trying to do. &lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s apropos of nothing, but it made me smile that the C# version required PInvoke to get a fullscreen window, and the Swing one just supported it out-of-the-box. &lt;/p&gt;
&lt;p&gt;Being familiar with Visual Studio was a definite benefit when working with the C# code. I&amp;rsquo;m not very facile with the debugging capabilities of Emacs/SLIME, which is what I use to develop Clojure, and when I had problems it took me a little longer to figure them out. That said, having the REPL was really awesome, and it really makes me hate the Immediate Window in Visual Studio by comparison. It would be interesting to try &lt;a href="http://www.bestinclass.dk/index.php/2010/03/clojure-ides-the-grand-tour-getting-started/"&gt;some of the other Clojure IDEs&lt;/a&gt; to see how they stack up.&lt;/p&gt;
&lt;p&gt;Neither version of the code has much in the way of comments. Sorry about that. :)&lt;/p&gt;
&lt;p&gt;Anyway, that&amp;rsquo;s my pile of unstructured thoughts. Hope it&amp;rsquo;s of interest, if not value, to at least some of you. And as I said, further discussion, rewrites, comments, and criticism are wholly welcome.&lt;/p&gt;
&lt;div&gt;

&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=75489" width="1" height="1"&gt;</description></item><item><title>Creating a Lazy Enumeration of Directory Descendants in C#</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/10/creating-a-lazy-enumeration-of-directory-descendants-in-c.aspx</link><pubDate>Wed, 10 Mar 2010 13:57:18 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:75397</guid><dc:creator>craig-andera</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=75397</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=75397</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/10/creating-a-lazy-enumeration-of-directory-descendants-in-c.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Update: &lt;/strong&gt;it &lt;a href="http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/10/75386.aspx#comments"&gt;turns out that Clojure has a built-in file-seq function&lt;/a&gt; (thanks to Stuart Sierra for pointing this out) that already does exactly this, making Clojure the winner hands-down for brevity :) Seriously though, arguments about “batteries included” aside – although a valid point of consideration – I still think it’s interesting to consider the bits of code below. &lt;/p&gt;  &lt;p&gt;Yesterday, I &lt;a href="http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/09/creating-a-lazy-sequence-of-directory-descendants-in-clojure.aspx"&gt;posted some Clojure code&lt;/a&gt; that showed how to create a function that would lazily return all the descendants of a directory. Here’s the code again: &lt;/p&gt;  &lt;pre&gt;(import [java.io File])

(defn dir-descendants [dir]
  (let [children (.listFiles (File. dir))]
    (lazy-cat 
     (map (memfn getPath) (filter (memfn isFile) children)) 
     (mapcat dir-descendants 
      (map (memfn getPath) (filter (memfn isDirectory) children))))))&lt;/pre&gt;

&lt;p&gt;Towards the end of the post, I tossed off a somewhat off-hand comment: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Two things struck me about writing this code. The first is that it’s really, really compact. It would be even smaller if it weren’t for the calls to memfn, which is just there so I can use a Java method as if it were a Clojure function. The second is that it was a bit of a mind-bender to write, although having written it I find it fairly easy to read. But I suspect both of those things would also be true if I attempted to write the equivalent C# (including the laziness, probably via a “yield return” implementation of IEnumerable somewhere), although it would almost certainly be at least somewhat more verbose. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, &lt;a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2334"&gt;Chris Sells called me on that one&lt;/a&gt;. Here’s the equivalent C# code he came up with: &lt;/p&gt;

&lt;pre&gt;using System.IO;
using System.Collections.Generic;

namespace ConsoleApplication1 {
    class Program {
        static IEnumerable GetDirectoryDecendants(string path) {
            foreach (var file in Directory.GetFiles(path)) { yield return file; }
            foreach (var directory in Directory.GetDirectories(path)) {
                foreach (var file in GetDirectoryDecendants(directory)) { yield return file; }
            }
        }
    }
}&lt;/pre&gt;

&lt;p&gt;I think quantitative comparisons of code terseness are generally pretty silly, but - subjectively - when I look at that it seems just as compact as the Clojure version. So I stand corrected on that one. A few other observations: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Chris included namespace and class statements. Clojure has equivalents for these, but I omitted them. Omitting them from the C# version would make it even shorter. &lt;/li&gt;

  &lt;li&gt;The C# version can actually be made &lt;strong&gt;more&lt;/strong&gt; lazy than the Clojure one because of the CLR’s Directory.EnumerateFiles method, as pointed out by John &lt;a href="http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/09/creating-a-lazy-sequence-of-directory-descendants-in-clojure.aspx#comments"&gt;in the comments to yesterday’s post&lt;/a&gt;. That’s pretty cool. I could, however, take advantage of this if I used &lt;a href="http://wiki.github.com/richhickey/clojure-clr/"&gt;ClojureCLR&lt;/a&gt; instead of the JVM-based Clojure. &lt;/li&gt;

  &lt;li&gt;I said that writing the Clojure version was a bit of a mind-bender. To clarify, the bendiness came from the behavior of lazy-cat, and I think primarily because I’m relatively new to Clojure. The “yield return” in the C# code – which is the key to the laziness – gave me similar pause when I first encountered it years ago. And although I’m comfortable enough with it now, the two yield return statements in Chris’s code made me pause for a moment to convince myself it would work without consuming stack. So I think there’s probably some inherent complexity in the laziness that – like many things – is no big barrier once you internalize it in either language. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I haven’t proven anything to anyone, not even myself. That said, having worked with Clojure a bit and C# a &lt;strong&gt;lot&lt;/strong&gt;, I’m still left with the impression that Clojure is generally more compact. It will be a few years before I can say whether that’s a good thing or not (or even whether it’s true), since I tend to think working with a language on that time scale is the only way to really get to know it. I will do two things, however. The first is to show you another bit of code in both Clojure and C#. First, the C#: &lt;/p&gt;

&lt;pre&gt;private static IEnumerable Fibs()
{
    yield return 0; 
    yield return 1; 
	
    int a = 0; 
    int b = 1; 
    while (true)
    {
        int temp = a + b; 
        a = b; 
        b = temp; 
        yield return b; 
    }
}&lt;/pre&gt;

&lt;p&gt;Next, the Clojure:&lt;/p&gt;

&lt;pre&gt;(def fibs (lazy-cat [0 1] (map + fibs (rest fibs))))&lt;/pre&gt;

&lt;p&gt;Hopefully it’s obvious from at least one of these that they’re meant to compute the Fibonacci sequence. &lt;/p&gt;

&lt;p&gt;Maybe someone can come up with ways to make the C# more compact: I would welcome such suggestions. And I’m not trying to have a Clojure-versus-C# contest here – those are stupid, like saying, “Which is better: a hammer or a drill press?” But language comparisons are still interesting in that you generally wind up learning something you didn’t know about at least one of the languages. &lt;/p&gt;

&lt;p&gt;The other thing I’m going to do is to implement my slideshow app (the thing that had me writing the directory recursion function in the first place) in both languages and post them here. Until Chris posted, I was pretty sure I knew how they’d stack up. Now I’m just curious! Maybe you are, too. &lt;/p&gt;

&lt;p&gt;Thanks, Chris, for keeping me honest. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=75397" width="1" height="1"&gt;</description></item><item><title>Creating a Lazy Sequence of Directory Descendants in Clojure</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/09/creating-a-lazy-sequence-of-directory-descendants-in-clojure.aspx</link><pubDate>Tue, 09 Mar 2010 14:23:00 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:75386</guid><dc:creator>craig-andera</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=75386</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=75386</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/03/09/creating-a-lazy-sequence-of-directory-descendants-in-clojure.aspx#comments</comments><description>&lt;p&gt;&lt;b&gt;Update: &lt;/b&gt;it turns out Clojure has a built-in function file-seq that does (almost) exactly this. The difference is that you get a lazy sequence of File objects, not paths. Hooray for &amp;quot;batteries included&amp;quot;!&lt;/p&gt;
&lt;p&gt;I was playing around with Clojure this morning, attempting to write a little photo viewer application. As part of this, I wound up writing a function that produces a lazy sequence of all the files that are descendants of a given directory. I was pretty happy with how it turned out, so I thought I&amp;rsquo;d share it. Here&amp;rsquo;s the code in its entirety:&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;pre&gt;(import [java.io File])

(defn dir-descendants [dir]
  (let [children (.listFiles (File. dir))]
    (lazy-cat 
     (map (memfn getPath) (filter (memfn isFile) children)) 
     (mapcat dir-descendants 
      (map (memfn getPath) (filter (memfn isDirectory) children))))))
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;The key bit here is the lazy-cat, which returns a lazy sequence &amp;ndash; it doesn&amp;rsquo;t evaluate the second expression (in which I walk into the children of the current directory) until someone asks for the next element in the sequence. In other words, even though this function looks recursive, it&amp;rsquo;s not. Because lazy-cat returns right away, the &amp;ldquo;nested&amp;rdquo; call to &amp;nbsp;dir-descendants happens after the stack has been popped. This is totally awesome, because it means I can call dir-descendants and it&amp;rsquo;ll return right away. So I can start displaying pictures without having to wait for the entire directory tree to be enumerated.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Two things struck me about writing this code. The first is that it&amp;rsquo;s really, really compact. It would be even smaller if it weren&amp;rsquo;t for the calls to memfn, which is just there so I can use a Java method as if it were a Clojure function. The second is that it was a bit of a mind-bender to write, although having written it I find it fairly easy to read. But I suspect both of those things would also be true if I attempted to write the equivalent C# (including the laziness, probably via a &amp;ldquo;yield return&amp;rdquo; implementation of IEnumerable somewhere), although it would almost certainly be at least somewhat more verbose.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=75386" width="1" height="1"&gt;</description></item><item><title>On the Utility of TestPropertyAttribute</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/02/24/on-the-utility-of-testpropertyattribute.aspx</link><pubDate>Wed, 24 Feb 2010 13:13:54 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:75262</guid><dc:creator>craig-andera</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=75262</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=75262</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/02/24/on-the-utility-of-testpropertyattribute.aspx#comments</comments><description>&lt;p&gt;On the project I’ve been working on lately, I’ve been using the unit test stuff that ships with Visual Studio/.NET, in the Microsoft.VisualStudio.TestTools.UnitTesting namespace. For my purposes, I’ve found it to be adequate, and it has the benefit that I don’t need to include any additional libraries. &lt;/p&gt;  &lt;p&gt;I recently came across one use of it, however, that took me some time to figure out. Primarily because the documentation on this feature sucks pretty bad. It’s the TestPropertyAttribute, and it’s useful enough to be worth knowing about. So I thought I would share. &lt;/p&gt;  &lt;p&gt;If you read &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.testpropertyattribute(VS.80).aspx"&gt;the documentation for TestPropertyAttribute&lt;/a&gt;, your first reaction might well be the same as mine was: “Huh? That looks like it adds precisely &lt;strong&gt;no&lt;/strong&gt; value over any other custom attribute I might write.” Because the docs show that to retrieve the value, you reflect against the test method it’s defined on, which is pretty silly. However, in experimenting, I found that there’s &lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.testcontext.properties(VS.80).aspx"&gt;an equally poorly documented property on the TestContext class&lt;/a&gt; called Properties that you can use to get the value of this attribute. &lt;/p&gt;  &lt;p&gt;Still, if you only need a value within the TestMethod itself, there’s not much value in it, as it’s no better than just hardcoding the value within the body of the test. Where TestProperty shines, though, is that the properties for the current test are also available during the TestInitialize method. That means you can bung a whole bunch of common setup code into your TestInitialize method, and parameterize its behavior based on properties defined on the tests themselves. A little code might help demonstrate what I mean: &lt;/p&gt; &lt;span style="widows:2;text-transform:none;text-indent:0px;border-collapse:separate;font:medium &amp;#39;Times New Roman&amp;#39;;white-space:normal;orphans:2;letter-spacing:normal;word-spacing:0px;-webkit-border-horizontal-spacing:0px;-webkit-border-vertical-spacing:0px;-webkit-text-decorations-in-effect:none;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;" class="Apple-style-span"&gt;&lt;span style="font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;font-size:small;" class="Apple-style-span"&gt;     &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;&lt;br class="Apple-interchange-newline" /&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO; &lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; Microsoft.VisualStudio.TestTools.UnitTesting;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Demo&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    [TestClass]&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ThingTests&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    {&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="rem"&gt;// Note that we have to have a TestContext, and it must&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;span class="rem"&gt;// be named TestContext&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; TestContext TestContext { get; set; }&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        &lt;span class="rem"&gt;// A simple field that we&amp;#39;re going to initialize to &lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        &lt;span class="rem"&gt;// some value in the Initialize method.  &lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _thing; &lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        [TestInitialize]&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        {&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            &lt;span class="rem"&gt;// Obviously we could do something much more complex here.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (TestContext.Properties.Contains(&lt;span class="str"&gt;&amp;quot;thing&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            {&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;                _thing = TestContext.Properties[&lt;span class="str"&gt;&amp;quot;thing&amp;quot;&lt;/span&gt;] &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            }&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            {&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;                _thing = &lt;span class="str"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;; &lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            }&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;        }&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        [TestMethod]&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestAgainstDefaultSetup()&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        {&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            Assert.AreEqual(&lt;span class="str"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;, _thing); &lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        }&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        [TestMethod]&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;        [TestProperty(&lt;span class="str"&gt;&amp;quot;thing&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;non-default&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestAgainstCustomSetup()&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;        {&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;            Assert.AreEqual(&lt;span class="str"&gt;&amp;quot;non-default&amp;quot;&lt;/span&gt;, _thing); &lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;        }&lt;/pre&gt;

    &lt;pre style="margin:0em;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;"&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;    }&lt;/pre&gt;

    &lt;pre style="margin:0em;width:1248px;font-family:consolas, &amp;#39;Courier New&amp;#39;, courier, monospace;color:black;font-size:small;" class="alt"&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;}&lt;/pre&gt;

    &lt;p&gt;&lt;/p&gt;
  &lt;/span&gt;Basically, we’ve got a field _thing that we usually want to leave at the default value of “default”, but in some tests we want to override to some other value. Moreover, we want to override it in the Initialize method, since that’s where we’re doing our setup that’s common across tests. – maybe we have fairly complicated setup that needs to differ only slightly in some tests. So we use the TestProperty attribute to set a property named “thing” to whatever we like. Then, in the Initialize method, we can use TestContext.Properties to check for the presence of that value and take appropriate action. &lt;/span&gt;

&lt;p&gt;I’ve made the code intentionally trivial to more easily demonstrate the concept, but I’m sure you can visualize more realistic scenarios where this might come in handy. For example, I’ve used it to customize which directory my Initialize method operates on.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=75262" width="1" height="1"&gt;</description></item><item><title>2009 – The Year in Review</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/01/05/2009-the-year-in-review.aspx</link><pubDate>Tue, 05 Jan 2010 13:04:36 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:74213</guid><dc:creator>craig-andera</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=74213</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=74213</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2010/01/05/2009-the-year-in-review.aspx#comments</comments><description>&lt;p&gt;With only six posts the entire year, 2009 was my lightest ever for blogging, although I continue to be active on Twitter (&lt;a href="http://twitter.com/craigandera"&gt;here&lt;/a&gt;). I don’t see that changing in 2010. Still, as is my custom, I post herewith a review of 2009, both personal and professional. &lt;/p&gt;  &lt;p&gt;Looking back on &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/12/31/2008-the-year-in-review.aspx"&gt;my review of 2008&lt;/a&gt;, it seems that 2009 was a year of relative stability for me. I continued to work on pretty much the same stuff: primarily MSDN, but a few side projects whenever I could wedge in some free time. And outside of work, family consumes the bulk of my time, although I still manage to run and to occasionally do something else fun (like &lt;a href="http://www.digitalcombatsimulator.com/"&gt;fly the Black Shark&lt;/a&gt; – ping me if you want to join us!). &lt;/p&gt;  &lt;p&gt;The MSDN work has remained interesting, particularly in giving me the chance to work on Visual Studio 2010 itself. That’s right, I have code that will ship in the box! Specifically in the bit that supports offline help. It was quite an experience to work on so large a project, and I’m definitely looking forward to installing the final bits when they are released later this year. &lt;/p&gt;  &lt;p&gt;A few random highlights from the year: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I bought an iPod Touch, which I totally love. I use it constantly, and if it ever broke I’d buy another on in a heartbeat. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://clojure.org/"&gt;Clojure&lt;/a&gt; remains the most interesting programming language I know. I &lt;a href="http://clojure.org/funding"&gt;donated&lt;/a&gt; twice in 2009, and would encourage you to do the same (donating just once would be fine). Even if you don’t care about Clojure - although any serious programmer owes it to themselves to check it out - I assure you that Rich is doing a lot to advance the state of the art in concurrent programming and is worthy of your support. &lt;/li&gt;    &lt;li&gt;I read &lt;a href="http://www.amazon.com/Hobbit-Illustrated-Fantasy-Classic/dp/0345445600/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1262695197&amp;amp;sr=8-2"&gt;a graphic novel version&lt;/a&gt; of “The Hobbit” to my five-year-old…four times. &lt;/li&gt;    &lt;li&gt;We made some progress on the basement, but am still (somewhat depressingly) not done. &lt;/li&gt;    &lt;li&gt;I started using &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; seriously, and think it’s pretty cool.&lt;/li&gt;    &lt;li&gt;I ran in a track meet for the first time since college. And didn’t suck…as much as I thought I would. &lt;/li&gt;    &lt;li&gt;I started playing bass again. Badly, but I don’t care. &lt;/li&gt;    &lt;li&gt;I saw four movies in an actual theater: Earth, Terminator, Harry Potter, Star Trek. That’s roughly four more than I usually see, at least since the kids were born. &lt;/li&gt;    &lt;li&gt;We did lots and lots of travel: I was away from home for a cumulative total of over two months last year, including one trip to Asia. Alice and the girls were away for around &lt;strong&gt;three &lt;/strong&gt;months if you add it up, including a second trip to Asia without me. Crazy. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As for what 2010 holds, I’m honestly not sure. On the personal front, it would be great to finish the basement. But bigger than that by far looms the shadow of Kindergarten, which our older daughter will enter in the fall. I’m sure it’ll be a big transition for everyone around here, particularly in the mornings, which tend to run on the late side most days. But we’ll handle it like we handle everything else. And I’m sure we’ll keep traveling, but hopefully not &lt;em&gt;quite&lt;/em&gt; as much. &lt;/p&gt;  &lt;p&gt;On the work front I really have no idea. I’m continuing to work with MSDN, and that will go on for at least a bit longer, but the life of an independent contractor is filled with uncertainty, and there’s the distinct possibility I’ll have to do a fairly serious (and possibly lengthy) search for work at some point. But as I’ve said before, it’s the rare challenge that doesn’t pose an opportunity. &lt;/p&gt;  &lt;p&gt;Good luck to you in 2010!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=74213" width="1" height="1"&gt;</description></item><item><title>Kim Wolk Gets a Blog</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/10/30/kim-wolk-gets-a-blog.aspx</link><pubDate>Fri, 30 Oct 2009 12:03:23 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:73451</guid><dc:creator>craig-andera</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=73451</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=73451</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/10/30/kim-wolk-gets-a-blog.aspx#comments</comments><description>&lt;p&gt;Excuse me while I blow the dust off the ol’ blog here. &lt;/p&gt;  &lt;p&gt;So I see that &lt;a href="http://blogs.msdn.com/kwolk/"&gt;Kim has a blog now&lt;/a&gt;. Finally. About time. See, Kim is one of the most effective people I’ve worked with in my career. And I’ve worked with her on many different projects for coming up on 15 years now. If she has something to do say, it’s worth listening to. &lt;/p&gt;  &lt;p&gt;Subscribed!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=73451" width="1" height="1"&gt;</description></item><item><title>MSDN Lightweight Mode</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/08/05/msdn-lightweight-mode.aspx</link><pubDate>Wed, 05 Aug 2009 13:54:29 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:71474</guid><dc:creator>craig-andera</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=71474</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=71474</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/08/05/msdn-lightweight-mode.aspx#comments</comments><description>&lt;p&gt;Long time, no blog. Mostly I update on Twitter now (&lt;a href="http://twitter.com/craigandera"&gt;http://twitter.com/craigandera&lt;/a&gt;) – it’s just easier to hurl a 140-character tidbit out than it is to write one of these posts. And I’m nothing if not lazy. But a reader posted a comment over &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2009/04/02/msdn-loband-rocks.aspx#comments"&gt;here&lt;/a&gt; about MSDN Lightweight Mode. I checked it out, and it’s pretty cool, so I thought I would share it here on the blog, since I know not everyone watches my Twitter feed. &lt;/p&gt;  &lt;p&gt;Anyway, have a look at &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates(lightweight).aspx"&gt;http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates(lightweight).aspx&lt;/a&gt; (for example) and see what you think. I like it. I particularly like the fact that I can view just C# code (or just VB, or just whatever), as the noise generated by seeing all the languages is probably my only complaint with the loband view, which I still love and use as my primary interface to the MSDN website.&amp;#160; &lt;/p&gt;  &lt;p&gt;I have no idea if this is an official thing, or an alpha that will disappear tomorrow, or what. Although I’m still doing work for MSDN, I only heard about this via the comment that Robert dropped on my blog. So hopefully I won’t get in trouble for sharing it, since I found out about it in public. :) &lt;/p&gt;  &lt;p&gt;Check it out and see what you think. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=71474" width="1" height="1"&gt;</description></item><item><title>MSDN Loband Rocks</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/04/02/msdn-loband-rocks.aspx</link><pubDate>Thu, 02 Apr 2009 14:03:18 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:59251</guid><dc:creator>craig-andera</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=59251</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=59251</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/04/02/msdn-loband-rocks.aspx#comments</comments><description>&lt;p&gt;I &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/06/26/51219.aspx"&gt;mentioned MSDN Loband a few months ago&lt;/a&gt;. Well, &lt;a href="http://blogs.msdn.com/innovation/archive/2009/03/26/launching-low-bandwidth-loband-beta-for-long-haul.aspx"&gt;they’ve updated it&lt;/a&gt;, and the update kicks some serious butt. Check it out &lt;a href="http://msdn.microsoft.com/en-us/library/default(loband).aspx"&gt;here&lt;/a&gt; (the root of the MSDN library) or &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlreader(loband).aspx"&gt;here&lt;/a&gt; (the docs for System.Xml.XmlReader, which show a more typical page). Note the navigation links on the left side, particularly the absence of the tree, and notice how much more streamlined – and therefore faster – the HTML is. I even had a friend tell me that it works pretty well on an iPhone over 3G…in New Zealand! &lt;/p&gt;  &lt;p&gt;Now, once you’ve decided you like this version much better than the old one, click the “Persist low bandwidth view” link in the upper right corner and rejoice in the fact that you will always get this view. &lt;/p&gt;  &lt;p&gt;I can pimp this one with a clear conscience because I had nothing to do with implementing it. Kudos to the team. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=59251" width="1" height="1"&gt;</description></item><item><title>Using Extension Methods to Verify Assumptions</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/03/18/using-extension-methods-to-verify-assumptions.aspx</link><pubDate>Wed, 18 Mar 2009 14:02:36 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:57806</guid><dc:creator>craig-andera</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=57806</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=57806</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/03/18/using-extension-methods-to-verify-assumptions.aspx#comments</comments><description>&lt;p&gt;I was working on something with &lt;a href="http://pluralsight.com/blogs/tewald"&gt;Tim&lt;/a&gt; yesterday, and between us we came up with what I think is a pretty cool trick. We were defining some extension methods on XElement and friends that make it easier to work work XHTML. Something like this: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;doc.Html().Div(“foo”).Div(“bar”).Value&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Which would pull out the text content of a div with a class of “bar” that was a descendant of a div with a class of “foo”. All well and good, but one of the problems we were trying to address is that we didn’t want to proceed if there was no div of class “foo”. A NullReferenceException would be thrown, but we wanted something more specific. So we came up with this: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="courier new"&gt;public static T OrThrow&amp;lt;T&amp;gt;(this T obj, Exception e) {       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (obj == null) {         &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw e;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; return obj;         &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="Segoe UI"&gt;Which in turn allowed us to write this: &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;doc.Html().Div(“foo”).OrThrow(new MyException(“no foo”)).Div(“bar”).Value&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The clever bit is that the OrThrow extension method is generic on the type it’s invoked on, and it returns that type, so you can insert it into a chained expression and you don’t lose any intellisense. And because of type inference, you don’t actually have to specify the type (you don’t have to type OrThrow&amp;lt;IEnumerable&amp;lt;XElement&amp;gt;&amp;gt;), which cleans up the expression a bit. &lt;/p&gt;  &lt;p&gt;This approach is more general than just XHTML, of course. Really, it allows you to insert arbitrary assertions/checks into a series of chained calls using a fairly natural syntax (for some value of “natural”). Nothing you can’t do other ways, but we liked the way this came out enough to want to share it. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=57806" width="1" height="1"&gt;</description></item><item><title>Hard Links in Windows Do Not Update Immediately</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/02/13/hard-links-in-windows-do-not-update-immediately.aspx</link><pubDate>Fri, 13 Feb 2009 14:05:06 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:56712</guid><dc:creator>craig-andera</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=56712</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=56712</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/02/13/hard-links-in-windows-do-not-update-immediately.aspx#comments</comments><description>&lt;p&gt;I was pretty excited when I saw &lt;a href="http://technet.microsoft.com/en-us/library/cc753194.aspx"&gt;mklink&lt;/a&gt; appear. Filesystem links can solve a lot of annoying problems, which is why you see them used all over the place in Unixy systems. Although, like salt, the key is to use them sparingly. &lt;/p&gt;  &lt;p&gt;Which is why I’m so annoyed that the Windows version is pretty much completely useless. Soft links are only recognized in some contexts, but hard links are the real offender. Try this from an elevated command prompt: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;gt; cd C:\temp     &lt;br /&gt;&amp;gt; echo foo &amp;gt; a.txt      &lt;br /&gt;&amp;gt; mklink /h C:\temp\hard-a.txt C:\temp\a.txt      &lt;br /&gt;&amp;gt; more hard-a.txt      &lt;br /&gt;foo&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So far, so good. Now try this: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;gt; echo more &amp;gt;&amp;gt; a.txt     &lt;br /&gt;&amp;gt; more hard-a.txt      &lt;br /&gt;foo      &lt;br /&gt;&amp;gt; more a.txt      &lt;br /&gt;foo      &lt;br /&gt;more      &lt;br /&gt;&amp;gt; more hard-a.txt      &lt;br /&gt;foo      &lt;br /&gt;more&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;WTF? My hard link doesn’t update immediately? That sucks! &lt;/p&gt;  &lt;p&gt;From experimentation, it seems that it only updates after you’ve actually accessed the link once. Since one of the things I’d like to do is hardlink files into my &lt;a href="http://www.getdropbox.com/"&gt;Dropbox&lt;/a&gt; synchronization directory, this is pretty much a non-starter – they’ll never appear to be updated, and therefore will never sync. Unless I visit every file, which is pointless, because if I was going to do that, I could just copy them. Which is what I’m trying to avoid. &lt;/p&gt;  &lt;p&gt;I’m more than willing to believe I’m missing something here, but if so I don’t know what it is. My best guess is that this is a bug in the filesystem caching code (I’m on Windows 2008). &lt;/p&gt;  &lt;p&gt;Days like this make me want to switch full-time to my Ubuntu machine. Also not perfect, but at least the novelty makes me less sensitive to its shortcomings.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=56712" width="1" height="1"&gt;</description></item><item><title>What Is All the Fuss About How You Can Write DSLs in Lisp?</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/01/05/what-is-all-the-fuss-about-how-you-can-write-dsls-in-lisp.aspx</link><pubDate>Mon, 05 Jan 2009 18:30:33 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:56067</guid><dc:creator>craig-andera</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=56067</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=56067</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2009/01/05/what-is-all-the-fuss-about-how-you-can-write-dsls-in-lisp.aspx#comments</comments><description>&lt;p&gt;I saw &lt;a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2230"&gt;Chris’s recent post&lt;/a&gt;, and felt compelled to respond, despite the fact that I’m pretty sure I’m going to regret it. :) &lt;/p&gt;  &lt;p&gt;Here’s what he says, abridged: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;(when (and (&amp;lt; time 20:00)       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (timing-is-right))        &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; (trade (make-shares 100 x)))&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;IMO, that&amp;#39;s not a DSL -- that&amp;#39;s just a set of function calls in an existing language.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The short version of my response to this is: “Yes! Exactly! That’s a feature, not a bug!” On to the longer version.&lt;/p&gt;  &lt;p&gt;This argument, as a question of semantics, is fundamentally doomed to remain unresolved, unless someone can magically provide an exact definition of DSL that a) has no imprecision, and b) everyone agrees with. I’ll just pass on waiting for that to happen, and make my own observation: &lt;/p&gt;  &lt;p&gt;A set of function calls in an existing language is generally preferable to a completely separate language. Particularly if it’s the language that you’re using to write the rest of your system. Sure, there are cases where using a specialized language is the thing to do, but over the last few years I’ve come to have a lot more - what’s the word? respect? fear? caution? – anyway hesitance around introducing additional languages into the development process. It’s not rare to see C#, SQL, XSLT, XPath, NAnt XML, regular expressions, and four or five other grammars floating around in the development lifecycle of a single process, and it’s got a real price. If nothing else, it means that not everyone can work on every part of the system. Throw in the fact that some of those are hard to debug, or have conflicting metaphors, or different performance characteristics, and it adds up. &lt;/p&gt;  &lt;p&gt;So yes, one of the reasons that I’m excited about Clojure is that it’s a Lisp, and as a Lisp it is flexible enough to adapt to the point where I often don’t need a DSL. Or, if you like, where my DSL is also a Lisp. That doesn’t mean “I never want to use a DSL” or “I always want to use Lisp” – all things in moderation. It certainly doesn’t mean “You shouldn’t use M” – how the hell would &lt;strong&gt;I &lt;/strong&gt;know what &lt;strong&gt;you&lt;/strong&gt; need? But for me, I think it’s nice to have a tool that gives me the choice. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=56067" width="1" height="1"&gt;</description></item><item><title>2008 – The Year in Review</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2008/12/31/2008-the-year-in-review.aspx</link><pubDate>Wed, 31 Dec 2008 20:35:09 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:56009</guid><dc:creator>craig-andera</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=56009</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=56009</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2008/12/31/2008-the-year-in-review.aspx#comments</comments><description>&lt;p&gt;&lt;/p&gt;  &lt;p&gt;It’s the end of the year, and although I skipped 2007, it is my habit to take a look back here on matters personal and professional. To whit: &lt;/p&gt;  &lt;p&gt;I blogged a lot less this year. There are a number of reasons for that. The main one is that I’m just not as interested in blogging as once I was. I think that comes with the increasing “inward focus” my career has taken. I just find that more and more, what matters to me is what matters to &lt;strong&gt;me&lt;/strong&gt;, not what matters to everyone else. That’s not a judgement or a boast, just an observation. It’s quite liberating: for example, I can go look at weird languages (see below) and not worry about it too much. :) &lt;/p&gt;  &lt;p&gt;If you really can’t get enough Craig, you can always try me in appetizer size over on &lt;a href="http://twitter.com/craigandera"&gt;my Twitter stream&lt;/a&gt;. I seem better able to post a few dozen characters than a few paragraphs these days. &lt;/p&gt;  &lt;p&gt;Career-wise, 2008 continued the shift I started in 2007 away from lots of small projects towards one big one. If I remember right, by the end of 2006 I’d worked on about seven different open source and proprietary projects, at a max of something like five simultaneously. That was too much, and I was feeling burned out. These days, pretty much all my professional time goes to a contract at Microsoft, where I’m working on the next version of Visual Studio. That has been very interesting for a variety of reasons, not the least of which is that it’s related to the work I’ve done on &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/01/23/50030.aspx"&gt;the MSDN REST Web Service&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Of course, the most significant event of 2008 had nothing to do with web services: it was &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/03/17/50494.aspx"&gt;the birth of our second child&lt;/a&gt;, daughter Susan. She was a cranky newborn, but has since turned into a charming and active baby. Needless to say, having two kids has really changed my life. I’m still coming to terms with giving up my free time – a painful process for me. &lt;/p&gt;  &lt;p&gt;Not that I have &lt;strong&gt;no&lt;/strong&gt; free time, of course. If I had none, I wouldn’t have been able to train for and run a &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/10/26/mcm-2008-or-take-that-engberg.aspx"&gt;marathon&lt;/a&gt;. But maybe I shouldn’t have talked so much smack in that post – &lt;a href="http://rengberg.blogspot.com/2008/11/auckland-marathon-2008.html"&gt;Engberg whupped me good&lt;/a&gt;, and now I have to run another one. I think maybe this time I’ll make qualifying for Boston my stretch goal. Along the way, I’d also like to run a sub-20:00 5K. That’s much more my type of thing – I’m a fast runner, not an endurance runner. &lt;/p&gt;  &lt;p&gt;This year saw my fascination with Lisp continue and even deepen, as is obvious from a &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/05/19/50982.aspx"&gt;variety&lt;/a&gt; &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/07/08/lisp-too-is-mainstream.aspx"&gt;of&lt;/a&gt; &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/10/07/typing-speed-mode-emacs-minor-mode.aspx"&gt;posts&lt;/a&gt; &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/11/19/a-c-repl-in-clojure.aspx"&gt;here&lt;/a&gt;. My latest interest on the parentheses front is &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt;. I made one (sort-of) provocative &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2008/11/19/a-c-repl-in-clojure.aspx"&gt;post&lt;/a&gt; about it, promised to say more, and never did. Well, given how not into blogging I am lately, I’m not sure whether I ever will live up to that promise. So go check it out for yourself: it really is an awesome language. &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;Stu’s book&lt;/a&gt; is a good way to get started. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Here at the cusp of the new year, I don’t really know what 2009 will hold for me. I have a pretty good idea that the Microsoft work will continue for a while, but of course as an independent there’s always an increased level of uncertainty. But I like to think that it’s a rare problem that doesn’t yield an opportunity, so I’m optimistic. &lt;/p&gt;  &lt;p&gt;On the family front, obviously we’re looking forward to watching both kids continue to grow and flourish. 2009 will be Ellen’s last full year of preschool, and of course Susan will likely start walking, talking, and doing all sorts of things. We hope to take family trips to Taiwan, Hong Kong, and Alaska, too. &lt;/p&gt;  &lt;p&gt;On the professional front, I really want to spend more time working with Clojure. I’ve got some ideas for some real apps I can write, since that is, after all, the only true way to learn a language or platform. Plus it gives me a chance to run Ubuntu regularly, which I’ve been enjoying as a departure from the ordinary. (Clojure runs on Windows just fine, BTW.)&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;In the personal realm there are the running goals I mentioned earlier. I also hope to continue to fly &lt;a href="http://en.wikipedia.org/wiki/Falcon_4.0"&gt;Falcon&lt;/a&gt;, and maybe even &lt;a href="http://www.digitalcombatsimulator.com/"&gt;DCS: Black Shark&lt;/a&gt;, which looks really sweet. If I somehow magically find extra time, and the basement finally gets finished, maybe I’ll even start playing bass and/or drums again. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Wishing you all the best in the new year.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=56009" width="1" height="1"&gt;</description></item><item><title>A C# REPL (in Clojure)</title><link>http://www.pluralsight-training.net/community/blogs/craig/archive/2008/11/19/a-c-repl-in-clojure.aspx</link><pubDate>Wed, 19 Nov 2008 19:43:24 GMT</pubDate><guid isPermaLink="false">d057c89c-07b5-4bfb-b52f-d79d1e3ece89:55016</guid><dc:creator>craig-andera</dc:creator><slash:comments>18</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/rsscomments.aspx?PostID=55016</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.pluralsight-training.net/community/blogs/craig/commentapi.aspx?PostID=55016</wfw:comment><comments>http://www.pluralsight-training.net/community/blogs/craig/archive/2008/11/19/a-c-repl-in-clojure.aspx#comments</comments><description>&lt;p&gt;It’s &lt;a href="http://www.pluralsight.com/community/blogs/craig/archive/2007/07/05/47922.aspx"&gt;no secret&lt;/a&gt; that I’ve been interested in Lisp for quite a while. Lately, that has meant &lt;a href="http://clojure.org"&gt;Clojure&lt;/a&gt;. Clojure is a new Lisp dialect that runs on top of the JVM. That means it has the power of Lisp (macros, dynamic typing, etc.) combined with the power of the JVM. The synergy reminds me of an old bumper sticker I saw years ago: “C: combining the speed of assembly with the power of assembly.” We’ve moved on a bit since then, but still. :) &lt;/p&gt;  &lt;p&gt;Anyway, you should check out Clojure. It is easily the most exciting technology I’ve seen in years…probably since I first saw .NET in June of 2000. Even beyond just being a Lisp that actually has vast libraries (one of the main complaints against Lisps of the past) is the fact that there are some truly brilliant features of the language above and beyond what other Lisps sport. &lt;/p&gt;  &lt;p&gt;One of the cool things I’d heard was that Clojure will run on top of &lt;a&gt;IKVM.NET&lt;/a&gt;, which is a .NET implementation of the JVM. I figured that if there were a reasonable story for .NET interop, I’d be able to use Clojure to drive .NET code in a REPL. A REPL is a Read-Eval-Print Loop, which is a fancy way of saying “an interactive programming command line”. It’s like the immediate window in the Visual Studio debugger on steroids, and its absence is one of the increasing number of things that makes C# painful to use as I gain proficiency in more advanced languages. &lt;/p&gt;  &lt;p&gt;Yes, I said it: C# is &lt;strong&gt;not&lt;/strong&gt; an advanced language. If you think it is, then in my opinion you don’t know enough programming languages yet. :)&lt;/p&gt;  &lt;p&gt;Intentionally provocative statements aside, here’s how you do it: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Download and unzip ikvm.net. No installer required. &lt;/li&gt;    &lt;li&gt;Download Clojure. I recommend grabbing the head of &lt;a href="https://sourceforge.net/svn/?group_id=137961"&gt;the Subversion tree&lt;/a&gt; rather than the release that’s on the website. &lt;/li&gt;    &lt;li&gt;Build Clojure by running “ant jar” in the clojure directory. You’ll have to install &lt;a href="http://ant.apache.org"&gt;Ant&lt;/a&gt; to do this if you haven’t already. &lt;/li&gt;    &lt;li&gt;Run “ikvmstub mscorlib.dll” to create mscorlib.jar, which will create the Java wrapper classes for the stuff in mscorlib. &lt;/li&gt;    &lt;li&gt;Launch a Clojure REPL via “ikvm –cp \path\to\clojure.jar;\path\to\mscorlib.jar clojure.lang.Repl”. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now you have a working REPL, in which all the types in mscorlib are available to be driven by Clojure, which is most &lt;strong&gt;definitely&lt;/strong&gt; an advanced language. Here’s a very simple example (the results of running the commands are indicated by =&amp;gt;): &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;(import &amp;#39;(cli.System DateTime))     &lt;br /&gt;=&amp;gt; nil      &lt;br /&gt;      &lt;br /&gt;(new DateTime)      &lt;br /&gt;=&amp;gt; #&amp;lt;DateTime 1/1/0001 12:00:00 AM&amp;gt;      &lt;br /&gt;      &lt;br /&gt;(.get_Now DateTime)      &lt;br /&gt;=&amp;gt; #&amp;lt;DateTime 11/19/2008 2:31:02 PM&amp;gt;      &lt;br /&gt;      &lt;br /&gt;(.ToString (new DateTime) &amp;quot;R&amp;quot;)      &lt;br /&gt;=&amp;gt; &amp;quot;Mon, 01 Jan 0001 00:00:00 GMT&amp;quot;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;You get the idea. &lt;/p&gt;  &lt;p&gt;Of course this is probably only useful as an exploratory tool: if I were writing Clojure for real, I’d write it against the JVM, not against IKVM.NET. But I use the excellent &lt;a href="http://www.sliver.com/dotnet/SnippetCompiler/"&gt;SnippetCompiler&lt;/a&gt; all the time now, but it’s still not the quite same thing as a real REPL, so I’m excited to have a &lt;em&gt;real&lt;/em&gt; REPL available. &lt;/p&gt;  &lt;p&gt;And really, the reason I’m posting this is that I’m hoping it will be a sort of gateway drug for you, and that what this will really do is kick off your interest in Clojure itself. The &lt;a href="http://clojure.org"&gt;website&lt;/a&gt; is a pretty good source of information, but you can also check out Stu Halloway’s &lt;em&gt;Programming Clojure&lt;/em&gt; book. It’s available in Beta form &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;here&lt;/a&gt;. I’ve been tech reviewing it, and even the early beta looks pretty good. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://www.pluralsight-training.net/community/aggbug.aspx?PostID=55016" width="1" height="1"&gt;</description></item></channel></rss>