@BevClement Actually, I'm working on a *very* high profile website so I can't afford to neglect IE... in reply to BevClement 23 hrs ago

September 2008

27
Sep

Why Stack Overflow’s reputation system is broken

I find it rather ironic that the author of the blog entry from which this excerpt is taken:

It seems like any time you try to measure the performance of knowledge workers, things rapidly disintegrate, and you get what Robert D. Austin calls measurement dysfunction. His book Measuring and Managing Performance in Organizations is an excellent and thorough survey of the subject. Managers like to implement measurement systems, and they like to tie compensation to performance based on these measurement systems. But in the absence of 100% supervision, workers have an incentive to “work to the measurement,” concerning themselves solely with the measurement and not with the actual value or quality of their work.

is also one of the faces behind a programmer website which does exactly what he is railing against.

I’m talking about the Stack Overflow reputation and badge system. Granted, it was more Jeff Atwood’s idea than Joel’s — he took his inspiration for it from the Xbox 360 — but the big problem is that when you try to turn a serious system that is supposed to be all about Getting Things Done into a game, people just game the system and turn it into an unusable mess that is not fit for purpose.

If you want to see what I mean, just take a look at this question, which I asked yesterday afternoon. I’ve been looking for a bug tracker system which can work as an integrated system for both developers and project managers for a while now, and none of the ones I’ve looked at so far have the particular feature I’m asking for.

The first so-called answer came within seconds and didn’t answer the question properly, which isn’t surprising since you would need at least 2-3 minutes just to read the question in the first place. It was followed by a string of about ten or so responses over the next half hour, again, very few of which made much effort to read the question, let alone answer it. Most people seemed to treat it as saying “What is your favourite issue tracker?” and one busybody even tagged it as “subjective” when I was asking for something very specific. And nobody so far has reported any success or otherwise with using an issue tracker of any description to integrate both the developer’s-eye view and the project manager’s-eye view.

This is a BIG problem with Stack Overflow, and I’ve seen it to an extent on other questions too. The system doesn’t favour good answers or correct answers or answers that actually make any attempt to answer the question, it favours quick answers. Being the first off the mark with something that at least looks like it could plausibly be an answer to the question means you’re most likely to get voted up. Getting voted up means appearing at the top of the list of answers, and it’s kind of self perpetuating because then you get more votes, and each vote means that you get ten reputation points, and if you get enough reputation points, you automatically become the Stack Overflow equivalent of a Wikipedia administrator.

The result is that you get a whole lot of knuckleheads gaming the system trying to pimp their reputation. They put up a response that looks fairly plausible and seems right to other knuckleheads but which either (a) doesn’t answer the question, or (b) is plain wrong. If the person asking the question is also a knucklehead, their answer gets marked as the accepted answer, which means even more reputation points. In the meantime, someone who arrives several days or weeks later with the correct answer doesn’t get any attention because their answer gets buried in all the other zeros. It’s particularly worrying because it’ll be the knuckleheads who end up running the show and deciding what goes and what doesn’t.

It’s as broken as lines of code per day, and it really really annoys me.

It really annoys a lot of other Stackers too — a request to fix it is the most popular user request on the Stack Overflow uservoice forums, though the problem is that there is no consensus about what needs to be done to stop it. I do hope they come up with some fix for it, otherwise the site could end up with no more value than its arch-nemesis, expertsexchange.

26
Sep

Colemak redux

It came as no surprise to me when I decided to revert to qwerty that my blog was inundated with spirited comments from the Colemak crowd. After all, some of them seem to think that the aforementioned layout could triple your typing speed, cure cancer, and stop global warming, and for me to admit that I’d failed to reach my qwerty speed after four months was nothing short of heresy for which I should be burned at the stake.

Well perhaps I was a bit too hard on it, and no doubt I’ll get another firestorm of comments from the fanboys here, because I’ve started using it again.

I’m not using it all the time, mind you. I tend to use my laptop at home, and in my experience, Colemak and laptop keyboards simply do not mix. But I’ve been using it increasingly at work with my Microsoft Natural 4000 keyboard, and the two of them seem to go together fairly well. I really can’t emphasise this strongly enough: if you want to get the most out of Colemak, get a split ergonomic keyboard.

