Tuesday, March 09, 2010

Pure WPF

This was prompted by a discussion on Padnug.

"Pure" is not a word I'd use often with regard to WPF. WPF rethinks many things, and not all of them have come into flower yet. Which is an optimist's way of saying, parts are missing today. To me, some of its big-picture rethinking has been biased toward massive empowerment of the developer, at the expense of off-the-shelf functionality. DIY over prefab. (I'm thinking especially of its debut without a DataGrid. In WPF you can write dazzling things, and when you know what you're doing the dazzle is just as easy or easier than WinForms... but you have to write them. The OOBE excitement is pretty sparse.) It's also been slow to build a comfort level in the dev community. To some, MVVM goes hand in hand with WPF, but I see senior developers still wary of MVVM or puzzled by it, and there are big areas where reasonable people disagree what it requires. [For example, the eventing between View and VM can be done in several ways, including at least two distinct patterns--classic .NET events vs routed events. Reactive.net (on its way to WPF) reworks the async pattern. Some people abstract the views in ways that the VM can manipulate; others are horrified by that. One's ideas about that are sometimes influence by whether you're using DI or not. In short, there's a fair amount of flux.] Junior devs, or old guard devs who aren't especially current, are mystified if not scared. Plus, of the total .NET workforce, there's more people on the web side than the desktop, I think--so lots of people who've stayed on the cutting edge of .NET as much as they've needed to, haven't touched WPF yet.

That's a long way of saying that to my mind, WPF feels too diffuse to be pure.

Tuesday, March 02, 2010

ViewModel rationale

Nikil Kothari had a great couple posts this week, notably this one.

He makes a good case for ViewModel, especially the idea that it's the next step up from codebehind. But there's more to be said. First off, UI is expensive, and not just mildly--it's basically as expensive as a software feature can be without being prohibitive (e.g., voice recognition). In my experience, whether on WinForms, HTML, Ajaxy and CSSed HTML, WPF, WebForms, or Silverlight--even my little tastes of Ruby on Rails--UI just takes developers longer to get a feature done-done. Often 4 or 5 times longer. There are some inherent and perhaps intractable reasons for this: UI is often what product owners feel most acutely, so there's lots of micromanaging, fiddling, and rework; the human eye is trained by evolution to absorb visual information quickly, with an especial emphasis on inconsistencies, so the tolerance for error is different; and everything in a UI tends to be intricately and sensitively connected to its neighbors, in time and in space, resulting in the wonderfully correct and illustrative metaphor of "the ripple effect".

There are also some regrettable reasons why UI is so hard: most notably that even the best tools, theories, and mindshare are still in their infancy. Many concepts that are getting some traction these days ("MVVM", "UX design") had effectively zero presence in commercial software even 15 years ago.

Since UI is expensive, a major trend among MV* patterns (MVC, MVP, MVVM, and other flavors of SupervisingController) is to make the UI dev burden as light as possible, and to provide more and framework/scaffolding that makes much of the plumbing just happen. The eventing and data binding in WPF and SL are important steps forward; so are codegen and reflection, which assist metaprogramming.

It's significant that ViewModel mindshare didn't really take off until the codebehind pattern matured a bit and there was framework support (primarily .NET) to knit the view's document-orientedness to its logic and state, as coded in... um, well, code.

I think the rise of CSS also played a crucial role, convincing millions of developers of the wisdom of separating visual markup from the containment tree--preferably in a reusable way that makes application-wide look-and-feel not only achievable but flexible and maintainable. CSS wasn't a step toward MVVM, but it cleared away some of the underbrush.

JavaScript is another factor that might have scared some devs straight, spending too much time repairing "clever" code integrated into a page.

So, some more drivers toward MVVM:
* stateless view --> one set of concerns (represention of state) out of the expensive UI
* passive view --> another set of concerns (choosing the next state, and transitioning to it) out of the expensive UI
* styles --> a third set of expensive concerns mitigated, at least partially. And MVVM handles most major tasks well, EXCEPT for styles, so it needed that task taken off the board
* scar tissue from browser scripting
* declarative code vs imperative/programmatic code, coexisting harmoniously via codebehind
* "conventions", base classes, and other forms of code leveraging/reuse that allow recurring problems to have recurring solutions, with minimal additional developer effort

Wednesday, January 27, 2010

Raising .NET events

This is a recycling of something I posted to Fabulous Adventures in Coding, in conversation with Pavel Minaev. Necessary background: the official .NET pattern for standard events (as opposed to, say, WPF routed events) recommends invoking them with a method along the lines of:
protected virtual OnFoo(FooEventArgs e) {...}

I thought of a few reasons for the "protected virtual OnFoo(FooArgs)" pattern. I can't come up with an aha moment, though.

