Thursday, October 11, 2007

I'm geek-famous again!

So if I bribe Craig Shoemaker with $5 every time he posts an episode of Polymorphic Podcast, I get mentioned on the podcast, and even on the blog. Being a Tivo / Podcast evangelist (short version: thou shalt not listen to commercials) it's weird how your sense of "famous" completely changes. In my weird little universe, Craig Shoemaker, Scott Hanselman, and the Java Posse are more famous than Matt Lauer or Hillary Duff. (Oh, excellent! I'm so unplugged that I didn't even get the name right... I was thinking Lindsay Lohan.)

Anywho, so Craig interviewed Miguel Castro again, and among other things, they talked about the whole abstract base class vs. interface decision. I am apparently in a minority here, but I prefer both. In all cases, I pass around the least-specific interface or base class that I need. (Does that parameter need to be List, or do you just need IEnumerable?)

I always think in terms of avoiding option-limiting decisions. So if I'm going to make a base class or interface for something, I want both. I start with an interface and that is the type that I always pass around. I make a base class that implements that interface, and that may even end up being the only thing in the world that ever implements that interface, but I've left myself an out -- the option to change my mind without ripping the guts out of everything.

When I start designing stuff this way, I get a lot of pushback, though. And usually the argument involves the phrase "overengineering". And then my response is usually that it won't feel overengineered if you see it everywhere and it just becomes the knee-jerk implementation that you always use. And it's really not a big deal. When you want to pull up some code into a base class, go ahead and do it. Then just go one step further and pull those signatures up into an interface.

Monday, March 05, 2007

Miguel de Icaza and Pixelmonkey talk Java, Mono, Windows, Linux

Andrew Montalenti, aka Pixelmonkey, started a lively debate with Miguel over at Miguel's comment google group. The thread is here, and Andrew's post on it is here.

Mono is my numero-uno interest as far as open source projects go. And I've always gotten a kick out of Miguel's style. Open source zealots seem often puzzled by Miguel's decision to dance with the devil, as they would see it.

I'm not calling Andrew a zealot, just that he brought up a number of the points that I've seen made with far less tact and forethought by some of the more zealous.

"Why would I choose mono when I have an open source java?" I think that's the wrong question. Most developers don't choose a language and/or platform. They either only know one, or of the several they know, one is dictated to them by their job. So why mono? Because it provides a path to Linux and other platforms where C# was their non-choice.

Along those lines, I'm planning on moving this blog to a mono-powered dasBlog engine on a linux host. Just to see what it's like. And to stop feeling like a *.blogspot.com poser. :)

Sunday, February 25, 2007

Almost there... Orcas better get this right.

It's a pretty old post... but it's a big internet and I haven't found the end yet. :)

David Ebbo explains how to distribute an ascx UserControl without having to distribute the actual ascx file.

And then a litany of comments with people having trouble getting the secret sauce to work just right.

To introduce this on my team, I need to be able to have an "ascx project" that fits into studio as a first-class member of the solution, and that produces an assembly that the other projects can refer to as a project reference.

I need this to have build automation, and a project model that I can let beginner-intermediate developers go to town on without having to understand all the underlying twiddling. It's just not quite there. So we're still doing "reference this assembly and copy these ascx files into your /controls directory". That blows, but the beginners can handle it.

There must be a universe that I am not exposed to where you would be allowed and would actually want to edit a code-behind, aspx, or ascx file on a live, production server. I can only imagine this scenario in a small business fiddling with their own little website. Those people can have the ascx UserControl. For bigger business development, we really just need and want resource-based full design-time support for a Web.Control.

Monday, February 12, 2007

Apache / IIS Flamebait

There's a ZDNet blog posting by Richard Stiennon that shows two call graphs comparing the system calls that a Linux / Apache server makes to serve up a simple page versus the equivalent on Windows / IIS.

Surprise, Apache makes fewer system calls. The argument is that this makes it easier to secure a Linux / Apache implementation. That might be true. My experience is that ignorant administration is an orders-of-magnitude greater threat than the inherent limitations of either platform.