Switching between the two layouts also seems more comfortable in the long run, once you get used to it. They exercise different muscles in your hands and arms, so I find that when I get tired working with one, switching to the other helps a lot. I also seem to be picking up a bit of speed with it too, and though I haven’t got round to testing myself again, I wouldn’t be surprised if I’m managing to hit 70 a bit more consistently.

Now if only someone would treat me to an Aeron chair

10
Sep

The leaf!

green_leafI was delighted to learn last week that I have been accepted as a member of 9rules. If you’ve never heard of it before, it’s an exclusive network of quality blogs run by Paul Scrivens, Mike Rundle and Tyme White. They don’t just accept anyone and everyone — only blogs with consistently good quality, design and content get accepted, so it was heartening to know that someone thinks I’m doing something right. They set the bar fairly high — you need to have been blogging consistently for at least six months, and they look for well thought out, thoroughly researched posts, and a good, consistent, easy to navigate design that is appropriate to what you’re writing about. So if you are one of those types who writes detritus like “omg lol chk out this youtube vid lmao rotfl” or posts those inane quizzes that tell you which Star Wars character you are, forget it.

There are some pretty interesting people in the network, such as Joe Anderson, who writes about a variety of issues related to general technology, Web 2.0 and “the” Wikipedia, and Lorelle van Fossen, whose blog about blogging is very well regarded within the WordPress community. Check out neverhappen.com too — it’s a daily photoblog with some absolutely stunning photography.

Needless to say, this will keep the pressure on me to come up with good quality content. The fact that I’m working in London for one of our Very Important Clients for the next three months puts even more pressure on my time as well — I have to set my alarm for half past five in the morning in order to catch the 07:25 train. However, a 55 minute commute each way does give me an opportunity to jot down some ideas for interesting content, even though the train can be pretty full and elbow room can be at a premium sometimes.

08
Sep

Paths and file locations in ASP.NET

There are loads of ways to find the path — either the URL or the physical path — to a page, user control or other file in an ASP.NET application. Unfortunately, however, the documentation doesn’t do a brilliant job of explaining them to you. There are also several different scenarios, depending on whether you are using conventional web forms, or URL rewriting, or Server.Transfer, or ASP.NET MVC. So I thought I’d better write down an overview of some of them for reference.

Scenario 1: direct request for a web form.

Just suppose for a minute that you have been contracted to rewrite Wikipedia in ASP.NET. So, for instance, you may end up with the page “What Wikipedia is Not” (aka “WP:NOT” or “Wikipedia’s attempt to get into the Guinness Book of Records for the most lies per kilobyte on a web page”) at http://en.wikipedia.org/wiki.aspx/WP:NOT.

In this case, you have several different properties of HttpContext.Current.Request containing different representations of it.

  • Request.RawUrl = "/wiki.aspx/WP:NOT" represents the path and query string parts of the URL. In this case, of course, there is no query string, but if there were, you might see it set to something like "/wiki.aspx/WP:NOT?mode=edit".
  • Request.Path = "/wiki.aspx/WP:NOT" represents the path part of the URL.
  • Request.FilePath = "/wiki.aspx" represents the part of the path to the file (in this case wiki.aspx) that is handling the request.
  • Request.PathInfo = "/WP:NOT" is a diff of Request.Path and Request.FilePath, giving the extraneous bit of the path that does not refer to a file in the file system.
  • Request.PhysicalPath = "c:\inetpub\wwwroot\wiki.aspx" is the physical path to the file that is servicing the request.

Case 2: Server.Transfer() and Server.Execute()

Sometimes, you may want to transfer control from one file to another. Let us suppose, for instance, that you decide to use several Web forms: one for articles, one for special pages, and one for article history. You do a few simple checks in wiki.aspx and decide to transfer control to another file, say, article.aspx, using Server.Transfer(). Then, another property of Request comes into play.

  • Request.CurrentExecutionFilePath = "/article.aspx" represents the path to the file that is currently handling the current part of the request.
  • Request.FilePath = "/wiki.aspx", however, remains unchanged.
  • Request.PhysicalPath = "c:\inetpub\wwwroot\wiki.aspx" also remains unchanged.
  • Request.AppRelativeCurrentExecutionFilePath = "~/article.aspx" is the same as Request.CurrentExecutionFilePath, but relative to the root of the web application, as defined in IIS. If your application were rooted at, say, "/wiki" then Request.CurrentExecutionFilePath would be "/wiki/article.aspx".
  • Everything else remains unchanged.

