• (cs)

    Now, imagine if he tried :

    returnVal = DateTimeParseSafe(s, iter++);

    Yes, I've seen that once...

  • TexDex (unregistered)

    I just love the use of recursion there. Reminds me of my freshman CS project learning about recursion. Maybe that says something about the writer of this little gem.

  • Corey Miller (unregistered)

    What an amazing way to do something totally useless! I've seen this done millions of times with for and while loops, but this is the first time I've seen it done with both error handling and iteration. It's like ingenuity wrapped in stupidity wrapped in a function.

  • Kiyyik (unregistered)

    Oy gevalt. My predecessor used this kind of thing a lot (though not, I must say, with recursion). Any time we called a data function she would give it ten tries to work. Absolutely bats. I guess she wanted to make really, REALLY sure.

  • tsmith (unregistered)

    I like the tail-recursion optimization. This at least shows that the programmer knows what he/she is doing.

  • Rex (unregistered) in reply to tsmith
    tsmith:
    This at least shows that the programmer knows what he/she is doing.

    At least.

  • (cs)

    This is ridiculous. Why would you hard-code a maximum of 10 tries into a wonderful method like this? It should really just take a positive integer and move it towards the base case of 0. That way you can specify 10 tries, or 100 tries!

  • quephird (unregistered)

    If at first you don't succeed, try, try, try, try, try, try, try, try, try again.

  • random person (unregistered) in reply to djork
    djork:
    This is ridiculous. Why would you hard-code a maximum of 10 tries into a wonderful method like this? It should really just take a positive integer and move it towards the base case of 0. That way you can specify 10 tries, or 100 tries!

    since it takes an int, it could be passed -90 for 100 tries...

  • (cs) in reply to tsmith
    tsmith:
    I like the tail-recursion optimization. This at least shows that the programmer knows what he/she is doing.
    I'd vote that he/she got lucky :P
  • WTFer (unregistered)

    It just goes to show what equal opportunity laws and hiring the mentally handicapped get you

    captcha - xevious, damn that was a good video game

  • (cs)

    Has anyone actually counted this up? With the iterations and the recursions, it looks like it runs far more than ten times. It looks like th following: 10+9+8+7+6+5+4+3+2+1 = 55

    Whoever wrote this, must really need to make sure, but what happens if it fails on the last attempt?

  • (cs)

    What amuses me most about this is that, even setting aside the recursion issue for a moment, the parameter you pass in is not the number of times you wish to try it again, but (10 - the number of times to try again). How long does it take to return if you pass in Integer.MinValue?

  • (cs)

    I once did something like this to fix a mysql error on an extremely stupid server. Once in a while, at random, a mysql call would just fail. If you tried it again right after it'd work fine. So I made it try 5 times, breaking if it fails. If it failed for a legitimate reason it means it wasted some time, but it failed for absolutely no reason just once more often then it failed for reals.

  • (cs) in reply to KattMan
    KattMan:
    Has anyone actually counted this up? With the iterations and the recursions, it looks like it runs far more than ten times. It looks like th following: 10+9+8+7+6+5+4+3+2+1 = 55

    Whoever wrote this, must really need to make sure, but what happens if it fails on the last attempt?

    Nah, there's no loop, it's just the recursion. It's more like 1+1+1+1+1+1+1+1+1+1 = 10

  • (cs) in reply to KattMan
    KattMan:
    Has anyone actually counted this up? With the iterations and the recursions, it looks like it runs far more than ten times. It looks like th following: 10+9+8+7+6+5+4+3+2+1 = 55

    Whoever wrote this, must really need to make sure, but what happens if it fails on the last attempt?

    After looking at the given code one more time, I think I'm way off the final count. I was thinking it looped with a while for some reason. Not counting the original attempt it actually tries 11 times.

  • Le Poete (unregistered) in reply to abx
    abx:
    KattMan:
    Has anyone actually counted this up? With the iterations and the recursions, it looks like it runs far more than ten times. It looks like th following: 10+9+8+7+6+5+4+3+2+1 = 55

    Whoever wrote this, must really need to make sure, but what happens if it fails on the last attempt?

    Nah, there's no loop, it's just the recursion. It's more like 1+1+1+1+1+1+1+1+1+1 = 10

    I'm not familiar with this language (Java or C#), but everything changes depending if iter is passed by value of reference.

    The count is ten if it's by reference, but much higher if by value.

  • Josh (unregistered)

    The real WTF is passing the same data to a function and expecting to get different results!

  • (cs) in reply to Le Poete
    Le Poete:
    I'm not familiar with this language (Java or C#), but everything changes depending if iter is passed by value of reference.

    The count is ten if it's by reference, but much higher if by value.

    It doesn't matter if it's by value or by reference. It will be 10 times regardless, since the int is incremented before the function call and not touched afterwards.

  • Nico (unregistered) in reply to Le Poete
    Le Poete:
    The count is ten if it's by reference, but much higher if by value.

    Sure? I don't think it makes any difference here. It looks like java so it's passed by value.

  • K (unregistered) in reply to Le Poete
    Le Poete:
    abx:
    KattMan:
    Has anyone actually counted this up? With the iterations and the recursions, it looks like it runs far more than ten times. It looks like th following: 10+9+8+7+6+5+4+3+2+1 = 55

    Whoever wrote this, must really need to make sure, but what happens if it fails on the last attempt?

    Nah, there's no loop, it's just the recursion. It's more like 1+1+1+1+1+1+1+1+1+1 = 10

    I'm not familiar with this language (Java or C#), but everything changes depending if iter is passed by value of reference.

    The count is ten if it's by reference, but much higher if by value.

    The real WTF is this comment.

  • Grant (unregistered)

    The really sad thing is that I am sure this was done for a reason. So, parsing a string to a date may fail, but parsing the exact same string again may succeed. I have seen this, but it was always a memory problem, or something stepping out of bounds and corrupting the memory from other processes.

  • Gazzonyx (unregistered) in reply to Kokuma
    Kokuma:
    Now, imagine if he tried :
    returnVal = DateTimeParseSafe(s, iter++);

    Yes, I've seen that once...

    Why wouldn't that work? It should increment the counter before calling the function, I think... would a preincrement work? I'm not all that great with java, but I think you can do this in C++ with a preincremented variable (++iter). So long as there's a base case that catches before hand.

  • anonymous (unregistered)

    (know nothing about java)

    probably he's waiting for s to be modified in another thread?

  • (cs) in reply to ebs2002
    ebs2002:
    Le Poete:
    I'm not familiar with this language (Java or C#), but everything changes depending if iter is passed by value of reference.

    The count is ten if it's by reference, but much higher if by value.

    It doesn't matter if it's by value or by reference. It will be 10 times regardless, since the int is incremented before the function call and not touched afterwards.

    It will be 11 in this case, we are starting from 0, not 1. I actually tested the code and had it count the iterations.

  • Michael (unregistered) in reply to Gazzonyx
    Gazzonyx:
    Kokuma:
    Now, imagine if he tried :
    returnVal = DateTimeParseSafe(s, iter++);

    Yes, I've seen that once...

    Why wouldn't that work? It should increment the counter before calling the function, I think... would a preincrement work? I'm not all that great with java, but I think you can do this in C++ with a preincremented variable (++iter). So long as there's a base case that catches before hand.

    It wouldn't work because iter++ returnes the value of iter BEFORE it was incremented. ++iter would work because it returns the incremented value.

  • Incursion (unregistered) in reply to Gazzonyx
    Gazzonyx:
    Kokuma:
    Now, imagine if he tried :
    returnVal = DateTimeParseSafe(s, iter++);

    Yes, I've seen that once...

    Why wouldn't that work? It should increment the counter before calling the function, I think... would a preincrement work? I'm not all that great with java, but I think you can do this in C++ with a preincremented variable (++iter). So long as there's a base case that catches before hand.

    You're right that preincrement would work (++i), but with ++i the value passed is the existing on, and incremented after the opteration. So a call of

    returnVal = DateTimeParseSafe(s, iter++);
    would pass the same value over, and over, and over.... Whee! Infinite recursion!

  • Brady Kelly (unregistered) in reply to WTFer
    WTFer:
    captcha - xevious, damn that was a good video game

    Man are you right about that!

  • javascript jan (unregistered)

    Can't help but think that this behaviour is motivated by some blasphemous non-thread-safety in the date parsing class. So I guess the real WTF is that the date parse takes long enough to prompt a context switch.

  • (cs) in reply to Incursion
    Incursion:
    You're right that preincrement would work (++i), but with ++i the value passed is the existing on, and incremented after the opteration. So a call of
    returnVal = DateTimeParseSafe(s, iter++);
    would pass the same value over, and over, and over.... Whee! Infinite recursion!

    I think you might want to go read up on C++ some more.

  • Michael (unregistered) in reply to Someone You Know
    Someone You Know:
    Incursion:
    You're right that preincrement would work (++i), but with ++i the value passed is the existing on, and incremented after the opteration. So a call of
    returnVal = DateTimeParseSafe(s, iter++);
    would pass the same value over, and over, and over.... Whee! Infinite recursion!

    I think you might want to go read up on C++ some more.

    I think that was a typo that should have read:

    You're right that preincrement would work (++i), but with i++ the value passed is the existing one
  • (cs)

    Better name for this function: DateTimeTryTryTryTryTryTryTryTryTryTryTryParse

    Surprisingly, I can almost find a point to this. Suppose you change

    returnVal = DateTime.Parse(s);
    to
    returnVal = DateTime.Parse(s,CultureInfo.CurrentCulture,iter);
    Now it attempts to parse the time with the various flags set:

    0 = None
    1 = AllowLeadingWhite
    2 = AllowTrailingWhite
    3 = AllowLeadingWhite && AllowTrailingWhite
    4 = AllowInnerWhite
    etc.

    Recurse until one is parsed correctly. Except, of course, that it doesn't actually DO that; and 15 would make more sense to stop at instead of 10. And of course it's a silly way of using the allow flags.

    Perhaps the developer copied the code from elsewhere, and simplified the parse statement because they didn't care about the CurrentCulture? And then the reason for the recursive loop got forgotten over time...

  • Hand tracer (unregistered) in reply to KattMan

    If anyone's still skeptical, here's how it does that:

    1. The wrapper method calls it, passing 0
    2. The method calls itself, passing 1
    3. The method calls itself, passing 2
    4. The method calls itself, passing 3
    5. The method calls itself, passing 4
    6. The method calls itself, passing 5
    7. The method calls itself, passing 6
    8. The method calls itself, passing 7
    9. The method calls itself, passing 8
    10. The method calls itself, passing 9
    11. The method calls itself, passing 10 At the 11th time, iter passes its upper boundary, so it won't call again.
  • John Doe (unregistered)

    Comments++: if at first your comment isn't correct, try again and again and again and ...

  • Andrew (unregistered)

    The time "Dog" parses to what ever the min for DateTime is. Got love that. I wish they would have sent in that class too.

  • (cs) in reply to KattMan

    How do you know that, like Schrödinger's cat, you didn't change the value just by observing it?

  • (cs) in reply to KattMan
    KattMan:
    ebs2002:
    Le Poete:
    I'm not familiar with this language (Java or C#), but everything changes depending if iter is passed by value of reference.

    The count is ten if it's by reference, but much higher if by value.

    It doesn't matter if it's by value or by reference. It will be 10 times regardless, since the int is incremented before the function call and not touched afterwards.

    It will be 11 in this case, we are starting from 0, not 1. I actually tested the code and had it count the iterations.

    Let's try this again.

    How do you know that, like Schrödinger's cat, you didn't change the value just by observing it?

  • (cs) in reply to tsmith
    tsmith:
    I like the tail-recursion optimization. This at least shows that the programmer knows what he/she is doing.

    I'm pretty certain it's not actually tail recursive, seeing as the call happens in an exception handler...

  • (cs) in reply to webrunner
    webrunner:
    I once did something like this to fix a mysql error on an extremely stupid server. Once in a while, at random, a mysql call would just fail. If you tried it again right after it'd work fine. So I made it try 5 times, breaking if it fails. If it failed for a legitimate reason it means it wasted some time, but it failed for absolutely no reason just once more often then it failed for reals.

    This is actually considered a legitimate way to deal with many types of MySQL deadlocks.

  • (cs) in reply to Josh
    Josh:
    The real WTF is passing the same data to a function and expecting to get different results!

    Congrats! You get the award for "Stating the Obvious"!

    -- Seejay

  • (cs)

    This is C#, not Java (Java's string is 'String', and Java has no DateTime class (it's java.util.Date or some crap).

    Still doesn't excuse whatever idiot wrote this piece of shit.

  • Anon (unregistered) in reply to javascript jan
    javascript jan:
    Can't help but think that this behaviour is motivated by some blasphemous non-thread-safety in the date parsing class. So I guess the real WTF is that the date parse takes long enough to prompt a context switch.
    I think you've hit the nail on the head. Java's date parsing routines are not thread safe. Really. It isn't.

    From java.text.SimpleDateFormat:

    Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
    This technique may have worked around that problem - although stupidly poorly (Java doesn't optimize tail recursion, period) and still potentially could have created invalid results.
  • Sgt. Preston (unregistered) in reply to jimlangrunner
    jimlangrunner:
    KattMan:
    ebs2002:
    Le Poete:
    I'm not familiar with this language (Java or C#), but everything changes depending if iter is passed by value of reference.

    The count is ten if it's by reference, but much higher if by value.

    It doesn't matter if it's by value or by reference. It will be 10 times regardless, since the int is incremented before the function call and not touched afterwards.

    It will be 11 in this case, we are starting from 0, not 1. I actually tested the code and had it count the iterations.

    Let's try this again.

    How do you know that, like Schrödinger's cat, you didn't change the value just by observing it?

    Accordinf to the Copenhagen interpretation, the DateTime is both parsed and unparsed and neither parsed nor unparsed until you count the iterations.

  • (cs) in reply to Kokuma

    Way back, mean waaay back, computers were not so reliable. For instance the CDC 1604, at least the first few, were built using transistors that did not meet the tight specs for the Navy's Univac computers. So instead of paying $50 per transistor, the marginal ones went for pennies each. Seymour Cray designed the gates and flip-flops of the 1604 to tolerate, mostly, the wider tolerances for gain and leakage.

    But on hot days things could get close to the margins, so it was not unusual to have to write programs with built-in double-checking of results.

  • (cs) in reply to Anon
    Anon:
    I think you've hit the nail on the head. Java's date parsing routines are not thread safe. Really. It isn't.

    From java.text.SimpleDateFormat:

    This technique may have worked around that problem - although stupidly poorly (Java doesn't optimize tail recursion, period) and still potentially could have created invalid results.

    You may still be right about the thread-safety thing, but do bear in mind that this isn't Java.

  • some random dude (unregistered)

    I saw a situation recently where this code pattern would actually have prevented a bug (mostly).

    A java class I was redesigning had a static SimpleDateFormatter that was used by multiple threads. That formatter isn't threadsafe, so occasionally it collided with another thread and threw a NumberFormatException.

    I chose to make the parent class threadsafe (and get rid of the static formatter), but if I had just tried ten times after each collision if probably would have looked like the bug was fixed. At least the exceptions would have been much less frequent.

  • (cs) in reply to Anon

    "Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally."

    Does that mean what I think it means? If you call Java's SimpleDateFormat concurrently from two threads, you might get the wrong answer?

    Amazing.

  • Anon (unregistered) in reply to Someone You Know
    Someone You Know:
    You may still be right about the thread-safety thing, but do bear in mind that this isn't Java.
    Yeah, I know, I accidentally edited out the part where I mentioned that WTF entries frequently are "ported" to another language when anonymized, so it's possible that the original was in Java.
  • (cs)

    The Real WTF(tm) is that he used overloading when a default argument would have been sufficient.

  • Pi (unregistered)

    Wow, that's a sick blend of tail recursion and iteration. Lisp hackers would be proud.

Leave a comment on “Tenth Time's The Charm”

Log In or post as a guest

Replying to comment #:

« Return to Article