May 2007 - Posts

This post will be quite long, since not only am I going to present the Range class I wrote, but I’m also going to go into some of the decisions I made and why I made them. First off, I’d like to thank Jay Bazuzi and his readers for his article and its follow-up where they created a simple Range class.

Generic or non-Generic?

Well-this question was easy enough in its way; it makes sense that we make a Range class generic. However, there was an implication on this. Obviously any kind of range will need to be able to compare its items, but which IComparable should we support? IComparable<T> has the advantage of being more strongly typed, but IComparable is probably more widely supported. It took me a while to decide, but I finally settled on IComparable<T>, largely because strong type safety is a good thing. In any case, the main Framework classes support it, and for custom classes, it’s not difficult to add.

Class or Struct?

This was a question that took a while to decide. I actually originally settled on struct, but then switched to class when I decided I wanted to return null from some methods. Then I changed my mind again and instead returned Nullable<Range<T>>. Finally, the decision was made for me due to two design decisions:

1.       I wanted to have child classes that inherited from Range<T>

2.       I wanted to ensure that the Range<T>’s created by a set of factory methods only.

Since you cannot inherit from structs, and anyone can create a struct using its default constructor, I had settled (by default) on a class.

Mutable or Immutable?

This was another tough call. By making the Range<T> mutable, I would certainly simplify my life, but there were some points against too. First off I was at that point considering a RangeList<T> that would keep a set of sorted ranges, trying to keep contiguous ranges together. If we could change the values of the range underneath the collection, this would become very difficult to keep in a consistent state. What finally hit the nail in the coffin though were the two child classes that I created, let’s look at the classes:

Class diagram of the Range and subclasses

In this diagram you can see that I decided on a Range<T> base class that would contain the UpperBound and LowerBound properties, and handle all the comparisons and modifications necessary. Sometimes we would want to associate a range with something other than just the range, some extra data. To cater for this possibility, I created the Range<TKey, TValue> class, which inherited from the base Range<T>, but added a Value property. Finally, I also handled a special case, a case where the range represented an array, similar to Range<TKey, TValue>. but different in two respects. Firstly, it inherited from Range<int> specifically, and secondly the value was an array just for easier access to the elements. To be honest I’m still not sure about this one.

Anyway, these subclasses decided the mutability question for me. It’s all very well to talk about splitting a Range<T>, but what exactly does it mean to split a Range<TKey, TValue>? What should I do with the value? If I didn’t know what it was, how could I meaningfully handle joining or splitting ranges containing such values?  I couldn’t, so I decided to make the ranges immutable. All the “modification” methods on Range<T> you see in that diagram return completely new ranges. More particularly a call to Range<TKey, TValue>’s Union would return a Range<TKey>, without the associated value. All of the main methods here return simple ranges, without associated extra data. They are used, in a sense to tell the developer what to do:

var start = Range.Create(0, 5, "Hello ");
var end = Range.Create(6, 10, "World");
var join = start.Union(end);   // 0->10

In the example above, the last Range tells us that the union of start and end is a range from 0 to 10; it doesn’t know to concatenate the two strings though. That would be for the programmer to determine, perhaps something like:

var final = Range.Create(join.LowerBound, join.UpperBound, start.Value + end.Value);

So, as with the class vs. struct decision, in a very real way it was previous decisions that forced my hand on this one. The lesson is important I think. Quite often decisions made much earlier in the process constrain your choices later on. In a sense, this is the point of refactoring, to once again open up your available options.

Interfaces and Overloads

The one interface to implement was pretty obvious, IComparable<Range<T>>. A complete no-brainer there. I also thought it was important to provide comparison against T, so that’s why IComparable<T>. This segues nicely into quite an interesting digression. Given a range {0->10}, is it bigger or smaller than 5? The comparisons were to give me nightmares. I created all sorts of spaghetti code, made even more monstrous by a doomed decision to try and support not only infinities, but also limits, values that were not quite the given value. So we could have a range {[5]->10} which meant that the range extended from just after 5 up to and including 10. Now, ask yourself this question; forget the simple comparison I gave you earlier, which is now larger: {[5]->10} or {1->[5]}, or what about {∞->[5]} vs. {5->[7]}? I found myself in a nightmare world in which comparisons changed their meaning based on which side of the comparison and which side of the range they were on.

 