While it's sort of an interesting look... I've got a few big problems with the post:
a) The graphs are unreadable, and therefore FUD. I'm sure it was just a bandwidth issue not to have a version of the graph with enough resolution to actually read the system calls being made. However, just showing two pictures with lots of lines and basing your conclusion on the fact that one picture has way more lines in it is a pretty shoddy argument. I'll give Stiennon the benefit of the doubt that he both analyzed the original graphs, and is qualified to understand what they say. If that's not the case, then shame on you for stirring up a pointless religious debate.
b) Microsoft chose this implementation on purpose. You can make an intellectually honest argument that keeping most processing in user-space is inherently more secure, but that's just a (sensible) opinion, and not gospel fact. IIS7 moved most low-level processing into http.sys as a conscious decision in support of performance and stability. ASP.Net can blow chunks and IIS will restart it. IIS can blow chunks and http.sys will queue up the requests until the OS restarts IIS. You would be right in assuming that this puts the entire OS at the mercy of any holes in http.sys. But in closed-source land that means that http.sys is going to be something that they pay extra-special attention to, and also insulate from the feature-itis that ASP.Net (and thus IIS) are prone to.


Alright, that's enough defending Microsoft (like they need my help). In Linux-land, there's a fanatical devotion to moving as much code as possible out of kernel-space and into user-mode. Security is one of the concerns, but it also keeps the kernel simple and light (well, simple as far as kernels go). This is a design decision that gets repeated in lots of Linux projects, but it comes at a price, like all design decisions do. Until the code can cross the magic line where really almost everything is happening in user-mode, there's a not-irrelevant performance cost from the marshaling between memory spaces. Apache already crossed that line... it's a good decision. And really, under the open source model where defense-in-depth is even more important, it's usually a good decision for most projects.

Of course, this is only a "decision" you get to make if you're hacking straight at the API. And if you're one of those people... you knew all this already. :)

Oh, and thanks to Arno for pointing me at the post.

Thursday, February 08, 2007

Yet weirder nuances with C# interfaces

Brennan has a post about the differences between implicitly and explicitly implementing an interface in C#. He's got screenshots and better code formatting than I've figured out how to do yet, so really just go look there. But in brief, if you have an interface like this:

 public interface IDog  
 {  
     void Bark();  
     void Run();  
     void Catch();  
 }
You have two ways you can implement it. Implicitly, which is what I'm used to seeing:

 public class Bulldog : IDog  
 {  
#region Implicit implementation of IDog
 
     // Implicit 
     public void Bark()  
     {  
         throw new NotImplementedException();  
     }  
 
     public void Run()  
     {  
         throw new NotImplementedException();  
     }  
 
     public void Catch()  
     {  
         throw new NotImplementedException();  
     }  
 
#endregion  
 } 
Or explicitly like this:

 public class Terrier : IDog  
 {  
#region Explicit implementation of IDog
 
     void IDog.Bark()  
     {  
         throw new NotImplementedException();  
     }  
 
     void IDog.Run()  
     {  
         throw new NotImplementedException();  
     }  
 
     void IDog.Catch()  
     {  
         throw new NotImplementedException();  
     }  
 
#endregion  
 }  


They both accomplish the same thing (sort of, here come the nuances). Brennan pointed out that the explicit implementation (Terrier) will not show intellisense for variables of type Terrier. But you can still pass it around to methods expecting an IDog. Bulldog behaves more like you would expect -- intellisense shows all the methods and you can still pass it anywhere you could pass an IDog.

So lately I've been playing with Reflector more than is healthy for a person. It prompted me to go out and read the CIL specification. (Well, I'm almost done with Partition I at any rate. Yes, I've become that kind of geek.)

So I compiled this little sample and dropped it into Reflector. Interesting. The "normal" implicit implementation in Bulldog.Bark:
.method public hidebysig newslot virtual final instance void Bark() cil managed
{
      .
maxstack 8
      L_0000: nop 
      L_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
      L_0006: throw 
}
And the explicit implementation:
.method private hidebysig newslot virtual final instance void com.navelplace.IDog.Bark() cil managed
{
      .override com.navelplace.IDog::Bark
      .
maxstack 8
      L_0000: nop 
      L_0001: newobj instance void [mscorlib]System.NotImplementedException::.ctor()
      L_0006: throw 
}
So everything after .maxstack 8 is identical, as you'd expect. That nop puzzles me. That's a CIL no-op (do nothing). I'm guessing it has to do with byte alignment. If I'm wrong I'd love somebody to explain that to me.