There should be some way for a derived type to invoke its parent's event. That supports "protected" and the args.

There shouldn't be a way for nonderived types to invoke an event. That rules out "protected internal".

There shouldn't be a way for nonderived types to inspect the underlying delegate chain. Subscribers can put delegates to nonpublic methods in there; there's an expectation of privacy. That underscores why the backing delegate is private.

This is almost more of a mechanical problem than a logical one, but: there's a syntax problem in C#, at least--a logjam around accessibility. An event already has a modifier that is shorthand for its Add and Remove methods. How would we express accessibility of the event raiser, distinct from the accessibility of add/remove?

That covers everything but the reaons for "virtual". Leo mentioned the template method pattern. I think I'd call this a hook more than template--I think template implies both virtual and nonvirtual steps, where the base class performs the invariant steps nonvirtually. In this case, there is no invariant behavior, is there? Derived classes can suppress the actual raising of the event altogether. But the larger point stands: derived classes can decorate the base behavior.

If a derived class provides its own Add/Remove, it has to invoke its own local event; the base event is private. So there's an in-for-a-dime-in-for-a-dollar reason.

By making OnFoo virtual, you allow derived types to do a bit of covariance. Derived classes can read all the data from the FooArgs object and invoke an event that passes a SubFooArgs instead. It's cowboyish but possible. (I'm not coming up with a compelling example why you'd WANT to do this, but...)

Maybe this is a more realistic motivation: with a virtual OnFoo, you can precede (or simply replace) the base classes's event with a cancellable event of your own.

Okay. That's plenty of offtopic speculation from the likes of me. I'd still like to know if there's an aha-moment explanation, though. This is beginning to feel like an interview question...

Tuesday, December 15, 2009

Inheritance pattern: contract via constructor

In C# and the C-ish object oriented languages, if you want a family of types to implement a property, with each implementation particularized to each type (i.e., you care that everyone implements it, but you don't want one implementation cascaded to all), the big two techniques get lots of press: object inheritance from an abstract base and interface implementation. Here's another technique that's unsurprising when you think about it, but I've never seen it discussed as such: I'll call it contract via constructor. It's a little more stringent than the two classic approaches, since a subclass can't dodge the contract (in C#, at compile time, anyway) by implementing the required property as
throw new NotImplementedException();
And, it's feasible for a non-abstract class.

The idea is for a base class to require a value via its constructor(s) rather than requiring it via abstract property. Obviously, this is not universally advisable. But I find I have at least one rather substantial object hierarcy in most apps: say, one for persistable objects, maybe another for DTOs, and if a UI is involved, often several flavors of controls or containers, plus architectural base types if we're doing MVVM or such. Often, there's something I'd like to code out once, in a base class, with slight variations for each leaf. There's usually a generic type parameter or two that expresses the type-specific variations, but sometimes there's additional metadata, staticly known to each leaf but not knowable in the general case up at the base. It's the sort of thing where a VB programmer would write an enum into the base class and ride to putative glory on a switch statement. Not so great for framework programming or for, really, any code that shouldn't make you want to fire someone.

In the few hours since I really noticed this and have been salting it around my current project before deciding to blog it, contract via constructor is particularly useful if the property you seek is metadata about each subtype, e.g., so that you can handle it universally in the base type.

For example, suppose I want to specialize IntBindingPair into a family of types, each associated with an IEntity<int>. (An IEntity<int> here is a persistable object with an int primary key, and a string property suitable for display. The "binding pair", therefore, is basically a key/value pair for UI binding.) My base class's constructor takes an int and a string. I want each new subtype to be constructable from just the IEntity reference, so I need each subtype to specify how to choose its string value. (No, it's not time to override ToString(). Go sit in the corner.)

I could use an abstract property:

public abstract Func<TEntity, string> ValueExtractor { get; }

But I'd still be stuck on how to map my child class's sole IEntity argument to my base class's int and string; the instance property isn't available to be used in constructor args, for obvious reasons.

So, when in need, inject a fix! (This is a more commendable motto in software design than in, say, intravenous drug use.)


public abstract class IntBindingPair<TEntity> : IntBindingPair
  where TEntity : class, IEntity<int>
{
  protected IntBindingPair(TEntity entity, Func<TEntity, string> valueExtractor)
    : base(entity.PrimaryKey1, valueExtractor.Invoke(entity))
  {
    ValueExtractor = valueExtractor;
  }

  public Func<TEntity, string> ValueExtractor { get; private set; }
}


Now any child type must provide a real (or at least non-null) value for ValueExtractor; otherwise it won't even instantiate.

public class FooDisplay : IntBindingPair<IFoo>
{
  public FooDisplay(IFoo foo)
    : base(foo, f => f.Bar)
  {}
}
public interface IFoo : IEntity<int>
{
  string Bar { get; }
}


