• (cs) in reply to dubwai
    dubwai:
    wakeskate:
    dubwai:

    Java 1.5 improved a lot, and most of the critics aren't true anymore as you mentioned, but it also added other improvements (i.e. generic-types - a'la templates in C++) which C# doesn't have.



    C# version 2.0 has generics.

    I don't know why it says I wrote that because I did not.



    A bad edit of a quote, more than likely. It's just text, after all.
  • (cs) in reply to dubwai
    dubwai:

    But isn't that exactly what you are doing when you use an interface to import the constants?  At least with the static import there's a little visibility.  I can see how it would be bad in most situations but I think it's useful in a few special ones.


    No - I'd do it the same way whether I'd imported a class or an interface (or a static import, having thought about it just seems like a little bit of a hack to get round the multiple inheritence problems.. I shall have to look up the reasons for it) - I always use: InterfaceName.ConstantName or ClassName.ConstantName.

    I think it's always good practice to use the classname when referencing a static variable, just like I always use this.variableName when to distinguish from local variables (I know some people use the leading underscore.. but I
    just can't get to grips with that). Plus - it triggers the code insight (my goodness I'm getting lazy)...

    dubwai:

    As far as using constants for the column names, perhaps it's a WTF.  I like knowing that the name I call the SQL with will always be the same thing I retrieve the value with, guaranteed.  Maybe it's overkill.  I'm tend have a lot of what my gramar school teachers called "careless errors" so I do a lot of these things to save myself from myself.

    I can see it's nice for that - on the other hand, if a column name changes you could end up using a constant 'NAME' to refer to column 'FULLNAME' which could get nasty.

  • (cs) in reply to Buff

    Buff:
    I can see it's nice for that - on the other hand, if a column name changes you could end up using a constant 'NAME' to refer to column 'FULLNAME' which could get nasty.

    No I wouldn't leave it named incorrectly.  I would refactor it.  Even without an IDE, you can comment out the declaration, find all the uses of it and fix it.  If you just use a literal String, you have to search for the text which tends to be less reliable and less focused.  The point isn't that you never have change the rest of the code (I kind of suggested that, sorry), it's getting the compiler to catch my errors.

  • (cs) in reply to dubwai
    dubwai:
    I assume the C# does what Java does i.e. turn:

    String s = a + b + c;

    into the equivalent of:

    s = new StringBuffer(a).append(b).append(c);

    There is no benefit to doing this manually.  Even in the old versions of Java that used the String.concat() method, you need to concatenat at least 3 Strings before you see any benefit at all.  To see a noticeable benefit, you'd need to concatenat dozens.

    In the above, a, b, and c are non-literal Strings.


    However (getting back to the second half of the WTF), if they had  been assigned literal values, such as

    a = "This";
    b = "is";
    c = "a test.";

    ... then it is safe to assume that the compiler would perform constant folding on them in the case of concatenation; in fact, if a, b, and c are not reassigned elsewhere, and s is never reassigned, then compiler should eliminate the variables entirely and simply use the literal "This is a test." wherever there is a subsequent reference to s.

    In the case where only two of the values were constant, then if the constants are successive, such as in

    a =  Math.random();
    b = " is a ";
    c = "random number.";

    String s = a + b + c;

    Then it would (presumably) substitute the two literals and concatenate that to the non-literal:

    String s = a + " is a random number.";

    Only if all of the literals are disjoint, or all the values are non-literal, would it perform the whole series of cancatenations as written at runtime.

    On the other hand (as I understand it), by explicitly using a Stringbuffer and the append() method, the compiler doesn't get the option to do that; since it is a method invocation rather than a built-in operator expression, the compiler cannot assume that the result of the operations will be a constant, even when the arguments are constant (consider for a moment the case of a method that has a side effect such as printing to the console). This is true even though the compiler uses the same method internally for performing non-literal concatenation at runtime.

    (As an aside, constant folding is one of the reasons why arguments for functional programming: if the compiler knows that the result of a function will be fixed for a given constant argument, then it pre-compute the operation and substitute the function call with the constant result.)

    Comments and corrections welcome.

  • (cs) in reply to Schol-R-LEA
    Schol-R-LEA:
    However (getting back to the second half of the WTF), if they had  been assigned literal values, such as

    a = "This";
    b = "is";
    c = "a test.";

    ... then it is safe to assume that the compiler would perform constant folding on them in the case of concatenation; in fact, if a, b, and c are not reassigned elsewhere, and s is never reassigned, then compiler should eliminate the variables entirely and simply use the literal "This is a test." wherever there is a subsequent reference to s.

    While I agree that the above is possible, I'm not so sure you can count on this behavior.  The JLS states that literals must be concatenated at compile time.  I don't believe it requires compilers to analyze non-literals to determine if they never change.  (If a, b, and c are final, then I think it will concatenate at compile time but I'm not sure off the top of my head.)

    An aggressive optimizing compiler might be likely to do as you describe.

  • tom (unregistered)

    I showed my 7 month old son that, and even he started crying.  Perhaps he saw the tears in my eyes first, but I'm not so sure

  • (cs) in reply to KoFFiE

    What, dubwai?  You think that "VB programmers" have never heard of swapping the values of two things (usually memory locations or registers) using XOR?  Maybe some of them haven't, but some of us have.  Some of us used to write IBM System/390 assembler code, anyway.

  • (cs) in reply to DWalker
    To clarify, that was in response to dubwai's post:
     
    " int var1 = 10;
     int var2 = 123;
     // Swap them using XOR'ing :)
     var1 ^= var2;
     var2 ^= var1;
     var1 ^= var2;
    // Et voila - swapped them - that wasn't too hard now was it? :)

    VB coders are prolly scratching their head now - but well ..."

  • (cs) in reply to DWalker
    DWalker:
    To clarify, that was in response to dubwai's post:

    That wasn't my post.  Again.

  • (cs) in reply to wakeskate
    wakeskate:
    dubwai:

    Java 1.5 improved a lot, and most of the critics aren't true anymore as you mentioned, but it also added other improvements (i.e. generic-types - a'la templates in C++) which C# doesn't have.



    C# version 2.0 has generics.

    and anonymous methods as well. nullable types. And http://research.microsoft.com/comega/ has stuff going on that will be hard to reach by Java. then again, you never know when MS is going to use it.

    Still some delphi features I'm missing in C# though, like delegates by interface, and strictly typed types:

    http://www.netindustry.nl/blog/2005/04/wheres-in-c.html

    Wiebe

     

  • (cs) in reply to DWalker

    DWalker:
    What, dubwai?  You think that "VB programmers" have never heard of swapping the values of two things (usually memory locations or registers) using XOR?  Maybe some of them haven't, but some of us have.  Some of us used to write IBM System/390 assembler code, anyway.

    Where did it go wrong? [6][:#]

  • Craig (unregistered) in reply to jmo21
    jmo21:
    dubwai:

    Mad Hatter:
    I'm no StringBuffer() expert... could someone explain what is "wtf" about the second portion of the code?

    When you do this in Java:

    String s = "start" + "finish";

    It compiles into the equivalent of:

    String s = "startfinish";

    In other words, the + doesn't do anything at runtime.  This is true for any literal (constant, etc.) that can be determined at compile time.

    By forcing the StringBuffer concatenation, you force this concatenation to happen at runtime.  So not only is the code harder to read, it's slower.

    The other thing is that in any version of Java > 1.3, + for no-literals will compile into the equivalent of the StringBuffer append (or StringBuilder in 1.5) version anyway.

    You should only use StringBuffer when you are repeatedly adding Strings to each other in a loop or similar operation where the entire concatenation can't happen at once.

    Don't know about Java, but in .Net the String object is immutable which means anytime you try to add to it, behind the scenes, an extra copy of the object is created - and the original value and the new part are then added to the new object

    not such a big deal with a simple couple of concatenations, but when u have some repetitive load of concats, it is more sensible to use a StringBuilder object, (and its Append method) which is not immutable (mutable?? :) - u dont get lots of extra objects being created - hence conserves memory.

     

    .NET does the same thing as java, in that it performs the concatenation at compile time instead of at runtime when possible, i.e. when the strings are literals or constants as opposed to, say, return values from method calls.

  • noobguy (unregistered) in reply to Charles Nadolski

    why this wasnt put into a stored procedure in the first place....?

  • ehdv (unregistered)

    According to a recent article I read (I wish I could find the link, but it was an interview with some Java expert), using the plus sign isn't actually that bad, since Java 1.6 now uses the StringBuilder class automatically. The article said that doing it the semantically right way was best in the long run because future implementation changes wouldn't leave your code behind.

Leave a comment on “When Good Practices Go Bad ”

Log In or post as a guest

Replying to comment #:

« Return to Article