Language Envy - episode 0
Although C# is the language that I can call myself proficient enough to make a living these days, there are other languages that I have to use for specific tasks (like JavaScript, SQL, XSLT.) I also like using other general purpose languages for pure exploration or pet projects. I'd include Ruby, ObjectiveC and PHP in this group.
When using other languages it often happens that I encounter features that I wish C# had or that the C#-equivalent was as easy (it works both ways — I miss some C# feature on the other side as well.)
In this series of undetermined length I will be posting some of the items from my wish list as I remember them.
The case statement
To start things off, let's check out C#'s case statement, straight from the language specification.
switch-statement:
switch ( expression ) switch-block
switch-block:
{ switch-sectionsopt }
switch-sections:
switch-section
switch-sections switch-section
switch-section:
switch-labels statement-list
switch-labels:
switch-label
switch-labels switch-label
switch-label:
case constant-expression : // <-- line 14
default :
I know that doesn't look like C# code. What I'd like to point is in line 14. The
expression in each case label has to be a constant. I'm sure that helps
making the switch statement compile to a very efficient MSIL code, but
let's consider what we are missing because of that.
Here's a sample of what you can do in a Ruby case expression.
Months = %w(JAN FEB MAR APR MAY\
JUN JUL AGO SEP OCT NOV DEC)
def get_month(value)
case value
when Date # class name (instance of?)
return Months[value.month - 1]
when /\d{4}-(\d{2})-\d{2}/ # Regular expression (matches ?)
return Months[$1.to_i - 1]
when 1..12 # Range of values (contained ?)
return Months[value - 1]
end
end
puts get_month(Date.today)
puts get_month("2008-10-20")
puts get_month(8)
As you can hopefully see in the above example, the expressions in
each when statement do not need to be constants
(class names like Date are constants, by the way)
Ruby defines the === (triple equal) comparison operator
that can be overriden in each class and is used in the case
expression to test each when condition. This is usually read
as "when value matches with this expression here...".
Not surprisingly, the built-in classes in Ruby do override the triple
equal operator to add a more meaningful implementation for it.
Range matches the values that are within the range. RegExp matches
values that agree with the regular expression, Class objects
match values that are instances of that class, etc.
I use this feature all the time and it's so convenient that I'd be thrilled to see it in C# one day.
So, what is my suggestion?
I wouldn't be a real programmer if I didn't try to sell my own suggestion, would I? Since
IComparable is taken and means something different, I was thinking of maybe
something like this.
public interface ICanMatch