All posts by jonskeet

Mad props to @arcaderage for the "Princess Rescue" image - see https://toggl.com/programming-princess for the full original

Writing user interfaces

Some of you may know that I don’t do a lot of user interface work. Well, in the last couple of weeks I’ve been doing little but user interface work. I thought it might be time to share a few reflections.

Designers

The designer in VS 2005 is actually very good – for a designer. It still has its “thou shalt not touch this bit of code” which of course you then have to touch in order to include some controls which aren’t in the toolbox, but overall it’s pretty reasonable. I particularly like the “GenerateMember” property it uses to decide whether or not to create a member variable for controls. No more silly label variables for no reason!

One day I’ll be able to use WPF/XAML, which is of course another step up again, but until then this isn’t too bad.

TableLayoutPanel

Hooray, a half-decent layout in WinForms. Whatever people may say, just using Dock and Anchor doesn’t give enough control over layout in my view. Lining things up with absolute positioning should have been a thing of the past years ago.

TableLayoutPanel appears to have some significant shortcomings, however. In particular, I was in a situation where it would have been really nice if TLP allocated all the “Absolute” sizes, then gave as much as possible to the AutoSize rows, then gave any spare to the percentage rows. However, it goes top to bottom, left to right. Basically I wanted a couple of buttons below a multi-line label, and for the label to become a scrolling area if there wasn’t enough room for it, with the buttons always present just below the label. Maybe there’s a way to lay this out the way I want, but having sworn over it for most of an afternoon, I’ve given up.

Scrolling is also a pain – it tooks me a long time to get any scrollbars to appear when I wanted, and I still don’t know exactly what triggered it suddenly working. Even now they aren’t quite right, as the appearance of a vertical scrollbar forces a horizontal scrollbar to let you get at the bit of the panel which is now taken up by the vertical scrollbar – even if there’s nothing there! All very frustrating.

Overall architecture

I really suck at this. I’m trying to separate everything out appropriately, but I don’t know enough about it to cope when things get tricky. All the samples of MVC, MVP, Humble Dialog etc are fine when they’re doing relatively simple stuff, but it feels like UI is particularly prone to “I know I shouldn’t have this logic here really, but it’s much easier than doing it properly…” Hmm.

Frustration/Joy

I have really mixed feelings about the satisfaction derived from UI. A lot of the time it seems like very slow work – implementing a small UI feature seems to take a lot longer than implementing a small server-side feature – but when it’s working, it’s very visible. You can show people the results. Just demonstrating hundreds of working unit tests and a few database tables filled with data doesn’t have nearly as much of a pull. I think a prototype UI (not prototyping the real UI, just enough to demonstrate backend features) is possibly the way forward here.

Basically, I suspect I’ll never be a GUI person at my core. I can grow to be passably good at it, but I suspect that you have to keep working at it for a high proportion of your time to know all the gotchas and tricks involved and keep a clean design.

 

In other news – the book is still coming along. Sorry to have kept so quiet about it, but I’m hoping I’ll be able to announce something properly (and tangibly) fairly soon.

Extension methods and .NET 2.0

Update: as Daniel Moth has pointed out in the comments, it is possible to use extension methods in Orcas projects targeting .NET 2.0 by introducing your own System.Runtime.CompilerServices.ExtensionAttribute class. See Daniel’s blog post for more details.

One of the neat things about Visual Studio 2008 is that you can target .NET 2.0, 3.0 and 3.5. I’m hoping to start using it professionally shortly after it’s released – assuming stability and performance aren’t an issue, of course. The great thing is that some of the C# 3 features don’t require any framework support at all (and none of them require CLR support, as far as I’m aware). So, I’ll be able to use anonymous types, local variable type inference, object initializers, collection initializers and automatic properties. Sure, there’s no LINQ, but I can take that hit.

But what about extension methods? As far as I can figure out, they only require one feature from the framework: an attribute to decorate a method to say that it’s an extension method. If we could provide that as a compile-time option, we could use extension methods in .NET 2.0 projects, assuming I haven’t forgotten something important.