Anywho... before you wig out about looking at IL... what are the differences? The explicit version declares itself as a .override, and not the implicit version. They're both "virtual final instance void". I'll break that down: virtual and final have the same meaning as they do in C#, virtual because all methods from an interface are virtual, final meaning you could not override Bark() in a subclass of Bulldog or Terrier. CIL is a lot more statically-oriented, so "instance" means "not static". And void meaning, umm, void.

hidebysig and newslot are pretty obscure -- they have to do with overloading and overriding. I believe all .method's coming out of C# will be marked hidebysig, or at least I haven't stumbled across anything marked hidebyname yet. It means that foo() will hide base.foo() but not base.foo(int). With hidebyname, foo() would hide anything from base named foo, regardless of signature. Although "signature" includes more things than we're used to in C#.
newslot comes into play for overriding. Implementing an interface requires a new slot on the type, but overriding a virtual method on a class would not specify newslot.

But now the real difference, and the weird part. The explicit implementation is marked private, while the implicit implementation is marked public. This explains why the explicit implementation doesn't show up in intellisense -- it's a private member of the concrete class. But it's not just intellisense that thinks so. new Terrier().Bark() is a compile-time error. This would seem to violate the inheritance rules from the spec, since everything in an interface is public:
When a derived type overrides a virtual method, it can specify a new accessibility for the virtual method, but the accessibility in the derived class shall permit at least as much access as the access granted to the method it is overriding.
There would seem to be an exception made for interfaces. And notice the method that specifically says ".override" is the one apparently violating the accessibility rule. Haven't stumbled across the part of the spec that explains the reasoning. It doesn't violate the substitution principle, since anything expecting an IDog would get an implicit cast and the explicit implementations would become visible again. But it still seems weird.

Friday, February 02, 2007

Concurrency and C-Omega

The old name was Polyphonic C#. Both sound cool, but C-Omega is harder to type, but looks way cooler when you use the real symbol: Cw (that made blogger mad putting that in, and Firefox remains unimpressed with my font tag, so follow the link or read this in IE to see the symbol). Apparently it is not CW which would have looked cooler.
Anyway, I totally stumbled across it while trolling the Microsoft Research site. Concurrency stuff is becoming a lot more interesting to me -- from the geeky theory level just because of the increasing abundance of multi-core processors, but also because I'm running into these same issues at work. Cw dovetails a bunch of LINQ stuff into it too, but the concurrency stuff is what has me excited.
We implemented a pretty naive attempt at SOA here, and ran into the classic performance bottleneck. The extra network hop involved in talking to a web service caused all the same old kinds of performance issues that we used to run into with DCOM, just in new ways. Consuming too many discreet services means you're making too many network roundtrips, so the server spends most of its time waiting around for responses from other servers. And for us, it does all that waiting in a serial fashion. Ouch.
This is of course why all of .Net's auto-generated web service proxies have asynchronous equivalents to every call, but synchronizing all the callbacks in a way that isn't both confusing and brittle is pretty hard. And then there's the whole issue of defending your code from slash-and-burn programmers that just don't get it.

But check out their simple example (I made it simpler):

1 public class Buffer

2 {

3 public async Put(string s);

4

5 public string Get() & Put(string s)

6 {

7 return s;

8 }

9 }




The idea is that any call to Put just hands off the parameter and returns immediately (async implies a void return type). A call to Get is synchronous like a regular method call, but has to be paired with a call to Put. So if Put had already been called, the value s is waiting to be returned. If Put has not been called, the call to Get blocks until some other thread calls Put. Multiple calls to Put will stack up waiting to be consumed.
This example hurt my brain to look at the first time:



1 public class ReaderWriter