I had forgotten the cardinal rule of software development: Keep it Simple Stupid. For goodness sakes if I needed infinities and limits, I could bloody well implement another class that handled them, and just pass it in as the type parameter to Range! Trying to implement a range that did everything was an exercise in futility. More particularly, what if the developer using my class didn’t want to have infinities, or the hassle of figuring out obscure comparison rules?

 

Anyway, after a fair bit of time excising the horrific comparison code and unit tests, I settled on a simple solution, comparisons would be against the LowerBound. So {5->10} < 6Just for jollies I decided to also support IComparable, where I just tested the type of the incoming object and passed it to the relevant CompareTo method.

 

I also overloaded Equals. Now, I decided that Equals would only ever return true for two ranges. I’m not fully decided on this one. It means I have the unusual situation where {5->10}.CompareTo(5) == 0, but {5->10}.Equals(5) == false. However, as I see it Equals is a much stricter comparison than CompareTo. If you disagree, let me know.

 

To make life a bit easier I also provided a simple little overload of ToString that gives me my nice {x->y} in the debugger.

 

Operators

This was fun. I normally don’t do operator overloading, simply because there isn’t much call for it. Let’s face it, what exactly does it mean to add two Customer objects? I implemented the usual comparison operators, and also implemented three modification operators:

·         ^ - Which I took to mean Complement, removing a range from another.

·         | - Which I took to mean Union, coalescing two ranges into one range that spans both.

·         & - Which I took to mean Intersect, providing a range for the areas where both ranges overlap.

Again, I’m not 100% sure I’ve done the right thing by providing the modification operators, but I guess I just got carried away.

 

Iterators

This was quite interesting. I wanted to be able to iterate through a range. In other words (for integers), given {0->5}, to iterate 0, 1, 2, 3, 4, 5. However, since I’m dealing in generics, I don’t really know what the T is, and I especially don’t know what it means to iterate from one T to another. Even for types I do know about, how would I iterate them? I mean, if it was DateTime, would I iterate the seconds, minutes, years? So what I did was take a delegate in the Iterate method called incrementor. It’s a Func<TArg0, TResult>> and so can be used with a lambda expression. So you can do this for example:

 

Range<int> range = Range.Create(0, 5);
foreach (int i in range.Iterate(x => x + 1))
{
    Debug.WriteLine(i);
}

I thought it was a nice touch. Just for completeness I provided a ReverseIterate that takes a decrementor. So, the meaning of a range is left up to the person supplying the incrementor, and a single range can mean different things at different times. Cool!

Factory class

A nice touch from the original article by Jay was to have a static Range class that takes the methods that operate on multiple ranges. I decided not to completely go that route, but all the stuff that operated on lists of ranges, as well as the factory methods I put in this class:

Class diagram of the static Range class

Covariance/Contravariance

C# does not support covariance for generics. What this means is that if I have a method like this:

 

IEnumerable<Range<T>> Find<T>(this IEnumerable<Range<T>> ranges, Func<Range<T>, bool> predicate)

 

I cannot pass a List<RangeArray<object>> into the ranges parameter. Even though the list implements IEnumerable<T>, and the T in this case is inherited from Range<T>, it does not see these two types as compatible. Apparently there is good reason for this, but I don’t know what it is.

 

So, in order to get around this problem, I originally decided to create a RangeList<T> and a RangeList<TKey, TValue> and a RangeArrayList<T>, all of which would implement IEnumerable<Range<T>>, and thus the methods on the static class would accept them, and there would be celebrations throughout the land. Well, I did, and it worked fine, but it niggled at me. I realized that the only reason those collection classes existed was to get around the covariance problem, but that they also constrained the solution. What if someone wanted a Dictionary<Range<T>, string>, and wanted to pass the Keys enumerator to one of my methods? Well, they wouldn’t be able to, all because of bloody covariance. So, if you cast your eye up to that class diagram above, you’ll see my solution.

 