Now, I know there’s a lot of controversy about whether extension methods are really a good idea in the first place – but I for one would welcome the opportunity to use them in .NET 2.0 projects. My wild guess is that I won’t be able to use .NET 3.5 until mid-2009, and that a lot of other developers will be in the same boat. I’m sure the transition from 2.0 to 3.5 will be faster than 1.1 to 2.0 – and I doubt that many people will target 3.0 at all – but it’ll still be far from instantaneous.

The obvious downside of this would be everyone creating their own attributes and using them throughout their projects. However, it wouldn’t take long to remove them when the project moved on to .NET 3.5 – delete the attribute and remove the compiler option, then fix the compilation errors.

It’s too late to suggest this for the Orcas timeframe, really, which is a shame. I wish I’d thought of it earlier – although I suspect it’s been suggested before, so it probably wouldn’t make any odds. Anyway, what do you all think?

Is C# 3 too big to learn from scratch?

I’ve been looking at C# 3 in a fair amount of detail recently, and likewise going over the features of C# 2. (I hope to be able to be less coy about all this soon.) I’m beginning to think that while it’s all great for existing C# 1 and C# 2 developers, I feel sorry for someone wanting to learn C# 3 from scratch. It’s becoming quite a big language – and of course the framework is big and getting bigger (more on that in another post).

I’m generally a fan of small languages whose functionality is provided by libraries. This is still the case with C#, but the compiler is now being smarter in various ways to allow for a lot of the neat features in C# 3.