2 {

3 private async idle();

4 private async s(int n);

5

6 /// <summary>

7 /// We start out by dropping message to idle()

8 /// </summary>

9 public ReaderWriter()

10 {

11 //

12 idle();

13 }

14

15 /// <summary>

16 /// A call to Exclusive() will block unless or until

17 /// there is an idle() message dropped. It consumes

18 /// the idle() message, so another call to Exclusive()

19 /// will have to wait for someone else to call idle().

20 /// </summary>

21 public void Exclusive() & idle()

22 {

23 //We don't need to actually do anything.

24 //Consuming the idle() message is enough.

25 }

26

27 public void ReleaseExclusive()

28 {

29 //Makes us idle again.

30 idle();

31 }

32

33 /// <summary>

34 /// A call to Shared will block until there is a matching

35 /// message of either idle() or s(int). You only have

36 /// to match on one of the asynchronous methods. So a

37 /// call to Shared() will either match idle() or s(int),

38 /// but not both. (The & syntax makes that a little

39 /// confusing. You might think Shared would wait for

40 /// both idle and s(int).)

41 /// </summary>

42 public void Shared() & idle()

43 {

44 /*

45 * If we were idle, when somebody called Shared,

46 * then we go here, and drop a message that there

47 * is one reader.

48 */

49 s(1);

50 }

51 & s(int n)

52 {

53 /*

54 * If we were already in Shared mode and somebody

55 * called Shared again, then just bump up the counter.

56 */

57 s(n+1);

58 }

59

60 /// <summary>

61 /// This just needs to make the decision to either

62 /// decrement the shared counter or call idle. Either

63 /// way, it will drop another asynchronous message.

64 /// And if you follow the logic, ReleaseShared() will

65 /// always find that there is a waiting s(int) message.

66 /// </summary>

67 public void ReleaseShared() & s(int n)

68 {

69 if (n == 1)

70 idle();

71 else

72 s(n - 1);

73 }

74 }



It's a lot less painful once you grasp on to the fact that an asynchronous call is just dropping off a message. (The contents of the message being the parameters.) The & token groups together method signatures (you can group two or more, but only one can be synchronous). Together the grouped signatures form a chord, and the body will execute when a synchronous and an asynchronous call find a match. I found the concept got simpler as I started thinking about it in a similar way to signature matching for overloaded methods.
It is a little unsettling to see that state is being stored with no variables for you to look at. But there's at least a baseline here for debugging tools to latch onto that would making debugging a multi-threaded app a lot less painful.
And yah, this stuff is hard to wrap your brain around, but concurrency is hard to wrap your brain around. This is a big step into abstracting away the non-essentials.

There are some other equally-impressive things being baked into Cw, go check it out.

Thursday, January 25, 2007

Good intro to MSBuild

Brennan wrote a nice little tutorial on MSBuild over on his blog. It'll be especially useful to you if you've never used ant or Nant before. There's also some good quick starts over at the Channel 9 wiki.

I have a fetish for making build scripts. Considering how plebeian the task is, I enjoy it way more than I ought to. I ran into Brennan's post hunting around for good stuff on Foundation Server's build stuff.

Foundation Server looks awesome. I don't quite understand why Microsoft is trying to make money off of it, but they're being quite clever about it. You can download a 90 day trial from here. And then you're just a checkbook away from turning your trial version into a production version.

We are likely falling for it. :)

Strange things coming from Microsoft these days. MSBuild (and Studio's total integration with MSBuild) is just a slam dunk, but very un-Microsoft of them. And then trying to make money off of VSTS and Foundation Server (you can't download it as part of the not-so-universal-anymore MSDN subscription). I would think the mindshare they'd own by giving it away would be worth more dollars than they're going to get for licensing. Or maybe they're just so confident in their monopoly these days that they figure they might as well start charging for more stuff. Hmm...

Friday, January 12, 2007

Review: Working Effectively with Legacy Code

I originally posted this review to Amazon. Thought I'd repeat it here. The author, Michael Feathers, is from Object Mentor. Check out their blogs, there's a lot of interesting noise being made over there. (They recently moved the blog from their old site, but the new site has a link to the old stuff.)

Here's a link directly to the book where you can read other reviews. Oh, and I didn't mention it originally in my review, but another big plus to this book is that it's language-agnostic, which is a big deal when legacy code is your issue.

Anywho, here's the review. The punchline is: READ THIS BOOK! It's really excellent.

A more accurate title for this book would have been "Unit Testing and Refactoring is How To Work Effectively with Legacy Code" The book operates entirely from that premise, and only spends a little time trying to sell you on the concept. If you're still struggling with that debate, this book may rub you the wrong way. However, I found it to be intensely practical and found the author repeatedly speaking about scenarios that I run into quite often.

I would describe myself as someone who finds the whole fascination with design patterns a little optimistic and certainly hype-laden. Useful to be familiar with, but nothing to preach about. Feathers' treatment of patterns is exactly what they should be, however -- from the trenches, and goal-oriented. He describes the patterns he uses with the very immediate goal of how they will help you "get code under test" as he would put it, and slowly unwind the spaghetti we all run into.