This same syntax solves another, possibly more general problem: how to transform constructor signatures from child types to suit the requirements of a base type.

Wednesday, October 28, 2009

Law of Grammarian Outrage

Much as Godwin's Law predicts the eventual invocation of Hitler in any sufficiently long internet discussion, I'd like to propose an axiom in the same sociological vein. There is a correlation between A, the number of commenting readers of a blog that are of an analytical (not to say hairsplitting) bent, and B, the likelihood that any blog post that mentions "beg the question" will get more responses to this controversial point of usage than to the original intended topic. (A for analytical, B for beg.) I'd say that on average, you need about 3 such readers for a 50% likelihood and perhaps 6 for 95%.

Relatedly, the number of grammarian posts is probably big omega of n^2, where n is the number of such readers: each such reader tends to respond to every other at least once. This far outstrips the usual number, which is, what, n log n, maybe? That is, the rate of response per reader would be log n. Or perhaps it would be "blog n".

Wednesday, August 19, 2009

App vs framework design

Another rebroadcast, this time of a response to Eric Gunnerson on differences between app and framework design.

Good post. I think your distinction between designing framework APIs versus wholly-owned application code is important. Not sure what Peter Ritchie is trying to get at by disagreeing; the differences between API and application design are so large that I'm inclined to say that anyone who disagrees has never designed an API that got released into the wild and made it to v2.

One of the few .NET books worth having as a physical book, IMO, is the "Framework Design Guidelines" by Cwalina, Abrams, et al. As good as it is, though, it's very much tuned to fx level (and is very frank about that; note the title). I've had several discussion with devs who've read that and think it's scripture for app design. Most recently, I had someone tell me that we shouldn't use underscores or case-sensitivity as part our C# naming conventions for nonpublic members, because the book cautions against language specific names b/c there are .NET languages that are case-insensitive or that may not have the same support for underscores. Of course, this guy also thought FxCop was the universal standard, too. I asked him why they didn't just name it FxPope and remove the ability to turn rules off. I'm glad not to work there anymore...

Wednesday, July 22, 2009

The Uncle Who Won't Shut Up

Following is a rebroadcast of my comment on Hanselman's blog.

Looking forward to hearing Uncle Bob again. I find him very insightful on coding issues, less so on community issues like how software developers should carry themselves, envision the job, etc. Then there's his politics, which I only mention because it is a large fraction of his tweets (i.e., he mentions it first and puts it in the public sphere). The farther he gets away from technical questions and the closer to sociological theories, he gets less empirical and more loopy. Worse, he also gets more strident, or at least no less so.

I guess he's not the first geek to go a little crackpot when outside his tech strengths. Noam Chomsky, anyone?

Anyway, here's a few questions I'd like someone to ask him. Maybe in part 4?

1. He's pretty big on craftsmanship lately. For the most part, the lesson of history has been, when craftspersons compete with engineering (i.e., industrial processes and capitalist management), the craftspersons get crushed. ("Outcompeted.") The industrial products are more reliable, they scale better, they don't have single-source dependency risks, etc.--and having scaled, their unit cost is cheaper. The "craftsmen" he mythologizes never got around to looking at their products that way; instead, they sat around, pretty happy with themselves, their traditions, and their traditional notions of "quality" and "reliability" until engineers came along and ate their lunch. The engineers innovated, while the "craftsmen" celebrated the past. Given the lessons of history, therefore, why on earth would we want to emulate craftsmen? Or does the "craftsmanship" vision only work for boutique shops, authors, and consultants?

2. He seems pretty ignorant of history with his "professionalism" speeches, too. Strictly speaking, a profession is something that is licensed by the state: doctor, lawyer, even plumber, and (notably) every sort of engineer except software engineer. A profession usually has generations of lore and experience behind it, and a core association (the AMA, the state bars, etc) that maintains "professional standards" and a code of ethics. Thus, in general, an industry has to be a couple generations old AND coalesced around a consensus set of practices before it can even THINK about becoming a profession. (Indeed, that's why the phrase "world's oldest profession" is actually quite a bit funnier, in a dry way, than most people realize today, now that the modern usage of "professional" has stretched to mean "white collar" and/or "not qualifying for amateur status".) I'm pretty sure that if Uncle Bob thought about it, he wouldn't want the government or anybody else telling him who's qualified to write software, or what his ethics should be. Ergo, either he hasn't thought about it, or he doesn't understand the connotations of the words he uses. Either way, he sounds unconvincing.

3. From what I can gather in his tweets and blogs, he's emphatically against not only health care reform, but regulation of the health sector in most any form. I'd love for you, Scott, to ask him how an unregulated insurance market would serve insulin-dependent diabetics, or anyone else who's acutely or chronically dependent on medical treatment. I'd love for you to look him in the eye and ask him what carrier would cover you, and whether you'd ever be able to work for a company smaller than Microsoft and still have coverage. (Of course, maybe you'd rather not entangle your blog and podcasts with that much off-topic drama. It would be quite professional of you, so to speak, to avoid it. But I have several close relatives with diabetes and other health issues, so I'm pretty tired of Uncle Bob's free ride. If he wants to evangelize ideas that would have awful human consequences, I think people should stand up. Your decision is yours, of course.)