First I made all the constructors of my classes internal, ensuring that no-one could inherit them, just for good measure I marked Range<TKey, TValue> and RangeArray<T> as sealed. Then, I created two overloaded private methods on Range, called MakeCovariant. One took an IEnumerable<Range<TKey, TValue>> and the other an IEnumerable<RangeArray<T>>, and they both returned IEnumerable<Range<T>>. Then I created similar overloads for each of the static methods that called MakeCovariant on their arguments and passed the IEnumerable<Range<T>> to the “master” method. The upshot of all this was that the lack of covariance had now ceased to be a problem as far as my static Range was concerned. This would only work as long as my three classes were all that there was, and no-one created new subclasses, which I’ve ensured.

 

I guess this wouldn’t be necessary if I had just decided to stick with having the Range class as a struct, but I like having the three Range options, and now I don’t have to have three extra collection classes supporting them.

 

Anyway, one side-effect of all this is that the Find method is a bit interesting. Have a look at the three Find  signatures:

 

... Find<T>           (this IEnumerable<Range<T>> ranges,            Predicate<Range<T>> predicate)    ...

... Find<TKey, TValue>(this IEnumerable<Range<TKey, TValue>> ranges, Predicate<Range<TKey>> predicate) ...

... Find<T>           (this IEnumerable<RangeArray<T>> ranges,       Predicate<Range<int>> predicate) 

 

Note that, in all three cases, the predicate takes the base Range<T> class. What this means is that it you attempt something like:


IEnumerable<RangeArray<T>> ranges = /* Create Range */
Range.Find(ranges, x => (x.Values.Count == 0)); 


You’ll find that the lambda won’t compile. The simple reason is that, despite the fact that the collection contains RangeArray‘s, I’ve only written the predicate to accept Range<T>. I guess I could change it, but it’d mean duplicating the Find functionality, and I’m lazy.

 

So, have fun with the class, which you can find here. Please note that this is an Orcas project. It doesn’t take too much effort to back-port it to Whidbey though. Let me know if you have any problems, improvements or anything. It has not been rigorously tested, but I’ve included the unit tests I’ve done so far.

 

One of our more colourful politicans in South Africa, Patricia De Lille has called for blogs to be regulated, and has asked the National Intelligence Agency to investigate an anonymous blogger. Apparently this complete swine dared to make defamatory statements about Simon Grindrod, an Independant Democrats representative. Apparently this blog also slandered a rugby player, a reverend and an entertainer.

They refuse to indicate where to find this blog as it may give it credence, but are quite happy to waste state resources attempting to find this despicable criminal. I did a quick Google search for the relevant search terms and can find nothing, clear evidence of how clever this insidious blogger is.

You know it's bad enough that these bloggers can write what they like, but to actually allow people to read such uncensored filth!

Ms. De Lille, I think rugby sucks, Steve Hofmeyr has too little talent, Pastor Ray is a hypocrite, and you have too short a fuse. My name is Sean Hederman and I eagerly await your goose stepping, jack booted thugs.

Update:  A touch melodramatic on second thoughts and a clear head in the morning. Nonetheless, I cannot stand the pompousness of so many politicians who seem to take the view that no commoner had better ever say anything nasty about them. There is an arrogance implied in using our state intelligence agencies to track down some anonymous fool. If I were to ask the NIA to track down the real identity of a commenter on one of my posts, would they do it for me?

Of course not, the very idea is laughable. What's so bloody special about ID representatives that they think they should be above the slings and arrows of the chattering anonymous masses on the Internet? One thing is quite clear though, they have no real understanding of the Net. Action like this is simply cannon fodder for a tidal wave of abuse, hilarity, and satire.

Quite interestingly, Reinhardt Buys, a South African legal expert is quoted on the issue here. He is dismissive of De Lille's legal standing, and he "[says that he hopes that NIA has better things to do that censor free speech on the Internet]" and I particularly enjoyed his statement "De Lille’s remarks, assuming she was quoted correctly, show a limited understanding of not only the law, but also the use of the technology".

