• RvW (unregistered) in reply to Mason Wheeler
    Mason Wheeler:
    Slim Dave:
    Also, "(0 < count)" ... is that irritating to anyone else? "(count > 0)" seems a lot more intuitive to me.

    Standard Yoda Conditional for you. The people who invented C had more marketing skill than technical competence, and they made a compiler that thinks anything can be a boolean and called it a "feature." And now all the descendant languages are stuck with it and all the ugly syntax that it spawned, such as writing conditionals backwards.

    What are you talking about? Even if you have a problem with "0 < count", how is that related to marketing skill and the anything-can-be-a-boolean feature?

    In mathematics you can just write "0 <= index < size". In most programming languages you can't (or, if you can, it doesn't mean what you had in mind). So you have to think of something else. In my opinion, the following code seems perfectly fine:

    if ( ( 0 <= index ) && ( index < size ) ) { // do something with array[index] } else { // throw an index-out-of-bounds exception }

    Granted, the example was about count, but unless you want to tell the compiler it should treat constructs involving variable "count" differently from variable "index", based on the name alone, what can the language definition do?

  • (cs) in reply to wtf
    wtf:
    The Web is the Root of All Info:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    Or you commute is that unpredictable.

    My commute? 20 min. if you hit every green light along the way, 90 min. if everyone else decided to commute at the exact same time as you.

    Hmm. My commute is about two chapters of a typical science fiction novel. I love public transit!

    My commute? Minute and a half. Unless I decide to walk, then it's about 4

  • Kevin (unregistered) in reply to EngleBart
    EngleBart:
    If the database was properly normalized with cascading updates/deletes, then you should only have to check the primary widget table.

    Failure to exist in the widget table should indicate failure to exist in the entire DB!

    Of course, from the code seen here, this developer may have still messed it up.

    This is also wrong.

    10:58 a.m. Sally checks for next available WIDGET_ID. Finds WIDGET_ID=6 is available. 10:59 a.m. Sally adds WIDGET_ID=6 to the primary table, sees the time, and runs out for a lunch date (forgets to click "save" button). 11:02 a.m. Tim is running late for a lunch date with Sally, but can't leave until he adds his WIDGET. The application determines WIDGET_ID = 6 is available. 11:03 a.m. Tim tries to add WIDGET_ID = 6 to the primary WIDGET table. The application hangs. For 25 minutes. Tim becomes angry, as he is missing his lunch date with Sally. After 10 minutes, he calls IT, and berates them every 5 minutes as they investigate. 11:30 p.m. Sally gets back from lunch, annoyed at having been stood up.
    11:31 p.m. Sally calls Tim and tells him to go !@#$ himself. After hanging up, she sees that she'd forgetten to save her work, and clicks "save". 11:32 p.m. Tim's application finally unfreezes, and he gets an unhandled application error, some voodoo nonsense about a UNIQUE KEY CONSTRAINT VIOLATION. 11:33 p.m. DBA investigator sees there are suddenly no locks, calls Tim and happliy tells him that the performance issue has been resolved, and inquires, "are you still having a problem?". Tim is not in the best of moods for that question, hangs up, and calls company VP to ask how it is that after a $1 million hardware upgrade, it still takes 25 minutes to add a !@#$ing widget.

  • eric76 (unregistered)

    This must be the software version of "If at first you don't succeed, try, try again."

  • LB (unregistered) in reply to EngleBart
    EngleBart:
    boolean answer = f(); if (answer = true)

    would still suffer from the same problem, assign true to answer and then evaluate to true.

    Of course, with booleans, I always think the comparison operator is unnecessary.

    if (answer == true) can be changed to if (answer) if (answer == false) can be changed to if (!answer)

    You're assuming one side of a comparison is always a literal. How about:

    boolean answerA = funcA(); boolean answerB = funcB(); if (answerA = answerB) ...

  • by (unregistered) in reply to campkev
    campkev:
    wtf:
    The Web is the Root of All Info:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    Or you commute is that unpredictable.

    My commute? 20 min. if you hit every green light along the way, 90 min. if everyone else decided to commute at the exact same time as you.

    Hmm. My commute is about two chapters of a typical science fiction novel. I love public transit!

    My commute? Minute and a half. Unless I decide to walk, then it's about 4

    So...are you this guy?

    If not, I call BS.

  • Tharg (unregistered)

    So many WTF's, I almost abandon hope upon entering here. So, with loins girded, to battle:-

    The first WTF is that someone allowed code to be written and promoted to production without a code review. The legacy code may have been outsourced to umbo-gumbo-land, but that's no excuse for allowing such tat into production. No competent reviewer would ever allow this to pass.

    Why did the compay employing the outsourcers permit this to occur? Sheer incompetence springs to mind, but ah, that is supposition. No matter what, this is manifest incompetence by the developer and his superiors, and his superiors employers.

    As for the RDBMS that worked slower with stored procedures, I can assure the gentle reader that it wasn't Oracle. The big O features such unheard of high-tech wizardry as a cache. This breakthrough in computing science will come as a shock to many of our readers. In essence it saves repeated disk access by storing the latest and most used data in memory. A smart arse alogrithm ages the old stuff out of memory without user intervention. I may be shooting from the hip, but I believe that this sort of wizardry has been available since oh, around 1975.

    Finally, I call bullshit on the Java boyos and their "I can do it quicker" routine. Lets see some posted code, sample data, and verifiable timing tests. Put up or shut up!

  • Mike (unregistered) in reply to Someone You Know
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

  • Jellineck (unregistered) in reply to Mike
    Mike:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

    Actually, they need to find jobs closer to their homes.

  • Fahrenheit 451 (unregistered) in reply to Mike
    Mike:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

    Trust me, I understand how it can be really nice when you can do this, but either of the following complicate things:

    • Owning a house
    • A spouse that works 3 hours in the other direction.

    I made the same arguments as you in 2005; but back then, houses were flying off the shelves and the average unemployment period was much less than 30 weeks.

    Thank you Obama.

  • Brompot (unregistered) in reply to tiller
    tiller:
    Slim Dave:
    If all you want to do is checkj for the existence of at least on occurrence of a value in a table then you'd usually do well to do something like (in Oracle):
    select
      count(*)
    from
      my_table
    where
      my_column = :my_bind and
      rownum = 1

    Could save you do all the work to count the other ten million rows that you don't care about.

    Also, "(0 < count)" ... is that irritating to anyone else? "(count > 0)" seems a lot more intuitive to me.

    Doing it that way may have really bad performance on some databases if you use transactions, because then count(*) is not a simple operation. (You can't just return the number of rows because an other transaction may have a lock on some of them and thus delete them (This prevent the database from just returning the number of rows)).

    So I think that doing a select with limit 1 and then testing for an empty result is a better solution.

    In Oracle you would properly implement the referential integrity and then catch the exeception when you attempt to delete the parent.

    Captcha: Ingenium. Yes I am.

  • David Hamilton (unregistered) in reply to Tharg
    Tharg:
    As for the RDBMS that worked slower with stored procedures, I can assure the gentle reader that it wasn't Oracle. The big O features such unheard of high-tech wizardry as a cache. This breakthrough in computing science will come as a shock to many of our readers. In essence it saves repeated disk access by storing the latest and most used data in memory. A smart arse alogrithm ages the old stuff out of memory without user intervention. I may be shooting from the hip, but I believe that this sort of wizardry has been available since oh, around 1975.

    Finally, I call bullshit on the Java boyos and their "I can do it quicker" routine. Lets see some posted code, sample data, and verifiable timing tests. Put up or shut up!

    Yep, exactly. Caching. So data (the correct data set) cached in the web server will always be faster than getting it from the DB. Unless, of course, Oracle have added a web server to their DBMS (it is a logical step, as they've added almost everything else!)

    All performance computing is based on caching, and yet standard webapp implementation forget that and routinely throw away all the data between requests and load it all from scratch for the next...

    As to your assertion that those Stored Procedures couldn't possibly be running on Oracle... well, all I'm going to say is that I'm fascinated to know how you can assert that ;)

  • Tharg (unregistered)

    SP's may or may not be silver bullets (or should that be bullshit?) however, your link merely demonstrates that no matter how good the programming language, it can always be royally screwed up by a developer.

    However, it also exemplifies my original point. Do you for one minute think that such a "stored procedure" would pass a code review? I shudder to imagine the sheer carnage wrought by your linked example.

  • The Nerve (unregistered) in reply to Tharg
    Tharg:
    SP's may or may not be silver bullets (or should that be bullshit?) however, your link merely demonstrates that no matter how good the programming language, it can always be royally screwed up by a developer.

    However, it also exemplifies my original point. Do you for one minute think that such a "stored procedure" would pass a code review? I shudder to imagine the sheer carnage wrought by your linked example.

    I have not yet been able to find a job in the Ivory Tower. I don't think they've found a way to make a profit.

    I worked at a place before that did no code reviews and with competent developers produced WTFs on a non-regular basis. I worked at a place that did code reviews, and it was quickly discovered what person you wanted to do your code review. Plus, managers and higher always trump any process set in place.

    Now, if you've been working a while, you may have seen the kind of code-sweat shop that produced "the beast." This from the country that brought you <a rel="nofollow" href="http://thisisjuststupid.com/wordpress/wp-content/uploads/image/india%20wiring1.jpg"" target="_blank" title="http://thisisjuststupid.com/wordpress/wp-content/uploads/image/india%20wiring1.jpg"">wiring like this. You may have discovered that while this country may produce competent coders, scientists, professors, engineers, the ones who don't make it stay home and find jobs by under-bidding their competitors and brute-forcing solutions. And they don't do code reviews or unit tests.

  • (cs) in reply to luis.espinal
    luis.espinal:
    Anonymous:
    Does Java still not support the "using" pattern for disposable objects? I'm no fan of pointless syntactic sugar but this pattern would be a useful addition to the language. I like Java a lot but in all honesty I'm grateful to be working on .NET these days.

    I'm a fan of strategically used syntactic sugar, but the "using" keyword/clause could possibly do more harm than good in this particular context. The reason is that an idiot/incompetent programmer will still be an idiot/incompetent one with or without it.

    Let's look at some of the original codesod:

    rs = connection.createStatement().executeQuery(query);

    It is not only the creation of a java.sql.Connection object, but the creation of a great many number of java.sql.Statement (we only need one) and many java.sql.ResultSet objects, with none of them being cleared, re-used or closed.

    Imagine the dumbass who wrote that code being equipped with a Java equivalent of "using". Assuming his pineapple-level IQ gets him to realize "shit, I need to close them thingies", wrapping everything in "using" clauses, we would have:

    1. Even more redundant, unreadable, obfuscated code, and
    2. Would not compensate for the dumbass' inability to understand basal things like object indefinite lifetimes in Java or the fundamental fact that resources have cost and are limited.

    Adding "dispose pattern" syntactic sugar will not help here because the problem is deep, systemic and systematic. Syntactic sugar is like neosporing, and dumbass programmers are like skin cancer. You can't use the former to effectively treat the later.

    The problem isn't as bad as you think.... All of the unclosed java.sql.Statement and java.sql.ResultSet objects are only taking extra memory, they'll be garbage collected when they become a problem. It's certainly not good programming, but it doesn't cause a lot of problems. Unclosed java.sql.Connection objects are a really big problem because there are a lot of other resources being consumed -- connections are being taken from the connection pool and not being returned and many additional connections are being made to the database server. Many database servers have a hard time with even a few hundred connections, even if they aren't currently being used.

    In C#, you can't simply throw using where ever you want to, it can only be used to clean up an object that implements IDisposable. Only objects that consume resources outside the VM typically implement IDisposable. So, you won't end up with a huge clutter of using blocks, they will only end up where they are useful, even if the developer is a moron.

    Using is also good for newbies because it forces them to declare-use-destroy in the same procedure. Really atrocious things like global connections become very difficult to create.

  • Rob (unregistered) in reply to Henning Makholm
    Henning Makholm:
    It is an if statement written using the for statement.

    It's not even an if statement then - there's no branch. It's just a statement. They could have done this:

    rs = connection.createStatement().executeQuery(query);
    rs.next();
    count = rs.getInt(1);
    if (0 < count) return false;
    

    There was no need for the loop at all. The whole function is full of WTFery.

  • (cs) in reply to Tharg
    Tharg:
    So many WTF's, I almost abandon hope upon entering here. So, with loins girded, to battle:-

    The first WTF is that someone allowed code to be written and promoted to production without a code review. The legacy code may have been outsourced to umbo-gumbo-land, but that's no excuse for allowing such tat into production. No competent reviewer would ever allow this to pass.

    Why did the compay employing the outsourcers permit this to occur? Sheer incompetence springs to mind, but ah, that is supposition. No matter what, this is manifest incompetence by the developer and his superiors, and his superiors employers.

    As for the RDBMS that worked slower with stored procedures, I can assure the gentle reader that it wasn't Oracle. The big O features such unheard of high-tech wizardry as a cache. This breakthrough in computing science will come as a shock to many of our readers. In essence it saves repeated disk access by storing the latest and most used data in memory. A smart arse alogrithm ages the old stuff out of memory without user intervention. I may be shooting from the hip, but I believe that this sort of wizardry has been available since oh, around 1975.

    Finally, I call bullshit on the Java boyos and their "I can do it quicker" routine. Lets see some posted code, sample data, and verifiable timing tests. Put up or shut up!

    We can't do it quicker. The fastest implementation of any given algorithm that involves data access will likely be the implementation run closest to the data.

    However.... absolute speed isn't everything. For example, if I move the implementation to a web server, then it's much easier to throw 100 web servers at a problem than it is to divide the data among 100 database servers. Also, for 99% of problems, speed of execution doesn't trump all other concerns. High-performance stored procedures tend to cause code repetition. This is because intermediate abstractions make code slower. However, the removal of intermediate abstractions cause code to be harder to maintain.

    Im my opinion, stored procedures should be used as exceptions when performance needs demand them. All uses should be documented, along with the reason. Before anybody accuses me of advocating SQL spread throughout an entire application, I also feel that any data access code found outside the data access layer should be cause for public flogging.

  • Darth One-Joke (unregistered) in reply to eric76
    eric76:
    This must be the software version of "If at first you don't succeed, try, try again."

    while (!(success = try()));

  • JavaSmartA** (unregistered) in reply to Darth One-Joke
    Darth One-Joke:
    eric76:
    This must be the software version of "If at first you don't succeed, try, try again."

    while (!(success = try { try {}}));

    FTFY - Runs much faster

  • RvW (unregistered) in reply to Rob
    Rob:
    They could have done this:
    rs = connection.createStatement().executeQuery(query);
    rs.next();
    count = rs.getInt(1);
    if (0 < count) return false;
    

    Any particular reason to not just use

    rs = connection.createStatement().executeQuery(query);
    rs.next();
    if (0 < rs.getInt(1)) return false;
    
  • Darth One-Joke (unregistered) in reply to JavaSmartA**
    JavaSmartA**:
    Darth One-Joke:
    eric76:
    This must be the software version of "If at first you don't succeed, try, try again."

    while (!(success = try { try {}}));

    FTFY - Runs much faster

    True, but not in C ;)

  • CmartA** (unregistered) in reply to Darth One-Joke
    Darth One-Joke:
    JavaSmartA**:
    Darth One-Joke:
    eric76:
    This must be the software version of "If at first you don't succeed, try, try again."

    while (!(success = try { try {}}));

    FTFY - Runs much faster

    True, but not in C ;)

    #ifndef try #define try #endif

  • Sutherlands (unregistered) in reply to EngleBart
    EngleBart:
    I am pretty sure that James G. would never write if (answer == true) over if (answer) and probably did not even consider it when designing Java.
    The sad part is that the company I worked for previously - my second manager required that. So you can't do: if(componentIsReady) if(varIsInitialized) while(!finished)

    you had to do: if(componentIsReady == true) if(varIsInitialized == true) while(finished == false) { or while(finished != true) }

    Also, with ors and ands...

    if(componentIsReady == true && varIsInitialized == true && finished == false)

  • Anon (unregistered) in reply to Fahrenheit 451
    Fahrenheit 451:
    Mike:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

    Trust me, I understand how it can be really nice when you can do this, but either of the following complicate things:

    • Owning a house
    • A spouse that works 3 hours in the other direction.

    I made the same arguments as you in 2005; but back then, houses were flying off the shelves and the average unemployment period was much less than 30 weeks.

    Thank you GW Bush.

    FTFY, because you apparently aren't very good at remembering when the current crisis started. Unless you are suggesting Obama is a time-traveler in addition to being a Nigerian Muslim Marxist.

  • suscipere (unregistered) in reply to Anon
    Anon:
    Fahrenheit 451:
    Mike:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

    Trust me, I understand how it can be really nice when you can do this, but either of the following complicate things:

    • Owning a house
    • A spouse that works 3 hours in the other direction.

    I made the same arguments as you in 2005; but back then, houses were flying off the shelves and the average unemployment period was much less than 30 weeks.

    Thank you GW Bush.

    FTFY, because you apparently aren't very good at remembering when the current crisis started. Unless you are suggesting Obama is a time-traveler in addition to being a Nigerian Muslim Marxist.

    With a name like O'Bama, I figured he was Irish. Any relation to Irish Girl?

  • (cs) in reply to Mike
    Mike:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

    I know people like that. Sometimes they use public transportation, which does cut some time, but they should ultimately move closer. However, the worst kind of complainers are those that live near the new Suburban Railway which shaves off about 2 hours of heavy traffic... and still insist on using their damn stupid car.

    Oh, this is in Mexico City, where 30 minutes would be a short commute. This is partly thanks to NIMBYs in the metro area blocking any significant commuter rail projects.

  • (cs) in reply to RvW
    RvW:
    Mason Wheeler:
    Slim Dave:
    Also, "(0 < count)" ... is that irritating to anyone else? "(count > 0)" seems a lot more intuitive to me.

    Standard Yoda Conditional for you. The people who invented C had more marketing skill than technical competence, and they made a compiler that thinks anything can be a boolean and called it a "feature." And now all the descendant languages are stuck with it and all the ugly syntax that it spawned, such as writing conditionals backwards.

    What are you talking about? Even if you have a problem with "0 < count", how is that related to marketing skill and the anything-can-be-a-boolean feature?

    What I meant by that is that they took a hacked-up language designed for writing quick and dirty operating systems--back when operating systems were kilobytes in size, not gigabytes--which was designed as basically a smiley face painted over assembly and is completely unsuitable for doing large-scale work, and managed to market it successfully enough that it became rather widespread. Widespread enough that it's spawned an entire family of C-based languages which copied large chunks of C's grammar to make them easier for people familiar with the C family to pick up, and brought lots of C's flaws along with it. (For example, just look at how many of C++'s more horrific misfeatures aren't inherent flaws in what the language was trying to do, but in trying to do it C-style.)

    In mathematics you can just write "0 <= index < size". In most programming languages you can't (or, if you can, it doesn't mean what you had in mind). So you have to think of something else. In my opinion, the following code seems perfectly fine:

    if ( ( 0 <= index ) && ( index < size ) ) { // do something with array[index] } else { // throw an index-out-of-bounds exception }

    Granted, the example was about count, but unless you want to tell the compiler it should treat constructs involving variable "count" differently from variable "index", based on the name alone, what can the language definition do?

    Yeah, if it's part of a double conditional, that's different. But the example in the article was a single conditional, and it's backwards because C trains you to write conditionals backwards "as a best practice," because anything can be a boolean, even assignment, and it has confusing double operators. "if 0 < count" looks a whole lot like "if 0 == count" and was probably inspired by it.

    And your example shows another problem with anything being a boolean: the aforementioned confusing double operators.

    "if ( ( 0 <= index ) && ( index < size ) )"? What's the deal with that && sign anyway? Why can't you say "if ( ( 0 <= index ) & ( index < size ) )"? Because when numbers can be booleans, the compiler can't tell whether your and, or, xor or [b]not[b] is supposed to be operating on a number or on a boolean value, so you need to have separate, explicit "logical" and "bitwise" versions of each, and heaven help you if you get the two versions conflated.

    Even to this day Java and C#, which actually have real boolean types, require you to keep two sets of operators straight, simply because that's the way C did it almost 40 years ago.

    (And JFTR there's at least one language where you can say "if 0 < x < size" and have it evaluate exactly as you'd intuitively think it should: Delphi Prism, a .NET dialect of Delphi. I've been pushing for that construct to be included in standard Delphi too, but apparently the compiler team's had other priorities lately.) :(

  • Anonymously Yours (unregistered) in reply to anon
    anon:
    Larry Lard:
    Surely TRWTF is that a function named "isWidgetReferenced" is actually returning 'available'? - that is, whether the passed widget number is NOT referenced?
    I was thinking the same thing... there's nothing like trying to puzzle out the real meaning of an "opposite named function".

    'commoveo' - commoveo and fix this function name you idiot!

    What's particularly WTF-ish is if you look at the error-logger call, you can see the name given for the function is "isWidgetAvailable". That means either the coder intended to rename the function to "isWidgetAvailable" and forgot, renamed it to "isWidgetReferenced" for some sick reason but didn't update the error-logging, or named it what it should have been called in the error logs but couldn't rename it because it would have caused other code to break.

    Another lovely WTF is the fact this function returns true if it encounters an error. That is terrible. It would have been better to leave error-trapping out of this function (since your returns are limited to TRUE, FALSE, and FILE_NOT_FOUND) and let the caller handle the error. As it stands now, any error from the database tells the caller of the function to go ahead and use the ID.

  • Anonymously Yours (unregistered) in reply to Anonymously Yours

    Whoops. I mean it returns false on an error. If the caller is attempting to find a free ID because the programmer doesn't know what an identity is, it will force the caller to keep looping through IDs (possibly forever) any time the database has a bad day.

  • Ouch! (unregistered) in reply to Mason Wheeler
    Mason Wheeler:
    Yeah, if it's part of a double conditional, that's different. But the example in the article was a single conditional, and it's backwards because C trains you to write conditionals backwards "as a best practice," because anything can be a boolean, even assignment, and it has confusing double operators. "if 0 < count" looks a whole lot like "if 0 == count" and was probably inspired by it.

    And your example shows another problem with anything being a boolean: the aforementioned confusing double operators.

    "if ( ( 0 <= index ) && ( index < size ) )"? What's the deal with that && sign anyway? Why can't you say "if ( ( 0 <= index ) & ( index < size ) )"?

    You can. But it has different semantics from &&, it doesn't short-circuit (and be sure to use & only on the reults of boolean expressions if you want to use it as a logical and). Yes, the absence of a real boolean type is a PITA. But I consider it a good thing that bitwise and logical operators have different symbols, since they are different things.

    Because when numbers can be booleans, the compiler can't tell whether your and, or, xor or not is supposed to be operating on a number or on a boolean value, so you need to have separate, explicit "logical" and "bitwise" versions of each, and heaven help you if you get the two versions conflated.

    Even to this day Java and C#, which actually have real boolean types, require you to keep two sets of operators straight, simply because that's the way C did it almost 40 years ago.

    At least in Java, & and | are not only bitwise operators but also logical operators, the non-short-circuiting versions of && resp. ||. Whether they had any reason to have them besides that C kind of had them, I don't know. Whether it's a good idea to have them at all, well, I'm not convinced.

  • (cs) in reply to Airhead
    Airhead:
    Closing connections, opening connections... Who has the time for such nonsense? Just keep them open!

    If connection limit is reached, a) raise the limit b) add new hardware and c) do some magic, (d)????? (e)PROFIT!!

    You left out a couple of steps. I added them for you. You're welcome.

  • (cs) in reply to Mason Wheeler
    Mason Wheeler:
    ... big rant against C
    C makes sense to computers. Therefore, C will continue to be the measuring stick for most serious coding, and CompSci scholars will stick to C-ish languages.

    Some have actually fixed C's faults while keeping the syntax (like Java), and others have tried to stick weird stuff into C (like Objective-C). Honestly, I'd rather have C as a measuring stick and not abominations like Visual Basic, or even worse, MUMPS.

  • bjolling (unregistered) in reply to RvW
    RvW:
    Rob:
    They could have done this:
    rs = connection.createStatement().executeQuery(query);
    rs.next();
    count = rs.getInt(1);
    if (0 < count) return false;
    

    Any particular reason to not just use

    rs = connection.createStatement().executeQuery(query);
    rs.next();
    if (0 < rs.getInt(1)) return false;
    
    Any reason to not use:
    return ( connection.createStatement().executeScalar(query) <= 0 );
    
    or is this a function that only .NET is blessed with?
  • (cs)

    Typical copy-paste cargo cult programming.

    This is what happens when managers argue that "programming is easy", and then hire cheap idiots instead of actual programmers. In few other fields do customers have such a complete disregard for the value of competence.

  • Coder (unregistered) in reply to The Nerve
    The Nerve:
    That said, it's not necessary these days to manually close connections for most applications: they're moving toward dependency injection (IoC pattern) for the pooled resources.

    I smiled when I read the code: VB code using JAVA.

    I laughed when I read this. "these days"? "moving toward"?

    Dependancy Injection was the difference between MS Access and VB 3 in 1992.

  • RvW (unregistered) in reply to Mason Wheeler
    Mason Wheeler:
    Yeah, if it's part of a double conditional, that's different. But the example in the article was a single conditional, and it's backwards because C trains you to write conditionals backwards "as a best practice,"
    My bad, I thought you had a problem with the compiler accepting it, instead of it being promoted as a "safeguard against typos".
    Mason Wheeler:
    because anything can be a boolean, even assignment,
    You're preaching to the choir: I almost exclusively used Pascal before I had to start using C (because of a lack of Pascal compilers for the target systems; if there were I'd switch in a heartbeat). You type i = 1 and the compiler doesn't just tell you "that's bull" the language definition is clean enough it can also tell you "didn't you mean i := 1?". Same if you should accidentally write if i := 1 then (note the absence of those stupid, superfluous braces!). Sure, you can still make errors, but at least it's not so insanely easy (and with such difficult-to-track-down bugs as a result).
    Mason Wheeler:
    (And JFTR there's at least one language where you can say "if 0 < x < size" and have it evaluate exactly as you'd intuitively think it should: Delphi Prism, a .NET dialect of Delphi. I've been pushing for that construct to be included in standard Delphi too, but apparently the compiler team's had other priorities lately.) :(
    Well, you sure got my vote. And thanks for the reference, if I ever have time (probably in 2042 or so...) I'll look into Delphi Prism, it sounds like it might be an interesting language.

    On a related note, do you know the "multiple assignment": a, b, c := 0, 37, 42? That would make a nice extension too. Swap becomes real easy: a, b := b, a. In general, whenever you revert to something like a_old := a life would've been easier with multi-assigns. For instance, Kaldewaij's O(log N) algorithm for Fibonacci (converted from GCL to Pascal):

    function fib(AInput: integer): integer;
    var
      a, b, x, y, n: integer;
    begin
      a, b, x, y, n := 0, 1, 0, 1, AInput;
    
      while n <> 0 do
        if n mod 2 = 0 then
          a, b, n := a*a+b*b, a*b+b*a+b*b, n mod 2
        else
          x, y, n := a*x+b*y, b*x+a*y+b*y, n-1;
    
      return x;
    end;

    Without multi-assign that would become a mess (it's not clear why it works because I didn't bother copying the comments / derivation, but it's clear what the code is doing). Added benefit: even if two or three "normal" assignments could've done the job, this is just one statement. If your coding standard allows it you can save a lot of begin/ends (or, in C, braces) if you want to, which can often make your code much easier to read (even if it's just because more context fits on screen / paper). It can even be compiled easily and efficiently, no problem there either.

    Captcha: "nulla", good thing I'm not Slovenian or I might be offended you're calling me that. ;)

  • (cs) in reply to Cbuttius
    Cbuttius:
    The final object's finalizer can be implemented to do exactly that and you won't have to "remember" to do it yourself. Of course, the problem is you don't know exactly when this will happen, i.e. it is not guaranteed to happen as you leave scope, unlike in C++ where it is.

    Some of us don't have time to wait for non-deterministic garbage collection to call the finalizer method before the server on the other end of the unmanaged resources destabilizes. I have too many web users to keep their database connections open an extra GC cycle.

  • Iago (unregistered) in reply to The Web is the Root of All Info
    The Web is the Root of All Info:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    Or you commute is that unpredictable.

    My commute? 20 min. if you hit every green light along the way, 90 min. if everyone else decided to commute at the exact same time as you.

    What lights? Mind you the 150km of country train travel each way has got boreing over the past decade. More germainly, I'm with the 'move it to the database' crowd. One SP would have removed the obviousness of this WTF.

  • (cs) in reply to RvW
    RvW:
    On a related note, do you know the "multiple assignment": a, b, c := 0, 37, 42? That would make a nice extension too. Swap becomes real easy: a, b := b, a. In general, whenever you revert to something like a_old := a life would've been easier with multi-assigns. For instance, Kaldewaij's O(log N) algorithm for Fibonacci (converted from GCL to Pascal):
    function fib(AInput: integer): integer;
    var
      a, b, x, y, n: integer;
    begin
      a, b, x, y, n := 0, 1, 0, 1, AInput;
    

    while n <> 0 do if n mod 2 = 0 then a, b, n := aa+bb, ab+ba+bb, n mod 2 else x, y, n := ax+by, bx+ay+by, n-1;

    return x; end;

    Interesting. Only language I'm familiar with that does multi-assigns like that is Python.

  • (cs) in reply to danixdefcon5
    danixdefcon5:
    Mason Wheeler:
    ... big rant against C
    C makes sense to computers. Therefore, C will continue to be the measuring stick for most serious coding, and CompSci scholars will stick to C-ish languages.

    Oh, I'm well aware that it "makes sense to computers," and when you need a small library that can give you both high performance and (a certain degree of) portability, C's the way to go. My "big rant" is about how C is based on design principles for building small, high-performance libraries, (70s operating systems,) but that involves a lot of design choices that make it unsuitable for most modern, large-scale software, including modern operating systems. (A coworker of mine likes to say that Dennis Ritchie's true legacy in the field of computer science is the buffer overflow.)

  • wtf (unregistered) in reply to Mason Wheeler
    Mason Wheeler:
    danixdefcon5:
    Mason Wheeler:
    ... big rant against C
    C makes sense to computers. Therefore, C will continue to be the measuring stick for most serious coding, and CompSci scholars will stick to C-ish languages.

    Oh, I'm well aware that it "makes sense to computers," and when you need a small library that can give you both high performance and (a certain degree of) portability, C's the way to go. My "big rant" is about how C is based on design principles for building small, high-performance libraries, (70s operating systems,) but that involves a lot of design choices that make it unsuitable for most modern, large-scale software, including modern operating systems. (A coworker of mine likes to say that Dennis Ritchie's true legacy in the field of computer science is the buffer overflow.)

    You might say that, in that buffer overflows are a misfeature of C. But that's like saying that Tim Berners-Lee's true contribution to society is the Nigerian scam and phishing attacks.

  • (cs)

    "...by hundreds of poorly trained, and probably poorly paid, developers."

    AWTF ("Another WTF") is that the above probably allowed some IT-impaired VP to claim great cost savings and earn a huge bonus.

  • Henning Makholm (unregistered) in reply to Rob
    Rob:
    Henning Makholm:
    It is an if statement written using the for statement.

    It's not even an if statement then - there's no branch. It's just a statement. They could have done this:

    rs = connection.createStatement().executeQuery(query);
    rs.next();
    count = rs.getInt(1);
    if (0 < count) return false;
    

    rs.next() was the loop condition. If it returns false, the original code will not call getInt().

  • (cs)

    This is the first TDWTF article that has scared me.

    Our company uses a certain application, much unloved by our staff for its quirky behaviour, such as every now and then importing a transaction with no transaction type even though the transaction type is correctly specified in the source file.

    The vendor does not support this application any more and encourages customers to upgrade.

    And one of the workarounds that we had to implement when we started using it was a daily restart of the application server to clean up the JDBC connections which it leaves open after the day's processing.

  • sad man (unregistered)

    This is far from being the worst code ever seen. Just for using 'for' in an 'if' fashion, repeating endlessly the same few lines of code without seeing a clear HEY-I'M-HERE pattern, and not freeing any resources adquired, it only make it a usual-bunch-of-code-made-without-have-ever-thougt-in-code-at-all...

    Worse beasts are out there camping in the wilds...

  • Daveytay (unregistered) in reply to Someone You Know
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    Living in Christchurch, my commute is 15 minutes.

  • (cs) in reply to Jellineck
    Jellineck:
    Mike:
    Someone You Know:
    Scott Selikoff:
    ...he managed to shave 15 minutes off his commute...

    If fifteen minutes is just a "shave" off your commute, your commute is way too fucking long.

    My commute is 5 min. Maybe 10 if I get caught by all 4 traffic lights and there is heavy traffic for some reason. It's about 2.5 miles in total.

    BUT I know people that have a 3 hr one-way commute every day. I tried to tell them they need to move nearer to work, but noooooo...

    Actually, they need to find jobs closer to their homes.

    Or they need to find a faster vehicle for commuting.

  • (cs) in reply to Kevin
    Kevin:
    EngleBart:
    If the database was properly normalized with cascading updates/deletes, then you should only have to check the primary widget table.

    Failure to exist in the widget table should indicate failure to exist in the entire DB!

    Of course, from the code seen here, this developer may have still messed it up.

    This is also wrong.

    10:58 a.m. Sally checks for next available WIDGET_ID. Finds WIDGET_ID=6 is available. 10:59 a.m. Sally adds WIDGET_ID=6 to the primary table, sees the time, and runs out for a lunch date (forgets to click "save" button). 11:02 a.m. Tim is running late for a lunch date with Sally, but can't leave until he adds his WIDGET. The application determines WIDGET_ID = 6 is available. 11:03 a.m. Tim tries to add WIDGET_ID = 6 to the primary WIDGET table. The application hangs. For 25 minutes. Tim becomes angry, as he is missing his lunch date with Sally. After 10 minutes, he calls IT, and berates them every 5 minutes as they investigate. 11:30 p.m. Sally gets back from lunch, annoyed at having been stood up.
    11:31 p.m. Sally calls Tim and tells him to go !@#$ himself. After hanging up, she sees that she'd forgetten to save her work, and clicks "save". 11:32 p.m. Tim's application finally unfreezes, and he gets an unhandled application error, some voodoo nonsense about a UNIQUE KEY CONSTRAINT VIOLATION. 11:33 p.m. DBA investigator sees there are suddenly no locks, calls Tim and happliy tells him that the performance issue has been resolved, and inquires, "are you still having a problem?". Tim is not in the best of moods for that question, hangs up, and calls company VP to ask how it is that after a $1 million hardware upgrade, it still takes 25 minutes to add a !@#$ing widget.

    11:33 p.m. The company VP tells Tim to go !@#$ himself and goes back to sleep.
  • (cs) in reply to Mason Wheeler
    Mason Wheeler:

    "if ( ( 0 <= index ) && ( index < size ) )"? What's the deal with that && sign anyway? Why can't you say "if ( ( 0 <= index ) & ( index < size ) )"? Because when numbers can be booleans, the compiler can't tell whether your and, or, xor or [b]not[b] is supposed to be operating on a number or on a boolean value, so you need to have separate, explicit "logical" and "bitwise" versions of each, and heaven help you if you get the two versions conflated.

    Even to this day Java and C#, which actually have real boolean types, require you to keep two sets of operators straight, simply because that's the way C did it almost 40 years ago. :(

    Java and C# are more strictly type-safe than C.

    In C and C++ the expression will work with a single & if you can guarantee that the compiler will always return the same non-zero value when a boolean expression returns true. I do not think the standard, even now, promises it will, so technically one of them could return 1 and one of them 2, and 1 & 2 is 0 because they have no bits in common.

    It would make sense that in a system where booleans are not integers, you could use & on booleans with the same effect as &&.

    a < x < b

    is left-to-right associative in C++ at least, so you would get (a<x)<b. Assuming that a boolean always returns 0 or 1 then if b>1 the expression will always be true regardless of a and x, and if b<=0 then it will always be false. If b is somewhere between 0 or 1 (or equal to 1) then (a<x)<b will be true when (a<x) is false thus x is less than or equal to a.

  • (cs) in reply to Cbuttius
    Cbuttius:
    In C and C++ the expression will work with a single & if you can guarantee that the compiler will always return the same non-zero value when a boolean expression returns true. I do not think the standard, even now, promises it will, so technically one of them could return 1 and one of them 2, and 1 & 2 is 0 because they have no bits in common.
    Nope - both C and C++ are required to return 0 or 1 for booleans.

    You may be getting confused with the fact that in a conditional all non-zero values are considered true, and in those cases (a & b) may be false, while (a && b) is true. But that's only valid if a and/or b are not boolean.

Leave a comment on “Swallowed by the Beast”

Log In or post as a guest

Replying to comment #:

« Return to Article