Monday, May 31, 2004

FwSync 1.0 - Code Name Perserverance

It was a busy weekend - my wife was accepted to the Wharton Executive MBA program, and she started class yesterday. We drove up and got her settled in to her new, incredibly busy life. While she was listening to introductory speeches, I got some time to spend with my computer. I'd recently run into some issues with my offline FlexWiki editing tools, and finally needed the ability to merge offline and online changes. About eight hours of effort later, I've completed it. With this feature out of the way, I feel like I can finally slap a 1.0 label on FwSync. Woohoo!


This is really a milestone for me. Like many people in my line of work, I have a fairly short attention span - I tend to focus on something intently for a while, figure out about 80% of it, and then move on to the next thing. That's an asset when you're teaching a class or researching a new technology, but I've long been aware that “real” developers don't have the luxury of moving on once the interesting bits are finished. So I've been looking at FwSync and FlexWikiPad as ways to see if I can follow a project all the way through to the end.


I still have a fair way to go in my journey. If nothing else, I'd like to ship version 1.0 of FlexWikiPad as well. And beyond that, I want to spend some time supporting the products, because I think you learn a lot by hearing how the choices you make screw other people over. You learn even more when you then have to fix them. :)

Wednesday, May 26, 2004

PluralSight Online

I'm happy to see that Keith, Fritz, and Aaron have gotten the PluralSight website properly launched. I'm particularly pleased that Keith, Fritz, and Mike Woodring all now have proper blogs. These guys were some of the sharpest dudes at DevelopMentor...seriously.

Processing Command Line Wildcards

I can use a keyboard so much faster than a mouse that I just hate it when an app makes me click things instead of letting me type in shortcuts. So it's no surprise that I love working at the command line. One thing that distinguishes a good command line application from a bad one is whether or not it lets you use wildcards. For example, being able to do:


  fooutil blah.txt *.cs abc????.xml


is a good thing - it lets me say, “Run fooutil on the file blah.txt, any file with a .cs extension, and files that have a name that start with abc, are seven characters long, and have an xml extension” all in one fell swoop.


As it turns out, getting this behavior in your app is pretty easy. Here's the code:


public static int Main(string[] args) {
  foreach (string filespec in args) {
    string specdir = Path.GetDirectoryName(filespec);
    string specpart = Path.GetFileName(filespec);

    // GetFiles will vomit on an empty specdir
    if (specdir.Length == 0) {
      specdir = Environment.CurrentDirectory;
    }
    foreach (string file in Directory.GetFiles(specdir, specpart)) {
      string path = Path.Combine(specdir, file);
      // Your code to process the file identified by path goes here
    }
  }
}


The key magic here is Directory.GetFiles, which will return you a string array of file names that match a given directory a pattern. Check out the docs for Directory.GetFiles to get the full scoop on what patterns are legal. Also note the use of Path.Combine - never combine path elements with +.

Tuesday, May 25, 2004

XPQ

Since Eric mentioned me, I feel all this pressure to post something cool and C#-related. OK, here's a neat little number:


public class App {
  const string USAGE = @"Usage: xpq <xpath> <input>"; 
  public static void Main(string[] args) {
   
if (args.Length != 2) {
     
Console.WriteLine(USAGE);
     
return;
   
}

   
XPathDocument doc = new XPathDocument(args[1]);
   
XPathNavigator nav = doc.CreateNavigator();

   
object o = nav.Evaluate(args[0]);

   
if (o is XPathNodeIterator) {
     
XPathNodeIterator iter = o as XPathNodeIterator;
     
while (iter.MoveNext()) {
       
Console.WriteLine(iter.Current.Value); 
      
}
   
}
   
else {
     
Console.WriteLine(o);
   
}
  }
}