Smackdown!

Update 2

Thanks to brian for the link. It turns out that the offending blog entry is here. Basically, it's just some crackpot claiming to be a male prostitute who has serviced various South African celebrities. Zero credibility, and a U.S.-hosted blog anyway. Is Patricia going to get the U.S. to overturn it's First Amendment so that Grindrod can find out the identity of this blogger? I doubt it. Apparently the ID have threatened to sue anyone who posts the link to the site, so I'm eagerly going to be awaiting my subpoena.

I'd say that far more damage is being done to the ID image by their threats and overall childishness on this issue than some unimportant blogger. Anyone who takes themselves so seriously that crap like this infuriates them is worthy of ridicule.

Update 3

The ID have released a clarification of Patricia's remarks. Basically this clarification is a whole bunch of handwaving about how she supports freedom of speech, followed by asking how she can charge anonymous bloggers with slander.Indifferent She doesn't touch on how she's asked the NIA to waste taxpayers resources tracking down a lone nut, nor does she propose how anonymity can be suppressed across the whole Internet. She also doesn't go into why Grindrod is laying a charge for a civil matter.

She claims she was misunderstood. No, Patricia, we all understood you quite well, and your clarification just confirms it. You want to make it a crime to say nasty things about you and yours. You want to rip away anonymity on the Internet, ignoring the many whistleblowers and commentators that have successfully used this anonymity to effect positive change. All that, and you have no idea whether it's even feasible to do what you want. Here's a hint, it's not. Even if you could convince all other countries on Earth to stop giggling whenever you presented your demands for information, what makes you think that they'd even have the information you request.

In a world of Internet cafes and mobile access points, how exactly would you propose to institute your Ministry of Information?

Wouldn't it perhaps be a touch more practical for politicians and celebrities just to get thicker skins?

Update 4

Cape Town News has found the IP address of the blogger who so offended Patricia that she was willing to censor the Internet. Apparently said blogger was in Mitchells Plain at the time. The blog has also been taken down, I guess the blogger has caused the furore they were after. Someone needs to explain to the ID what a troll is.

In fact, several blogs and forums are reporting that the blogger is in fact one Juan Uys, formerly of the Gay and *** Alliance (aka Juan and his fax machine), formerly of the almost-existing Death Penalty Party of South Africa, formerly of Crime Expo SA. The man who apparently claimed that Raymond Ackerman supports crime in South Africa. He's had a run-in with Grindrod before by all accounts. Anyway, he has around about as much credibility as George W. Bush talking about WMD's. He's seemingly desperate to get himself any publicity at any costs no matter what the harm to his or anyone elses reputation. For goodness sakes this guy went and outed gay schoolchildren just before a Matric dance. He was pretending to be against sodomy at the time. This is a man with nary a scruple to be found.

All the ID's thuggish tactics did was give him exactly what he was craving. As I said before, troll.

So, the alleged anonymous blogger appears to have been outed fairly swiftly, without requiring NIA or police involvement, and without any curtailment of civil liberties. Now what will be interesting to see is if Grindrod does begin civil action against Juan Uys or whoever the samaleprostitute might prove to be. After all the sound and fury of the ID's disproportionate response, a lack of legal follow-through would be interesting.

I've just recently got my paws on the Orcas beta, and am wading through many blogs, trying new stuff out. I have come across a very cool blog called Yet Another Language Geek by a guy called Wes Dyer. If you haven't subscribed, trust me, do so now, but I'd strongly suggest reading some of his earlier posts first.

I have just endured over an hour of aggravation, and spent hundreds of rands trying to get my PC to boot. Not a difficult chore you might think, I mean some PC's have been known to boot several times. Hell, put Vista on and you'll boot several times a week. Anyway, whilst I was pulling open the innards of my computer I was musing on the design of these internals. Since I was replacing the power supply, my thoughts naturally gravitated to that. Guess which component on your PC does not come with a warranty? That's right, it's that PSU, which means basically that some manufacturers (with some assistance from our wonderfully reliable electricity supplier, Eskom) appear to have gone for an approach known in the stockbroker business as "churn".

