Useless programming language constructs

Ok, I'm back! :) After a long period of extensive programming (AKA 'Crunch mode'), the pressure is finally gone. Everybody who has released a big software product knows that releasing it is one, but the period after the initial release is as important as the release itself: early adopters who find odd bugs in weird circumstances no beta-tester has thought about testing nor did yourself thought it would be possible etc. But that's for another story to tell later :)

Today, I want to discuss a small set of, In My Humble Opinion, useless programming language constructs. I find them useless because they do not serve a purpose at all, however you can't leave them out because doing so will result in non-compilable code. I ran into these when porting C# code to VB.NET or during C# development.

  • break in case blocks.(C#). In C# you have to add a 'break;' statement after each statement group you define as the 'case' block. This is because you can't have 'fall through' in C# in switch/case statements. Example:
    switch(foo)
    {
       case 1:
          // some statements [A]
       case 2:
          // some statements [B]
    }
    'case 1:' will stop at the end of [A], because C# doesn't support fall through. However, you still have to specify 'break;' at the end of [A], because you can't fall through, but that is not supported anyway! So specifying break or not doesn't matter, the end result will be the same. Also, you have to specify 'break;' at the end of [B], even though it is the last case block in the switch.
  • Overloads when Overrides (VB.NET). VB.NET has many odd constructs, but one of the most weird ones is the obligation to specify 'Overloads' when you override a method with 'Overrides', even when the overridden method is abstract! Isn't it so that when you override a method, there is always another version of it, so overriding a method is also overloading the original. You can't leave Overloads out of the definition, even when the overridden method is abstract, which is weird, because abstract methods are not executable, the implementation of the abstract method is not an overriding method (however you have to specify Overrides), it is the implementation of the method.
  • WithEvents with form controls (VB.NET). When you are writing VB.NET without Visual Studio.NET (for example when you port C# code to VB.NET, you suddenly feel the power of the Visual Studio.NET editors: you leave out statements that are automatically added by these editors. One thing that I find weird in VB.NET and which is solved automatically by the VB.NET editor is the obligation to explicitly define 'WithEvents' with a control when you want to implement an event handler. So for example you have a button on a form, and when you leave out the 'WithEvents', you can't define an event-handler. However, what's the use of a button without events, besides a nice thingy on a form? Isn't it so that when a control exposes events you always should be able to define event handlers for these events, without having to rely on 'WithEvents' ?
  • ReadOnly with properties with only a 'Get' (VB.NET). This statement falls in the same category as the C# switch-case-break statement. When you leave out ReadOnly, it will not compile. When you specify a Set, plus ReadOnly, it will not compile. Isn't it obvious that when there is just a Get and no Set, the property is ReadOnly? Why a statement to explicitly define it ReadOnly, as if there is another way to define it.

Ok that's it for now, I'm sure C# and VB.NET have more of these language constructs which make you wonder why they're there in the first place. If you know more, post them in the comments :)

12 Comments

  • This is a case where you wouldn't use a break after every case if statements 1 and 2 have the same output.



    for(int i = 0; i < 10; i++)

    {

    switch(i)

    {

    case 1:

    case 2:

    case 7:

    Console.WriteLine("Hello {0}!", i);

    break;

    }

    }

    Console.Read();

  • But you also have to remember that there are more options than just break (as well as the ability to specify multiple cases:



    int i = 3;

    switch(i)

    {

    case 1:

    Console.WriteLine("ONE");

    break;

    case 2:

    Console.WriteLine("TWO");

    break;

    case 3:

    Console.WriteLine("Three alone");

    goto case 4;

    case 4:

    case 5:

    Console.WriteLine("3,4,or 5");

    break;



    }

  • Multiple cases are indeed without 'break' but they share the same code block, I was refering to case statements which do have a separate code block and thus have to have a break statement too



    The necessity to specify goto is the sign that the limitation of 'not having fall through' is wrong. If they just remove that limitation, it would be much better: you should specify break when you do not want fall through (and you already do so now) and you don't have to mess with goto crap when you want fall through.

  • You're not 100% correct on the second issue (WithEvents in VB.NET). When you said:



    "when you leave out the 'WithEvents', you can't define an event-handler."



    That's not totally correct. You can define an event-handler, you just can't automatically wire it up with the "handles" statement. Instead, you must use the AddHandler statement.



    So your choices are:



    private withevents x as Button

    and

    public sub eventhandler(...) Handles x.Click



    -- OR --



    private x as Button

    AddHandler x.Click, AddressOf eventhandler

  • Ah, thanks Patrick :) I should have said 'can't define an event handler with visual studio.net'.

  • I atcually think the ReadOnly/WriteOnly thing for properties is a Good Thing. It lets the compiler tell you "You wrote a property with just a Get or just a Set. Are you really sure you want to do that, or did you just forget?"

  • One reason you have to eplixitly specify a break in c# is because _a lot_ subtle coding errors in C and C++ come from the fact that you forget to say "break". This way you have to clearly state your intentions.

  • The mandatory overrides is IMHO good. Imagine you subclass a class and define new virtual method on it. Vendor of the subclassed class would eventually distribute new version, which has this method defined too. Than the compiler would scream, that you're trying to define new virtual method (virtual keyword) when you maybe want to do override.

    This way you know, that you're doing something, that you're maybe not supposed to do (new vs. override keyword)

  • Jakub: it's not the overrides, it's the overLOADS which is bogus. :) Overrides automatically implicitely says there is another method THUS it also overloads.

  • The break is necessary because many people would be expecting the fall through. To ignore past languages is to ignore present assumptions. Also it has been a rich area for bugs that is solved by being more explicit. The goto's are more explicit as well, explicit enough that you can insert/reorder things without breaking your code. Logic based on order of appearance is pretty fragile imo.



    So I'm happy with the break, the lack of fall throughs, and the resulting compiler errors you get when you don't specifically say what you want...

  • the only real useless programming language in existance is turing, although my lack luster teacher insists we will go "places" with it... the only place i think im headed with turing under my belt is the slums

  • Never have I been more disgusted with a programming languages. And I am certified teaching person.

Comments have been disabled for this content.