What does it do? It lets you run XPath queries against files from the command line. I call it XPQ for XPath Query. So, for example, I can print the number of “foo” nodes in a doc by running:


   xpq count(//foo) doc.xml


Or I can print the value of every “bar” attribute in a document by running:


  xpq //*/@bar doc.xml


The way it works is by taking advantage of the XPathNavigator.Evaluate method, which runs the supplied XPath expression and returns an object. The type of the object you get back depends on the expression you provide. If the XPath expression evaluates to a number, you get a double. If it evaluates to a string, you get a string. And if it evaluates to a identify more than one node in the document, you get an XPathNodeIterator.


I'm sure there are 999 tools out there that do all this and more, but I love that the framework lets you do so much with just a few lines of code. And this one covers about 90% of the cases where I just need to know something quick about an XML document.

Monday, May 24, 2004

I'd Like to Thank the Academy

It's an honor just to be nominated, of course.  I want to thank my parents, my director, and my dog Jimmy.

Wednesday, May 19, 2004

More Direct3D Afrikaans Translations

The third and fourth installments in the Direct3D tutorial series, are now available in Afrikaans. Thanks to Ernst Kuschke.

Tuesday, May 18, 2004

Moore of the Beginning of the End


I've been saying for years that Moore's Law will end in the next two decades. The typical response I get to this assertion is, “Oh, they'll just move on to the next thing...quantuum computing, multi-core processors, optical, whatever.“ This is basically an assertion of faith against an argument of physics - a typically human response. Which is why I'm pretty sure the computing industry is going to get totally blindsided when suddenly things stop getting exponentially smaller/faster/cheaper. What's Microsoft's business model when you have to buy a computer that's five times as expensive as the one you own now in order to support the features they're working on?


The key, of course, is to figure out a way to profit by announcing something that solves the problems while everyone else reels around in the smoke. My current best guess is “compiler technology,“ but that's another post.


It seems that Intel may already be experiencing an early little speed bump on the way to the giant brick wall.



The warning came first from a group of hobbyists that tests the speeds of computer chips. This year, the group discovered that Intel's newest microprocessor was running slower and hotter than its predecessor. What they had stumbled upon was a major threat to Intel's longstanding approach to dominating the semiconductor industry - relentlessly raising the clock speed of its chips. Then two weeks ago, Intel, the world's largest chip maker, publicly acknowledged that it had hit a "thermal wall" on its microprocessor line.


Sunday, May 16, 2004

FlexWikiPad 0.90

Yesterday I sat down and finally polished off supporting non-ASCII characters in FlexWikiPad. I have to say, I'm pretty happy with how the tool is coming along. Although it still has a few missing features, the bugs that are left are all ones I can ignore, and it's never yet lost any data for me. I've been using it pretty much every day for a few months now. It has completely replaced my use of OneNote, which I also really liked. I'm taking that as a sign that I must be on the right track.


Anyway, since I got the code to a good point, I went ahead and released version 0.90. Now I need to figure out what to work on next. One thing I miss is full-featured Find and Replace functionality - I definitely will be doing that soon, since I often find myself wanting it. But I can get the same effect with a command-line search of the underlying files, so I'm wondering if maybe I should add the other thing I really want to get in: configurability. Specifically, I'd like to move all the formatting to an XML config file so people can change fonts and regular expressions without having to wait for me to release a new version.


If you're interested in helping me out, now is the time. Go grab the tool, try it out, and make a feature suggestion here, here, or here in the comments.

Thursday, May 13, 2004

Yet More Direct3D Translations

Uploaded a bunch of stuff this morning:

  • Portuguese translations of my Direct3D slides. Available here. Thanks to Alexandre Lobao, author of  .NET Game Programming with DirectX 9.0.
  • The fifth and sixth installments in the Direct3D tutorial series, en Francais. Thanks to Kershin.
  • The first and second installments in the Direct3D tutorial series, translated into Afrikaans. Thanks to Ernst Kuschke.
  • Also, I noticed that DotNetPro now has a place to read the German articles I wrote (well, I wrote them in English and my friend Marcus translated them) that doesn't require registration.

If you're interested in doing a translation of anything on this site, please contact me. I'd have no problem with you hosting it on your page as long as I get to post it here too. Oh, and if you see a mistake in any of the translations, let me know on that one, too: of all the stuff I posted today, I can only actually read a tiny bit of the French one. :)

Beware File.OpenWrite

I was working on putting some finishing touches on FwDocGen yesterday, when I came across a subtle bug that took the help of Mike Woodring to figure out. FwDocGen is a fairly straightforward wrapper around an XSLT that takes in XML documentation and produces FlexWiki pages that document the classes, namespaces, etc. in your project. The idea is to produce the equivalent of MSDN docs for your class library, but on a wiki instead.


(Side note: FwDocGen is now released in a fairly usable form.)


Anyway, what I was seeing was that the last part of the documentation for a class would show up twice. That is, the docs would list all the methods, properties, etc., and then part of whatever came last would show up again: a little documentation fragment that was completely out of place.


Naturally my first instinct was that I had screwed up the transform and thrown in one too many <xsl:apply-templates /> calls. But everything checked out there, so I was stumped. I saw Mike was online, and since he's preternaturally smart, I pinged him. Within a few minutes, he had said the magic phrase that turned the light bulb on in my head. “Looks like a truncation problem,” he said. And it was.


The fundamental issue was that I was doing something like the following:


FileStream fs = File.OpenWrite(path);


which is a very handy convenience method for opening a file for write access. Unfortunately, as it says right in the docs, this is the equivalent of saying


FileStream fs = FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);


which is most definitely not the same thing. Why not? Because OpenOrCreate, when accessing an existing file, does not nuke out the contents that are already there. So if you have a file whose contents are


ABCDEFG