Note that Request.CurrentExecutionFilePath is always in use: if there has been no call to Server.Transfer it will be the same as Request.FilePath.

Case 3: URL rewriting

So you have this lovely new ASP.NET version of Wikipedia up and running, it works much more smoothly, has much less downtime, and runs on only a dozen or so servers rather than a hundred. Then, you start getting hate mail from irate Wikipedians, many of whom are open source zealots who are definitely not NPOV on Microsoft Windows. Jimbo and the Arbitration Committee get involved and demand you rewrite those URLs to cover up the fact that the Wikimedia Foundation has gone over to the Dark Side.

So, you take the original URL http://en.wikipedia.org/wiki/WP:NOT and transmogrify it into http://en.wikipedia.org/wiki.aspx?ns=Wikipedia&pg=What_Wikipedia_is_Not using a discreet call to Context.RewritePath.

Suddenly, everything changes!

  • Request.RawUrl = "/wiki/WP:NOT" represents the original path and query string parts of the URL. In actual fact, Request.RawUrl always represents exactly what you typed into your browser.
  • Request.Path = "/wiki.aspx" represents the path part of the URL.
  • Request.FilePath = "/wiki.aspx" represents the part of the path to the file (in this case wiki.aspx) that is handling the request.
  • Request.PathInfo is blank. When you use URL rewriting you have to point to a real file: you can’t use a PathInfo — that’s why you need to use a query string instead.
  • Request.CurrentExecutionFilePath = "/wiki.aspx" until you call Server.Transfer, when it changes.
  • Request.QueryString = "ns=Wikipedia&pg=What_Wikipedia_is_Not" is of course changed after the URL rewrite.
  • Request.PhysicalPath = "c:\inetpub\wwwroot\wiki.aspx" is, again, the physical path to the file that is servicing the request.

Case 4: ASP.NET MVC

So how on earth, you may be asking, does all this work with ASP.NET MVC? After all, it doesn’t use Web forms in the same way — URLs map to controllers, which then decide which views to render themselves.

Well here’s the skinny:

  • Request.RawUrl = "/wiki/WP:NOT" contains the raw URL (path and query string) as before.
  • Request.Path, Request.FilePath, and Request.CurrentExecutionFilePath, all contain the “path” part of the URL without the query string. They will all be set to "/wiki/WP:NOT"
  • Request.PathInfo is blank. ASP.NET MVC handles path info through the routing engine and passes it in the parameters for your controller.
  • Request.PhysicalPath = "c:\inetpub\wwwroot\wiki\WP:NOT" is NOT the physical path to the file that is servicing the request. Controllers may decide to render one of any number of views or other results, and they need not even be Web forms — they could be raw text content (from a ContentResult), or a redirect (from a RedirectResult or a RedirectToRouteResult) or a JSON string (from a JsonResult) and they aren’t associated with a physical file on the filesystem at all.

Case 5: ASP.NET MVC with URL rewriting and/or Server.Transfer

I shall leave this one as an exercise for the reader. No doubt there is someone, somewhere, who is doing this, for reasons that completely befuddle me. After all, I’d have thought that the whole MVC pattern renders URL rewriting and Server.Transfer pretty much redundant.

Case 6: Requests for a directory’s home page

This is much the same as the above, except that ASP.NET inserts the name of the home page — typically default.aspx — into Request.RawUrl, and, by extension, everything else. Obviously, this does not apply to ASP.NET MVC.

01
Sep

Commenting your code for speed reading

Here are a couple of important facts about code that you write, that many developers tend to overlook:

  1. You will spend much more time reading it than writing it, often after not having looked at it for months.
  2. Other people will also have to read it.

With this in mind, where possible, I like to use a coding style that helps me to speed-read my code. The idea is that you should be able to scan through a source file, picking out individual methods very quickly, and go from a grand overview of what’s going on to a detailed look at individual methods. It’s a style that I first picked up at university when looking at another developer’s code, and I’m yet to see anything that (in my humble opinion at any rate) beats it for clarity. It looks like this:

