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:
procedure Foo(aObject: TObject); begin case aObject.ClassType of TEdit: TMemo: TLabel: else //... end; end;
or
procedure Foo(aObject: TObject); begin case aObject of myEdit: myMemo: myLabel: else //... end; end;
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.
Your task?
Easy! Vote & Comment!
“In short, I propose to enhance the actual ‘Case’ structure to support every entity which has the = (equal) operator defined.”
OOOHHH YES ! This is really a pain to stay with Ordinal type !!!
Is this so hard to enhance ?
@ Is this so hard to enhance ?
I think it is against it’s intended purpose:
Making us programmers insane!
😉
Making us programmers insane!
Hmmm…. so in this way one can explain what’s happening in the .public.non-technical…
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.
Just let them do this damn 64 bit compiler and cros paltform thing…;)
“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…;)”
…hehehe…
“Strings would be slow;”
Not exactly. Will be faster compared with what we have now. (they can have sorted lists, hashes etc. – all generated at compile time) to optimize the search speed at RTM.
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!
I would like to see
case String of
‘Peter’:;
‘Paul’:;
end;
What about Mary?
Ah, yes. Mary Travers. May she rest in peace.
Since string supports the ‘=’ operator, your apostles are in. 🙂
You can use string case in FreePascal now.
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.
Yes, depending on how the
case
will look like there can be applied different optimizations: hashes, sorted lookup lists or the bare-bone fast implementation as is today.…but yes, the #1 is to have clean code. After this, if they can optimize it, so far so good.
Zarko and I both talked about case with string and some of the performance issues involved. You can read Zarko’s implementation here and several variations and performance numbers here
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.Makes sense, register a QC item.
Sure. Together with the poll’s results, I’ll put also the link.
I agree. Case should work for everything.
Then technically, as others have commented, it can replace IF-THEN-ELSE IF-…
c# has case with (gasp) strings!
Hmmm…. are you sure??? ::g::
I think that’s the other way around: Delphi is (almost) the single language which doesn’t have case with strings!
And, yes, (gasp)!
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.
http://www.google.com/url?url=http://groups.google.se/g/c307fefb/t/d186682bbe6cbe71/d/58d39ea2df36b2f8%3Fhl%3Dsv%26ie%3DUTF-8%26q%3Ddelphi%2Bcase%2Bstrings%2Bauthor:isaksson%2358d39ea2df36b2f8&ei=4Cf4Sr_QGoiqQJuN_Es&sa=t&ct=res&cd=1&source=groups&usg=AFQjCNEFH_2smm4So-5ftjXWFusQxRylHQ
or
http://tinyurl.com/yz7qz95
Well, if you want to convince people to vote for it I suggest you change both examples.
Both are perfect examples why people should NOT use a “case” statement in an OOP language.