Monday, July 13, 2009

INotifyPropertyChanged, C# lambdas, MethodBase.GetCurrentMethod()

I'm on a WPF project at the moment, and Silverlight before that. Both have this notion of INotifyPropertyChanged for bindings, whose only requirement is that you implement
event System.ComponentModel.PropertyChangedEventHandler PropertyChanged
and fire it off whenever any of your properties changes. So far so simple.

The downside is, the PropertyChangedEventArgs payload is not just a typewashed object, it's merely a string of the name of your property, so you see a lot of

public Foo Bar
{
get { return _bar; }
set
{
_bar = value;
OnNotifyPropertyChanged("Bar");
}
}

which works dandy until you rename something or forget to update your copy-and-paste. ReSharper will look in your literals for you, but I'm usually too impatient and sloppy to trust that.

Instead, I've been on a kick to use lambdas and MethodBase.GetCurrentMethod().

First you need a base class like ViewModelBase. Add the following:





   1:   

   2:          protected bool Set<TProperty>(Expression<Func<TViewModelInterface, TProperty>> expression, TProperty newValue)

   3:          {

   4:              TProperty oldValue = _propertyBag.Get(expression);

   5:              string propertyName = expression.GetPropertyName();

   6:              return SetObservable(oldValue, newValue, t => _propertyBag.Set(expression, t), propertyName);

   7:          }

   8:   

   9:          protected bool Set<TProperty>(MethodBase setter, TProperty newValue)

  10:          {

  11:              TProperty oldValue = _propertyBag.Get<TProperty>(setter);

  12:              string propertyName = setter.GetPropertyName();

  13:              return SetObservable(oldValue, newValue, t => _propertyBag.Set(setter, t), propertyName);

  14:          }

  15:   

  16:          private bool SetObservable<T>(T oldValue, T newValue, Action<T> updater, string propertyName)

  17:          {

  18:              bool changed = HasChanged(oldValue, newValue);

  19:              if (changed)

  20:              {

  21:                  updater.Invoke(newValue);

  22:                  // don't fire property change until oldValue is updated

  23:                  OnPropertyChanged(propertyName);

  24:              }

  25:              return changed;

  26:          }

  27:   

  28:          private static bool HasChanged<T>(T oldValue, T newValue)

  29:          {

  30:              bool changed;

  31:              if (ReferenceEquals(null, oldValue))

  32:              {

  33:                  changed = !ReferenceEquals(null, newValue);

  34:              }

  35:              else

  36:              {

  37:                  changed = !oldValue.Equals(newValue);

  38:              }

  39:              return changed;

  40:          }



Somewhere else are your helpful extensions:



   1:   

   2:          public const string GetterPrefix = "get_";

   3:          public const string SetterPrefix = "set_";

   4:          private static readonly int _prefixLength = GetterPrefix.Length;

   5:          

   6:          public static IList<Type> GetInheritedInterfaces(this Type type)

   7:          {

   8:              IList<Type> direct = type.GetInterfaces();

   9:              IList<Type> results = direct;

  10:              foreach (Type implemented in direct)

  11:              {

  12:                  results = results.Union(implemented.GetInheritedInterfaces()).ToList();

  13:              }

  14:              return results;

  15:          }

  16:   

  17:          public static string GetPropertyName<TInstance, TProperty>(this Expression<Func<TInstance, TProperty>> expression)

  18:          {

  19:              return ReflectionHelper.GetProperty(expression).Name;

  20:          }

  21:   

  22:          public static string GetPropertyName(this MethodBase method)

  23:          {

  24:              if (method.Name.StartsWith(GetterPrefix)

  25:                  || method.Name.StartsWith(SetterPrefix))

  26:              {

  27:                  return method.Name.Substring(_prefixLength);

  28:              }

  29:              throw new ArgumentException("Method was neither a setter or a getter.", "method");

  30:          }



where ReflectionHelper is basically lifted wholesale from Fluent NHibernate under BSD. It's not rocket science, though, just some manipulation of C# expression trees to extract the name of a property from a lambda that uses it.

Also, _propertyBag is basically a Dictionary where the strings are the names of the properties. Actually it's a Dictionary to keep some other stuff like original values, dirty bits, etc., but that's another topic.

The implementation of Get is like Set, only simpler.