/* ====== MyMethod ====== */

/// <summary>
///  XML comment goes here
/// </summary>
/// <param name="str">
///  A <see cref="System.String" /> which is passed as a parameter
///  to your method.
/// </param>
/// <returns>
///  An integer, representing something or other returned by your
///  method.
/// </returns>

int MyMethod(string str)
{
    // do something
}

The key features are as follows:

  1. The method signature is prefixed by a header comment and an (optional) doc comment block.
  2. The header comment consists of the method name surrounded on each side by six equals signs.
  3. There are two blank lines before the header comment, one blank line between the header and the doc comment, and one blank line between the doc comment and the method signature.

This may sound pretty pedantic and exacting, but it’s just my style, and I find it clear, crisp and very effective for the purpose. There are of course other similar variations on the theme, so it’s more the principle that matters rather than the exact details. Highlighting the name of your method or property in a header comment in particular works wonders: you can page through your source file in seconds, and perhaps even relax the focus in your eyes a bit, and zoom in on the method you’re after very quickly. The decorative equals signs draw attention to the text of the headers without overwhelming them, which means you can pick them out and read them in a fraction of a second when you’re scanning through your source code.

One thing that I’m not too happy about, however, is the XML documentation comments that Microsoft has come up with for C# and VB.NET. The angle bracket tax gives you a whole lot of visual clutter to deal with. Javadoc and PHPdoc style comments seem much more elegant and simple:

/* ====== MyMethod ====== */

/**
 * Doc comment goes here
 *
 * @param str
 *  A String which is passed as a parameter to your method.
 * @returns
 *  An integer, representing something or other.
 */

int MyMethod(string str)
{
    // do something
}

Some developers tend to go a bit overboard with decorative bits and pieces on their comments. This is a real-life example from a PHP date/time library that I have encountered:

//==============================================================================
// +---------------------------------------------------------------------------+
// | Function: getMonthName                                                    |
// +---------------------------------------------------------------------------+
// | Accepts:  Nothing                                                         |
// +---------------------------------------------------------------------------+
// | Returns:  The name of the month                                           |
// +---------------------------------------------------------------------------+
// | Description:                                                              |
// |                                                                           |
// | Returns the name of the month of the timeStamp                            |
// +---------------------------------------------------------------------------+
//==============================================================================
	function getMonthName()
	{
		return date('F', $this->_timeStamp);
	}
	
	
//==============================================================================
// +---------------------------------------------------------------------------+
// | Function: getWeekDayName                                                  |
// +---------------------------------------------------------------------------+
// | Accepts:  Nothing                                                         |
// +---------------------------------------------------------------------------+
// | Returns:  The name of the weekday                                         |
// +---------------------------------------------------------------------------+
// | Description:                                                              |
// |                                                                           |
// | Returns the name of the week day of the timeStamp                         |
// +---------------------------------------------------------------------------+
//==============================================================================
	function getWeekDayName()
	{
		return date('l', $this->_timeStamp);
	}

Very pretty, but the decorations on the comments dwarf both the code and the comments themselves somewhat. Personally I find it slower to scan — partly because the comments take up more space, which means you get less code on the screen at the same time, but also because it looks rather distracting. The difference is only a fraction of a second for each method, but it does add up in a big class.

Besides, that kind of bling is a complete faff to type.

Needless to say, this isn’t the only thing you need to do to make your code easy to read. You also need to choose sensible method names — not too long and not too short — that describe what your method does as precisely and clearly as possible within about 30 characters or less. Consistent indentation is also pretty important (Visual Studio is great in this respect — it does it all for you if you press Ctrl-K, D) as is keeping your line length down to something sensible. I find that the maximum line length you can sensibly get away with is about 96 characters: beyond that, you start to have to scroll horizontally all over the place, and your lines wrap when you try to print it out. Oh, and if you use the visual designers in SQL Server Management Studio, please tidy up the resulting SQL after you copy and paste it into your stored procedures. Otherwise you are making life difficult for whoever comes after you who has to understand and maintain the stuff.

What do you think? Do you use any particular stylistic conventions on your comments, or do you find incremental search, document outlines, syntax highlighting and code folding sufficient? Can my style of commenting be improved on?