It’s often been said in the newsgroups (usually when someone has been moving from another language to C#) that C# itself only takes a few days to learn, but the framework takes a lot longer. The “framework takes longer” part is still true, but what about learning C# in a few days? I’m sure it depends on previous experience: someone coming from a functional background is likely to find the C# 2/3 changes to do with anonymous methods and lambda expressions significantly easier than someone moving from C or Java.

The interesting thing about the new features in C# 3 is that aside from query expressions, they’re really fairly easy to describe. There’s a big difference between reading the description of something and really “getting” the feature – and I’m not even talking about best practices and applicability, just sheer “understanding what’s going on when you see it in use”. Generics in C# 2 work almost the other way round – they’re quite complicated to describe in detail, but you can largely get on with using them and deal with details later. You end up with surprises such as the lack of type parameter covariance, but there will always be new things to learn with virtually any feature.

So, if you were learning C# from scratch, would you be daunted? As a rough indicator (and one which genuinely doesn’t have much to do with my writing at the moment) how big a book do you think it would take to learn C# (without Windows Forms, etc – just enough of the core libraries to understand iterator blocks, IDisposable etc)? I suspect it would be hard to do it any sort of justice in less than about 700 pages, which is a pretty off-putting size (at least for me).

I’m not sure whether it’s useful for an incoming professional developer to start off learning C# 1, then learn 2 when he’s comfortable with 1, and then 3 afterwards. It would be quite hard to be productive either working on new code or maintaining old code without being able to understand the syntax that colleagues are using.

Maybe there are enough existing C# developers and enthusiastic newbies who are willing to make such a significant commitment. Maybe I’m completely wrong about how hard it is – let’s face it, it’s always hard to gauge the difficulty involved in learning something after you already know it. I am concerned though. How does everyone else feel?

Smart enumerations

This afternoon, my team leader checked with me that there really was no way of telling when the current iteration of a foreach loop is the last one. I confirmed the situation, and immediately thought, “Well, why isn’t there a way?” I know that you can’t tell without peeking ahead, but surely there’s a simple way of doing that in a general purpose fashion…

About 15 minutes later, SmartEnumerable<T> was born, or at least something with the same functionality. It chains whatever enumeration you give it (in the same way as a lot of the LINQ calls do) but adds extra information about whether this is the first and/or last element in the enumeration, and the notional index of the element. An example will probably make this clearer. Here’s some example code:

using System;
using System.Collections.Generic;

using MiscUtil.Collections;

class Example
{
    static void Main(string[] args)
    {
        List<string> list = new List<string>();
        list.Add("a");
        list.Add("b");
        list.Add("c");
        list.Add("d");
        list.Add("e");
        
        foreach (SmartEnumerable<string>.Entry entry in
                 new SmartEnumerable<string>(list))
        {
            Console.WriteLine ("{0,-7} {1} ({2}) {3}",
                               entry.IsLast  ? "Last ->" : "",
                               entry.Value,
                               entry.Index,
                               entry.IsFirst ? "<- First" : "");
        }
    }
}

The output is as follows:

        a (0) <- First
        b (1)
        c (2)
        d (3)
Last -> e (4)

I’m pretty pleased with that – but annoyed with myself for not thinking of doing it before. I’m pretty shocked that I haven’t seen it elsewhere; the code behind it is really straightforward. Anyway, it’s now part of my Miscellaneous Utilities library, so feel free to have at it.

Of course, if any of you cunning readers have seen the same thing elsewhere, feel free to indicate just how ignorant I am…

Visual Studio 2008 (Orcas) Beta 2 Released

Somehow I’d managed to miss this announcement, as had some other people on the C# newsgroup, so I thought it would be worth posting here too. Visual Studio 2008 (Orcas) beta 2 has been released, and it’s now feature complete, apparently. Finally I get to use automatic properties! This time I’m going to take the risk of installing it onto my home laptop “properly” as opposed to using a Virtual PC – after backing up, of course.

I’ve been downloading via the MSDN subscriptions file transfer manager, and have been getting a great transfer rate – better than the download sites listed below, so if you’re an MSDN subscriber, I’d try that way first.

Related links:

Overloading == to return a non-boolean

Were you aware that you could overload == to return types other than boolean? I certainly wasn’t until I started reading through the lifted operators part of the C# 2 specification. It’s quite bizarre – here it is in action:

using System;

class Test
{
    public static string operator== (Test t1, Test t2)
    {
        return "Fish?";
    }
    
    public static string operator!= (Test t1, Test t2)
    {
        return "Not a fish?";
    }

    static void Main()
    {
        Test a = new Test();
        Test b = new Test();
        Console.WriteLine (a==b);
    }
}

That ends up printing “Fish?” to the console. Strange but true. When I asked about this on the newsgroup, one poster said that he did use this functionality for an ORM type of system – his == operator on two expressions would return another expression which represented the test for equality between the other two expressions. I can’t say I much like this idea, although I could see where he was coming from. (The C# spec does specifically discourage this sort of thing, which is at least a start).

So, dear readers, have any of you done this, and if so, why?

Who do the “stars” look up to?

I follow a reasonable number of blogs. Not a vast number, but most of the ones I read (about computing, anyway) are written by people who are way out of my league. I mean, I can just about peer into the league of people like Simon Tatham who I’m proud to have as a friend even while I generally gape at his grasp of algorithms (verging on the obsessive at times, I have to say). Such people I regard as in a league above my own, and that’s fine – but then there are people like Don Box and Joe Duffy. If ever I’m tempted to start regarding myself as an “expert” in threading because some very kind people occasionally label me that way, all I need to do is think of Joe to come back to reality.

So my question is: who do these people look up to? Each other? I mean, I’m sure Don wouldn’t want to go head-to-head with Joe about detailed concurrency issues, and Joe probably wouldn’t try to bluff about web services around Don (which isn’t to say they couldn’t stimulate interesting discussion in each other’s area, of course). But there must be some recognition that they’re playing in the same league, just with slightly different equipment. Who do they regard with the sort of awe I have for them? Is there some uber-elite which us mere mortals don’t even hear about?

I think it’s healthy to be able to see people who are smarter than you. It can be a bit scary when you see just how wide the gap is (or at least appears to be) but it’s generally a good thing. The web has made this much easier – and simultaneously made it harder to be “big fish” because everyone gets to see how big the pond is.

If I get delusions of grandeur (well, more of them) I hope my friends will kick me back down to the right league. And if they don’t, I sincerely hope I’ll still be able to read the works of people like the ones listed above, and shrink back to Ronnie Corbert size again. Disclaimer: this doesn’t for one minute mean that I’ll avoid plugging my book like crazy when it’s nearer the release date.

Why hasn’t Microsoft bought JetBrains yet?

For those of you who aren’t aware, JetBrains is the company behind IntelliJ IDEA, the Java IDE which I’ve heard amazing things about (I’ve tried it a couple of times but never got into it – I think I need an expert sitting beside me to point out the cool stuff as I go) and ReSharper, the incredibly useful (although somewhat resource hungry) add-in to Visual Studio that turns it into a respectable IDE.

What would happen if Microsoft bought JetBrains?

I’m sure that killing off the reportedly best Java IDE would do .NET no harm (even if it would be a fairly cruel thing to do, and still leave other perfectly good IDEs in the Java space), and surely they could use the ideas and experience of the company to improve Visual Studio significantly. I strongly suspect that tighter integration could make all the ReSharper goodness available with less performance overhead, and while it’s no doubt too late now, wouldn’t it have been wonderful for all of those features to be available in Orcas?

Anyway, just a thought.

Implementing Ruby on .NET, and the importance of specifications

This morning, when following links to Jamie Cansdale’s ongoing tiff with Microsoft (best of luck, Jamie) I came across Martin Fowler’s concerns about Ruby on .NET. Most of the responses I’ve seen have – entirely reasonably – been about Microsoft’s relationship with open source and with the community as a whole. All of that is fine, but two points particularly caught my attention in Martin’s post:

Soon-to-be-ThoughtWorker Ola Bini, a JRuby committer, reckons that it’s almost impossible to figure out how to implement a Ruby runtime without looking at source code of the MRI – but Microsoft imposes drastic limitations on its employees’ ability to download open source software, let alone look at the source.

and

The overwhelming sense I heard in the community was not “Ruby will kill evil Microsoft” but “how can we overcome the problems to get Ruby on Microsoft.”

Now, as a disclaimer, I’ve done virtually no Ruby. I reviewed some early drafts of Ruby For Rails, and I’ve heard wonderful things about it from my ThoughtWorker friend Stuart, but I haven’t used it. As such, I certainly am in no position to judge it as a language in terms of elegance, power etc.

However, the first quote above raises a concern. My reading of it is that unless you look at the MRI, you don’t know how Ruby is meant to behave, and thus can’t implement it. Frankly, that puts me off the language a bit. I’m all for the agile idea of only documenting when it really adds a benefit, but surely specifying how a language is meant to behave is a real benefit. Now, I know there will always be kinks in languages where sane developers wouldn’t use the corner cases, but those developers who have used them really want them to work on every implementation, but I would hope those can be documented at the same time. Heck, there are plenty of details like that in C#, for instance.

This also answers the second quote I’ve included – what the community can do to overcome the problem of getting Ruby onto the .NET platform. If one of the main problems is that the team can’t look at the MRI source code, and currently the MRI source code is the only way of understanding how an implementation should behave, then surely changing the latter state of affairs would overcome the problem and help the rest of the community at the same time. Microsoft changing its interaction with the open source world would also overcome the problem, but in some ways that’s irrelevant – it in no way stops the community from writing a fully-fledged Ruby spec.

My concern when writing this is that this world is full of very smart people, and Martin’s obviously one of them, so I guess I’ve missed something. I’ve seen that there are some projects to specify Ruby’s behaviour, but if these projects are going well then that should make John Lam’s task more feasible, and if they aren’t then that would call into question either the Ruby community’s desire to see Ruby on .NET or its competence to actually get a spec together. Having watched a small part of the process of getting Groovy adequately specified, I know it’s a lot easier said than done, but even so…

So, what am I missing?

Writing is hard work: what I’ve been up to recently…

Just a brief note to explain what I’ve been up to recently (and why I’ve got about four fun blog posts which I haven’t had time to write up yet). I’m wildly pleased to say that I’m currently writing a C# book for Manning (the same folks who published Groovy in Action).

I can’t give any more details at the moment, but hopefully as we get closer to publication I can give more details about not just the content but the writing process and anything interesting I’ve discovered while writing it. (Heck, there’s never enough room for everything you might want to include in a book – there’ll no doubt be plenty of left-overs to go round :)

Anyway, it’s hard work but incredibly rewarding. 28 hour days would be really welcome right now, admittedly, but the buzz is fantastic.