Although the world didn't need yet another book about unit testing, refactoring, and patterns, there are few books that offer practical advice for the ugly side of software development. To get the most out of this book, you'll need to have slightly better than intermediate experience with object-oriented development, but this is not a hypothetical-scenario type book targeted at gurus. And most importantly, it acknowledges and embraces the fact that we have all inherited reams of code that has either abused and ignored OO principles, or wasn't even OO to begin with. It is quite readable and accessible, and doesn't overwhelm. I found a lot of valuable techniques in here that I have not found anywhere else.

I highly recommend this book, and I'm going to be shoving it down my coworkers' throats. :)

Sunday, January 07, 2007

Review: Saving Money and Time With Virtual Server (O'Reilly Shortcuts)

If you haven't heard of O'Reilly's Shortcuts series, they are a fairly large collection of downloadable PDF articles, usually between 25-100 pages long, and priced between 6-10 dollars.  Or if you have a Safari account, they're all included with your subscription.  Well, that's enough of sounding like a commercial for O'Reilly.  But they did send me a free copy to review (thanks Marsee!) so I thought I'd at least plug them a little.  And considering that I'm about to give a lukewarm review of the article itself...

This is the first Shortcut I've read, and I hope it's not indicative of the series as a whole.  While the quality of the article was quite good and the information useful, it was definitely a commercial for Microsoft's Virtual Server 2005. Granted, the article is clearly targetted as an introduction to Virtual Server, but any discussion of virtualization that does not also mention VMWare is clearly suspect. 

The author, Chris Sanders, is not a paid shill for Microsoft, so it's a shame that his article comes across as just another piece of evangelism.  Do check out his blog, though, he has quite a bit of useful tips and info for an IT admin, but that's just not my bag.  I'm the guy always making the IT guys nervous.  :)

In spite of my complaints, the article is a good introduction to Virtual Server to someone who has never used it before, and is even new to the idea of virtualization.  It has a quick introduction to the concept of virtualization, and then a basic how-to on setting up your first virtual machine.  The instructions were clear and easy to follow, and I had my little sample machine up and running with little trouble.  So good job there.

Not being an IT guy, I spent more time paying attention to how I could use it to run multiple development platforms, and didn't pay very close attention to the sections about security or consolidation (running multiple VM's on one beefy server).  But if you are an IT guy, I imagine you'll want to pay attention to those sections. 

I'm still not up to speed enough on the ins and outs of either Virtual Server or VMWare, but they are very soon going to end my adventures with Norton Ghost or dual booting.  Virtualization is one of the New Cool Things getting a lot of attention, and we're moving aggressively on it at my work.  If you're a newbie in this area like I am, you should put your ear to the ground.

But would I shell out $7.99 for this article?  Probably not.  Mostly because I'm a Cheap Bastard, but also because if I'm going to pay for someone's knowledge, I want an unbiased opinion.  This article isn't trying to be a reference source for Virtual Server.  So if I'm just being introduced to a product, I'd be really interested in hearing its relative merits to its obvious competitor.  And there is literally not one single mention of VMWare in the whole article.

If this were an article posted out on some IT forum, I would certainly point people to it and recommend they read it.  It's got good stuff.  But then I would recommend they google the comparisons.  If you've already got a Safari account, or if you're spending someone else's money, do download the article.  Amazon and O'Reilly do get lots of my money for technical books, but if I had just spent 8 bucks for this, I'd feel a little cheated.

Friday, January 05, 2007

Horrifying thing I just overheard at work.

I'm being arrogant as all hell... but I'm posting it anyway.

Dev1: "This is how they do multiple inheritance in C#. Interfaces."
Dev2: "Aaah."

Apparently Dev1 and Dev2 are C++ guys. And only C++ guys.

I have a rant in me about the importance of being multi-language and multi-platform literate. And this is perfect grist for that mill, but it more makes me think about the social and non-technical difficulties of coming up with a good design when you're part of a team that isn't really at the level to understand, implement, or take advantage of that design.

And I'm not talking about overly-elaborate designs that turn into frameworks that turn into solutions looking for a problem. I can explain dependency injection to someone, for example, but if they don't get it and understand why and when it is a good idea, then I'm pretty tied down in the kind of design I can put into our project.

Hrm...