The net-net of all this is that you can have

interface IMyClass
{
Foo Bar { get; set; }
}

class MyClass
{
public Foo Bar
{
get { return Get(x => x.Bar); }
set { Set(MethodBase.GetCurrentMethod(), value); }
}
}

which is fewer lines, no backing variable (e.g, _bar), and ReSharper-izable. Plus it breaks at compile time until you expose Bar on your interface, so it's as close to idiotproof as I've been able to get so far.


Against software "craftsmanship"

Lots of talk on web lately, esp from Object Mentor types like Uncle Bob and Michael Feathers, about the need for software developers to be more like craftsmen. This is true in small ways, I suppose, but it also seems false in large ones.

The decline of craftsmen, when possible, has usually been industrialization. One can get into frets about alienation of workers from their product, and in fact I usually agree or at least learn from such Marxist critiques. The moral core of those arguments, though, is the degree to which workers are left without meaningful tasks, in the aftermath of initial industrialization. That's a valid point when it applies, but it goes too far when you're just talking about how a software developer who's a dev today, and will be a dev tomorrow, should work.

So I don't think industrialization is evil or without useful lessons in this context. Mostly I think it's an important turning point in technical practices, a sort of coming of age. An inflection point, to use the modern parlance.

Back to software as craft: one of the revolutionaries of the Industrial Revolution was Eli Whitney, he of the interchangeable part. He famously figured out that an army could fight better if its rifles were each made from a finite number of said parts which could be carried into battle, pre-fabricated, rather than requiring a slew of blacksmiths and metallurgists to repair everything on demand. Or, more chronologically, he figured out that this was a better way to make a rifle, then he made a fortune selling rifles of that description to the U.S. Army, because the Army realized he was so, so right.

From interchangeable parts, computer scientists later borrowed the metaphor of subassemblies and, more broadly, decomposition. It's a natural enough idea mathematically, but making it intuitively clear to beginners almost always involves some example from the physical world--especially, the manufactured world.

From decomposition, we get the encapsulated object and the component. From these, we got to the unit test.

Would the craftsman have invented the unit test? To me, the answer is tautologically no. To break a task into subsitutable, commodity parts is, by definition, anti-craft. It is industrial. It is engineering. It's applying arguments (or motivation) of scale; ideas of aggregate, statistical value; perspective at the macro, systemic level; appreciate for complexity, emergent behavior, and the like. By definition, craft appreciates fuzzy essences, "things in themselves," metaphysics rather than physics. Those essences, those things, those human endeavors are valuable, but they are not engineering. I'd argue that the products they produce are not reliable in the way that an industrial product is, and therefore, that software developers should not be craftsmen.

Software needs ideas from the 21st century; the 19th already played out, and the craftsmen lost.

Postscript: Is it me, or is Uncle Bob's software advice, at least as it involves the community of developers (as opposed to pure technical practices like SOLID) getting progressively more hidebound, verging on counterrevolutionary and possibly trending toward stupid?

Monday, June 15, 2009

Odd final sentence in Fowler on UI Architecture

Fowler's overview of UI architectures is pretty much the standard article on the subject. I stumbled on it most recently when MSDN linked there from its Prism docs.

The final sentence has an odd little error, though--odd because this is an important sentence in a widely read article, and the error is quite apparent. The sentence reads, "Mappings will tend to be smaller for Supervising Controller than for Presentation Model as even complex updates will be determined by the Presentation Model and mapped, while a Supervising Controller will manipulate the widgets for complex cases without any mapping involved." (emphasis mine)

Clearly, the highlighted word should have been "simple". The Presentation Model is a stricter mediator of updates than the Supervising Controller is.

I suppose one could make the case that final sentences are so often overwrought, to the point of emptiness, that nobody really reads them anymore. But am I really the first person to be anal enough to notice this? Or is Fowler simply too busy to deal with web errata?

Like many motorists' failures to use turn signals, or the paving of our sidewalks with chewing gum and cigarette butts, overwrought final sentences are yet another symptom of the inexorable collapse of civilization as we know it, or would have known it, had we survived.

Thursday, June 11, 2009

WinMerge in VS2008

James Manning has an MSDN post for VS2005 that still helps when configuring alternative merge and compare tools.

Sunday, May 31, 2009

Silverlight.FX 2.1 navigation

Honestly, I'm torn between loving the declarative emphasis of Silverlight.FX--expressive, implementation-agnostic, terse--and recoiling in horror from how much it depends on string literals for commanding and now addressing/navigation. Also of concern, the MVC stuff follows ASP.MVC's conventions that make type name and file location semantically significant. (E.g., to have a Product controller, you need a type named ProductController in your /Controllers directory. Urgh.) There's a point at which convention-over-configuration strays into anarchy, and I think the ASP.NET pattern has passed it.