and you do a File.OpenWrite() on it, and then write “123” into it, you get


123DEFG


instead of just “123”. In other words, the file is not truncated on open. Which is probably not what you want. It certainly explained my problem, though. I'd changed the transform so some of the files were shorter, and when I re-ran the program, it wrote the shorter version over the top of the longer version, leaving the extra garbage at the end.


The fix was dead easy. I just swapped out File.OpenWrite for


FileStream fs = FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);


which works perfectly well. Somewhat confusingly (although it's well-documented), Create still works if the file is already there. But it truncates the file. Thanks Mike!

Wednesday, May 12, 2004

Get An Accountant

My wife and I run our own business. Occasionally, people that are looking to do the same thing will ask me for advice on what to do. My advice is always the same: talk to an accountant.


See, it's not that accountants are particularly necessary for doing things like keeping track of who paid you when: we actually do that ourselves. It's that the tax laws in this country are so unbelievably complex that you can't be an expert in your field and tax law too. Why are the tax laws so important? Because of two things:



  1. Picking the type of company to form (S Corporation, LLC, sole proprietorship, etc.) has a major impact on your tax liability.

  2. Figuring out what is an allowable deductible expense is hard. Getting it right can mean thousands of dollars a year in your pocket and/or your retirement accounts. Getting it wrong can mean an audit at best and jail time at worst.

An accountant is going to cost you, but they should always save you way, way more than you pay them. Talk to a few of them, though. One thing we found out was that there are as many approaches as there are accountants. This is something that is brought home to me by the fact that every time I ask our accountant what I think is a straightforward money question, he says, “Welllll...it depends,” and then goes on to explain what it depends on.


Which is exactly the same answer I give to software architecture questions. :)

Thursday, May 6, 2004

Nifty Autocomplete Tip

Keith Brown sent out this interesting tip today:



You can delete autocomplete items in Office and IE by holding the mouse down on the item that's getting in the way while the autocomplete listbox is down (you can force it to drop down in an empty field by clicking that field a couple times if necessary) and pressing DEL.


I'm loving this feature - I just used it to delete some old addresses from my TO: autocomplete in Outlook.


Obviously, this will come in handy.

Analogies Are Like Busses

I noticed that Brad posted a link to Joel's foreword of Mike's new book. Specifically, he called out this paragraph:



There’s something weird about software development, some mystical quality, that makes all kinds of people think they know how to do it. I’ve worked at dotcom-type companies full of liberal arts majors with no software experience or training who nevertheless were convinced that they knew how to manage software teams and design user interfaces. This is weird, because nobody thinks they know how to remove a burst appendix, or rebuild a car engine, unless they actually know how to do it, but for some reason there are all these people floating around who think they know everything there is to know about software development.


Is this really true? I've said before, people love compare our industry to others and say, “We should be more like that.” But I'd argue that - human nature being a constant - it's more likely that we simply don't see the manifestations of stupidity in other professions. For example: how many of a doctor's patients are people that decided to stop taking their antibiotics because they felt better? Or how many mechanics fix cars that never should even have been driven to the shop? Ask a doctor/mechanic, and you'll probably hear tales of people that never should be allowed to touch a human body/automobile.


It's true that few people will try to remove their own appendix. But few developers will try to write their own TCP/IP stack. Which is to say, since analogies are inherently subjective, you can prove anything you want with them. Show me a quantitatve measure of task complexity, then talk about how people approach software tasks differently...because I'm not convinced that they do.


After all, no matter what field you're in, half of your collegues will be dumber than average. ;)

Wednesday, May 5, 2004

Abstractions Really *Are* Leaky

I was just reading an interesting article over at the Scientific American website about complexity and quantum mechanics, and an analogy hit me between the eyes so hard I had to laugh.


Anyway, I'm not much of a physicist, but here's what I understood: superconductivity is an example of a quantum mechanical effect that exists on a macro scale. This is odd, because quantum effects generally only exist at a very small scale - by the time you get to bigger objects, quantum weirdness goes away. My (admittedly weak) understanding is that this is because the interactions between the tiny pieces sort of “average out” the quantum “smearing”. So, for example, you don't have to worry that I might teleport across the room while you're talking to me, the way you might if we were both electrons.


On to the analogy. When I read that superconductivity was a macro-scale quantum effect, the thought that spang immediately to mind was “Wow, talk about a leaky abstraction!” In other words, here's yet another example of the fact that you can never hide all the details of what's going on. You always have to be able to strip back the model to get to a lower level...living in blissful ignorance is only a part-time luxury.

Monday, May 3, 2004

We Now Return You To Your Regularly Scheduled Programming

The server this blog lives on had a bit of a hissy fit over the weekend. So, sorry if you came looking for something and couldn't get to it - everything's back on line now.