…On the Wings of the Software Wind

Main menu

Post navigation

The Anti-Case campaign

Some time ago, Nick and Malcolm drew our attention on a site which promote an anti-if campaign. Well, I don’t know how much that campaign is interesting for us, because, sincerely, I don’t see any time soon the if construction removed from programming languages.

But I will propose another campaign which I think is much more stringent for Delphi developers… It is anti Case campaign. And to be very clear, is against Case structure in the form in which is implemented now.

The idea struck when, having my previous experience with Class Signatures, I saw Jolyon’s post about using of absolute keyword. The first reaction was “Hey, my solution is better than this (safer – checks at compile time, much clearer code etc.) but it is a language improvement (requires support from the compiler)”. But because for us, mere mortals, this isn’t so easy to get, I tried to make Jolyon’s code cleaner. I was very frustrated (again) because in a perfect world, one should just write:

In fact there are integers, no? (An ‘ordinal’ type…)
…and of course, let us just skip over the advantages of the above code compared with the spaghetti code generated by the if approach.

Pushing things further, case, even if its very fast, nowadays is quite limited for the programming needs of a programmer in the winter of 2009 (yeah, I’m looking a little bit forward, but just a little, you know).

No strings, no objects, no classes. No floating-point, no records, no variants. No interfaces, no custom types, no nothing. Did I miss something?

In short, I propose to enhance the actual ‘Case’ structure to support every entity which has the = (equal) operator defined.

Ah, this is a common problem. Case supports integers. As with any abstraction, the convenience offered means the programmer no longer has a feel for performance cost.

Strings would be slow; altho’ I’m sure I have seen a “workaround” – perhaps on Zarko’s About blog?

Classes, Objects – the pointer/reference should be castable, but is that what the programmer expects?

Basically, each type would need background handling by the compiler; something you would automatically do in an IF statement.

But perhaps this could be opened up for the programmer to configure – something along the line of each case being lambda expression returning an integer? In essence, an if-elsif-else, but in case syntax?

There was a workaround for this but it allowed only case on strings. Don’t remember now where I saw it, wasn’t it on the Andreas Hausladen page?
Anyway, in my oppinion it is another thing that everyone wants but how much people actually will be using it?

Do you really need a case on a class or on an instance of object?

For me it is quite sufficient to make 3 if’s depending on an object type. I’ve never needed any more in my practice.

“There was a workaround for this but it allowed only case on strings.”
In fact there were two or tree. But all of these had drawbacks (naturally). The closest to perfection was (perhaps) Andreas Hausladen’s one which required a preprocessor.

“Just let them do this damn 64 bit compiler and cros paltform thing…;)”

Yes! Yes! YES! This is one of the things about modern Delphi that just seems like a pure craziness to me – ordinal types only? Compile ordinal case checks just like before – optimized for performance, and the rest just like if…else if…else if… for all I care, but allow them!

This is a very good suggestion! But I think the implementation should use something like hashes (also for strings). So you can efficiently implement case statements: you could have lookup tables when there are many choices for example.

In general (not limited to case-statements):
If you have code constructs which are inherently difficult to optimize or are potentially bad performing we could add compiler hints that tell us this.

=>
You can focus on writing clean code, without always worrying about performance.
Then in really critical code sections you could turn on these hints are rewrite these parts if necessary. Using a profiler would help in finding those places.

If performance isn’t crucial: clean and easy to read code is what you get.

But having such an extended case statement is actually even *better* for performance. When do you really take the time to optimize nested if-constructs?

Summary:
– focus on intent vs. implementation to write clean and understandable code.
– use clever optimization (which can benefit from higher-level descriptions, e.g. case instead of nested ifs,), give tools such as compiler hints where optimizations are difficult to implement or impossible without a full program analysis.

Yeah, knew it. Anyway, thanks for the link. It is one of the best workarounds given the actual situation. But it lacks of flexibility and readability compared with an official solution of course especially if the case list contains enough code to spawn more than one screen (yes, it happens sometimes). FTR, is what we use in our programs. Also, your approach can be extended using generics. Basically you can have a generic function IndexOf which will scans the array of the given type and returns the index of the sought element.

I agree that it’s time to expand the capabilities of ‘case’. Go for it!

The ‘case with strings’ has been discussed many times on the Borland newsgroups. I have used a sorted TStringList with good effect, although you really need an enumeration for the case labels too, to be able to read the program.