Granted, Silverlight is tangled up with xaml and must remain so, if only so it can roundtrip through Blend until something better comes along. This keeps its content quite close to text. And, maybe my love of Resharper has addicted me to static typing to an unhealthy degree, to the point that I want everything reflectable and typed, and I want it yesterday. But am I wrong to be creeped out by the strings? What makes this palatable? Is the theory: "It's acceptably safe to use strings for bindings, so long as they are sufficiently prominent, because their prominence implies that they are unlikely to fail without someone noticing?" (Much as many teams don't unit-test UI's, because the cost of high-fidelity testing is high, and manual testing gives it "enough" coverage.)

I don't get it.

Of course, xaml strings are not always strings. You can do some nifty things with type converters. But then again, type converters are a form of imperative code that's sufficiently subtle to let you THINK you're declarative and whatnot, when in fact you're nearly as entangled with imperative implementations as you ever were. Indeed, ever since a serendipitous typo, I refer to them as "type coverters".

And really, to the extent that they seem "nifty", most things you do with type converters seem so only because there isn't more elegant support in xaml for polymorphism. A richer language would erase (or at least subsume them) in a righteous flash of holy fire.

Monday, May 11, 2009

Uncle Bob, professional opinionator

Uncle Bob is back to his version of talk-radio for the blogosphere. Kernels of truth, whole gallons of certainty.

It's remarkable how many people get into definitional tugs-of-war over "professionalism" without citing the original, technical (if you will) meaning of professional.

Classically, if your vocation doesn't have an professional organization, government licensing requirements, and a code of professional ethics, among other things, you're not a professional. Plumbers are; coders aren't.

In my favorite clarifying example, there's a deep undertone of dry humor to the phrase "oldest profession", probably lost on most people today.

Thus, in the classical sense, anyway, an appeal for professionalism is an appeal to become establishment, institutional, blessed by the powers that be. Culturally (though perhaps not politically) it's conservative. I don't know that Uncle Bob intends this, but if so, it's seems to me this is not what Agile needs.

Craftsmanship, yes; ethics, of course; Marick's Artisanal Retro-Futurism x Team-Scale Anarcho-Syndicalism, very possibly. Speechifying and invective... no thanks.