So, given that the PSU is the most likely point of critical failure, one would expect that said PSU would be trivially easy to replace? Not so fast, instead, the octopus-like PSU snakes into every nook and cranny of your computer, making it marginally less difficult to extract than your standard exomorphic parasitic predator.

Standard PC Power Supply

What makes the sinuous bundle of power cables even more fun to implant is the already impressive collection of IDE, SATA, cards, jumper cables, and fan cables that the power cables must navigate through, without exerting the slightest bit of pressure that might cause any of the above to come loose, which would necessitate a complete rewire. Sometimes, if you're especially lucky, you pay a fortune for a high-end case like mine which puts the power supply in a separate compartment from the mainboard. This gives two main advantages. Firstly, it improves the airflow in the case. Secondly, it ensures that the arm-thickness worth of power cables must go through a tiny little slot, and then twist ninety degrees and slip in to the PSU, with half an inch of space spare to contain the inch thick cables.

After plotting that course (with much attendant swearing), I gained a new appreciation for the pains of childbirth. You may ask why I replaced the PSU. Well, that's simple really. My computer was refusing to boot, I'd power it on, and the fans would switch on and the lights would light up, but the hard drives would not spin, and the screens would remain dark, the only thing that appeared to work was the power button, which, if depressed for the requisite 5 seconds, would power down the PC. Again, you may ask, why the PSU? Well, I've gone through five power supplies in the last couple of years, and the result of their failure is always the afore-mentioned symptoms. So I'm getting quite accustomed to the painful cost of a high-end PSU, and the much more painful installation of one.

Since I'd decided to finally see some sense and switch from the brand that had failed five times, I had the new experience of trying to find a better than 500W PSU which had 4 SATA connectors, and was not my usual brand. As you may expect, almost every store only stocked my original brand, or didn't have powerful enough power supplies. Finally, at a store near my work, I found a 630W monster, with detachable cables, and funky flames on the box. Hoping the flames referred to something other than my PC after plugging in this PSU, I gratefully purchased it and headed homewards.

The installation was every bit as fun as I've explained above, with the added bonus of a cold or something that caused me to sneeze in machine-gun bursts. Not fun when doing wiring, but it did help remove dust from my PC internals. Afterwards, I switched on the PC, and watched as it did absolutely... nothing. The exact same symptoms as before. Wait, I spoke too quickly, there's a new bug in that the case power button no longer powers down the machine. I'm not sure if I can really complain about that, since compared to not booting, that's a bit of a rounding error. It's a little bit like getting snarky with the stewardess for being slow with your drinks order whilst in a six hundred mile an hour uncontrolled vertical dive.1

So, now I'm a few hundred bucks out of pocket for a PSU I didn't need, massively aggravated, and without a working PC. It was about then that a though crossed my mind: if it's this irritating and vile for me, a computer professional, who has built many computers, imagine what a pain it must be for everyone else.

We need some sanity in the design of these bloody machines. One power cable would be a good start. For goodness sakes, forget how difficult all these things are to wire, just keep in mind how untidy they make your case, and how much they disrupt critically needed cooling airflow. I mean, if you had sat down a group of engineering experts at the dawn of the computer age and asked them to design something to be as untidy, fragile, poorly thought out, and irritating as possible, the still wouldn't have caught up to the average computer manufacturer.

How about the Apple approach of having PC's that you can't fiddle with. Need more space, or to play the latest game? Buy a new computer with the required specs. How about if they wired the power to components in with the data connectors, sorta like USB does? How about a PC where it's easy to replace commonly replaced things? I'm telling you, between the pain of Vista and the nightmare of keeping a PC running and up to date, Apple is starting to look mighty good. C'mon, Steve, give up on this Mac OS crap, and start making PC's, you'll make a fortune.

------------------------------------------

1 Apologies to George Carlin