(Note that I haven't read his actual keynote. Perhaps the speechifying is less in the speech than in the blog.)

Friday, April 10, 2009

Obsolete attribute in .NET

More from the note-to-self category: the [Obsolete] attribute generates compile-time warnings (or errors) but is not enforced by the framework at runtime. This is pretty obvious when you realize its purpose (backwards compatibility that warns but does not break) but spooked one of my coworkers.

Tuesday, March 10, 2009

Bulk unblock in Vista

Vista's UAC suspicion of downloaded code (and other files) manifests itself as a warning on each such file, cropping up when you open them. I usually see this when I download sample code, open the VS .sln, and collapse under the slew of warning windows.

Ideally, my antivirus software would have a setting to remove these values after a successful scan, or at least prompt me. It doesn't.

The fix, like so many fixes, comes from SysInternals. The underlying problem is that the downloaded files have been associated in NTFS's mind with the "main unnamed data stream". Si's streams utility strips off this association, and will do it recursively:

streams -s -d .

The "." for current directory is necessary.

I must have Googled and re-learned this a dozen times.

Wednesday, November 19, 2008

Test pattern

File this under note to self. Say you have a method to test, and inside it looks something like:

public class Foo
{
public bool Bar()
{
return A && B && C && D == "https";
}
}

Meaning, your method has several dimensions of possible inputs, and only one or a handful of acceptable states. Obviously, if the function really is as simple as that, you might not even want a test; static inspection might suffice. But suppose that the evaluation of A, B, and C is a little more complex or expensive, and suppose that there are, say, 3 different acceptable combinations among the full permuation of inputs.

Further suppose that A..D are each enumerable domains. (The actual use case that made me think of this was something like: A is "whether a page requires SSL", B is "the user is authenticated", C is "a certain control is visible", and D is "the protocol on the page request".)

What should the test look like?

The code that began to test-drive the implementation started out like this:

[Test]
public void Bar()
{
Foo foo = new Foo() { A = true, B = true, C = true, D = Uri.Https };
Assert.That(foo.Bar(), Is.True);
// cases 2 and 3 not shown but expect true

// everything else expects false
foo.A = false;
Assert.That(foo.Bar(), Is.False);
// tedious and brittle cut-and-paste looms if not careful...
}

This is the sort of situation you get into with TDD and Simplest Thing That Could Possibly Work. Having plucked the low-hanging fruit in the first few passes, you then need to cover something like "all the other situations". You're tempted to write something like:

[Test]
public void Bar()
{
foreach(bool a in new[] {true, false})
foreach(bool b in new[] {true, false})
foreach(bool c in new[] {true, false})
foreach(string scheme in new[] {Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeFile})
{
Foo foo = new Foo() { A = a, B = a, C = a, D = scheme};
Assert.That(foo.Bar(), Is.EqualTo(a && b && c && d == Uri.Https));
// okay, this only covers one of the three acceptance cases; you get the idea, though
}
}

In other words, your verification looks suspiciously like your implementation. Nine times out of ten, that will work. But every so often you discover that you've overlooked some aspect of the problem, and your mirror-image test code didn't identify the discrepancy because it was so similar to the implementation that both had the same bug. (For example: maybe the evaluation of A, B, and C can have side effects that create a subtle a temporal dependency in the order of evaluation, and by duplicating the SUT logic in the test, you never exercise alternative paths.) In general, I feel much safer if the test code takes a different route over the problem space than the SUT does.

You could go table-driven, but then you've got a table to maintain, and how do you know the table is correct? (Read: exhaustive.) Really, you want to codegen the table, which is why I actually like the nested foreach() blocks that iterate over explicit sets in the second version. The loops are clear, terse, and exhaustive. I'd like to keep that portion of the structure while having something that is logically equivalent without being codewise identical.

So, here's the pattern I prefer:

[Test]
public void Bar()
{
// explicitly test each of the small number of outliers
Foo foo = new Foo() { A = true, B = true, C = true, D = Uri.UriSchemeHttp };
Assert.That(foo.Bar(), Is.True);
// repeat for the two other affirmative cases

int trues;
foreach(bool a in new[] {true, false})
foreach(bool b in new[] {true, false})
foreach(bool c in new[] {true, false})
foreach(string scheme in new[] {Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeFile})
{
Foo foo = new Foo() { A = a, B = a, C = a, D = scheme};
if(foo.Bar()) trues++;
}
Assert.That(trues, Is.EqualTo(3));
}

Terse? Check. Exhaustive? Check. Sufficiently different? Check. It seems unlikely that, if I refactor this code six weeks from now, I'd make a mental mistake on the implementation that would easily transfer to the test as well.

As they say in math, the proof is by counting.

Sunday, November 16, 2008

Indiscipline kills Agile

That Jim Shore is doing it again. Here's another post I put on his blog.

Agile isn't for everyone. Is that heresy? I turn now, equally heretically, to a sports analogy.

In baseball, there's a belief that an underachieving team can sometimes be improved by bringing in a manager who's not just a different face but a different style. If the previous regime was easygoing with the players, the new one needs to be a disciplinarian, and vice versa. In clubs that are perpetually bad, there's often a perceptible oscillation over time between the two poles.

The interesting thing is, the strategy is thought to work in the short term. Intense managers raise the team's intensity, yielding better results; looser managers increase the team's--I dunno--zen, also improving results. For example: the Tampa Bay Rays got to the World Series this year with a prototypical "player's coach" (Joe Maddon) who replace perhaps THE prototypical disciplinarian, Lou Piniella.

Over time (the conventional wisdom goes), players adjust, cultures change, the results ebb, and eventually the team is ripe for a new revolution.

To return, finally, to software: hidebound developer teams can benefit from Agile. They discover new things about themselves and their business by going iterative and tightening feedback cycles. If they are sufficiently self-aware to capture their discoveries, their engineers can probably engineer an improvement here and there.

However, software developers that can't sustain their own discipline amidst some of Agile's freedoms--i.e., developers who are not especially professionalized or engineerish--are not going to thrive with Agile. Not long term. Indiscipline kills Agile.

Thursday, November 13, 2008

C# primers

So, for reasons bureaucratic related to my master's degree, I've been taking a .NET class. I don't especially recommend taking courses in things you already largely know--especially if long-distance. If you're going to disagree with someone on a philosophical or stylistic point of code, you don't want to do so by email.

Anyway, one of my classmates asked the class,

> What outside reference materials, books, sites, personal advice, etc
> would you recommend for someone with a subpar knowledge of C#/.net in
> regards to this class?

My reply was lengthy enough that it now becomes its own post. It's old hat but I wanted a copy in the archive.

* * *

One of MS's top developer blogs is Scott Guthrie's. He was away over the summer for paternity leave but is gearing up again lately. He writes lots of "how to" pieces and overview pieces about new releases or forthcoming products. He's very senior, so if scottgu's not writing about it, he's probably the boss of someone who is and thus will have a link to it. The comments on his blogs are often useful, too. Extensive archives to search.

Another top blogger is Scott Hanselman, who went to MS about a year ago after being CTO at a firm that got bought. His job now is more or less to evangelize MS developer technologies to the community and advocate for developer issues within MS. His writing is good, and the
comments on his blog entries are usually very smart.

I mostly read the articles but he has a podcast and frequent screencasts, too. Be careful, though: Hanselman is co-author of "Professional ASP.NET in C# and VB", a book that, in my opinion, is a waste of time, money, and trees. It basically repeats what is obvious from the APIs and docs: no useful advice or insight. The code samples are trivial. If I were Hanselman, I'd take my name off the book.

I agree with others' assessments of Jeffrey Richter's main .NET book. Really good but dense. He has a blog but doesn't post much.

Richter is also a contributor to "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries", which is very good at filling a certain niche. The book is almost like a printout of a blog: there are two main authors but several other contributors (such as Richter) whose comments are in sidebars throughout the text. This book won't help you learn how to write your first C# program; it's mostly an explanation of various decisions that
were made by the people who designed the .NET Framework, and recommendations on what "programming in a .NET style" might mean. It also provides anecdotally interesting insight into the amount and styles of usability testing that MS does with its developer tools. (These guys are all very smart, but they realize that they're writing tools for an entire industry of developers, not just the world's elite. When I get worked up about MS doing something stupid, it's nice to be reminded that sometimes MS omits effective solutions not out of raw incompetence but because they want to be all things to all people.) Anyway, if you're someone whose learning/retention is
improved by understanding why* the framework is a certain way, or if you just enjoy deeper understanding, this book can be very helpful.

Joe Duffy is another very smart guy who writes well, and he's written a book for beginners: Professional .NET Framework 2.0. I've only had it for a few weeks but I've liked all the parts I've read. His blog is very technical. He works at MS on parallel programming extensions
to the .NET framework.

If you're going to work professionally on ASP.NET, read Stephen Walther. His "ASP.NET 3.5 Unleased" is my favorite ASP.NET book so far, and his blog has been a steady stream lately of
interesting experiments with the forthcoming ASP MVC framework.

Eric Lippert works on .NET language and developer stuff at MS. Very smart and reflective about how tools and languages relate to good design. He's for professional developers; not recommended fo people who haven't programmed much or who don't plan to. Really wonderful
stuff, though.

Sunday, October 26, 2008

Kanban planning and the reverse event horizon

This was inspired by a thread on Jim Shore's excellent blog. You should probably start there.

Where I work, planned MMFs (as opposed to emergent support items, or dev-initiated work) are pretty chunky: usually several pair-days. Moreover, since we do weekly meetings with the customer to re-assess the queue, and our throughput is much slower than a week (usually 30+ calendar days), items at the bottom can stagnate due to multiple unfavorable re-assessments. Our median (for completed work, whether MMF or no) is much better than our average (for queued MMFs). In practice this means the queue is FIFO/LIELO (First In First Out/Later In Even Later Out).

Indeed, you could make the argument that our queue is not so much a queue as it is a kind of event horizon in reverse. Hey! I'll make that argument.

The event horizon of a black hole is a characteristic distance, such that anything that comes inside its radius gets gravitated in, even radiation, never to be seen again outside the EH. In the case of our planning queue, it's not about the attraction of gravity so much as the repulsive (repellent? there's no upbeat way to say it, and maybe there shouldn't be) force on a task due to other tasks competing their way ahead more effectively. The REH (Reverse Event Horizon) is a number that represents the point in the queue such that, if your task is always that far back, its expected wait time is infinite. The repulsive force is (expected to be) insurmountable.

For us, "constraining" the queue to 7 slots has been anecdotally beneficial, but I suspect the benefit does not especially come from imposing structured flow on development. There's still a considerable amount of chaos in our flow. And, we can't conclude anything more than "anecdotal" benefit because we, erm, have metrics issues that I won't get into here. Indeed, I'm not sure Kanban has changed our development flow at all.

Instead, our benefit comes from not having to plan/estimate/presupport (lose a large amount of our finite attentiveness to) tasks that will never get done, or that will have to be radically re-imagined by the time we are ready to work on them. The information flow has been smoothed, even if the work product turbulence is about where it was before Kanban.

It's not just that the information flow is smoother on a per-task basis, either. I think Kanban has also reduced the baseline difficulty of planning. In particular, I think that once customers began to think of tasks as inventory (and maybe especially as things that both tie up "capital" and lose value over time), they began to give themselves permission to plan less. Or at least, plan fewer: each thing can still get the careful consideration it used to get, but fewer things enter the conversation. I think we all know there's a cost to planning, but Kanban makes its costs more familiar and apparent.

Next post, I'll look at actual numbers to argue that 7 items is a pretty good queue depth for us. Teaser: My guess is that our actual REH is somewhere around 10 or 12. I know that we finish 1-3 queued items per planning iteration.

Saturday, October 11, 2008

The end of history

This blog is hereby rebooted.

POST (power on self test) complete.