0

I am working on project where we have to work out delivery times based on rules in the database. The same day can have a few possibilities (same day deliveries) but also Fridays, Saturdays don't have rules so we have to look ahead and find the Monday rule.

Sorry for long winded explanation ...

To add to complexity we also calculate when the item can be collected at the delivery point so we calculate the pick up time based on AM / PM guarantees and make sure the place is open and its not holiday...

When I initially wrote up the logic I made a method that takes a date and calculates all these values and returns our Calculated Model. Just before the end I put in a test to make sure the model is populated otherwise there was no match made for that date and time and I increment the day by 1 and call my method again, with the incremented datetime and the rule until I hit the return and everything bubbles back to the original stack call. For me that worked like a charm, single level if statements and no complicated and and or's

Basically that code was shot down because other test and bug developers did not understand how to debug it, or what it was doing.

The new proposal is a single method that does the same thing but enclosed in a while statement until the condition is met. Then within the while there is a foreach that validates the deliveries can be met and a line of conditional if and nested conditional or's and then returns the Calculated model.

Is it bad to recall the same method from within it self until the ultimate condition is met with adjusted values?

Both code fragments work fine I just find having nested for each in while and conditionals if more difficult to decipher than a flat set of rules.

Piotr Kula
  • 9,597
  • 8
  • 59
  • 85
  • In my experience I always opt for the loop over some kind of recursion. – Mike Schwartz Feb 05 '14 at 20:47
  • 2
    In general looping is preferred over recursion, since is more readable and prevent stack overflows – Fabio Marcolini Feb 05 '14 at 20:48
  • TL;DR. Loop and/or stack-based algorithm (not the call stack) over recursion. – Jonathon Reinhart Feb 05 '14 at 20:49
  • Ahhhh. I don't know why it seems so much better for me the recursilvly call my method.But if all you guys say that looping is better than recursion, I need to shake that habit off. It seems like allot of my code is not "other developer" friendly - but in my mind find it to be less buggy(and practise). FYI- I also pass in the recursion integer and make sure it doest go over 14 days and throw an error because there must be a result otherwise something is wrong with the DB rules. – Piotr Kula Feb 05 '14 at 20:59

1 Answers1

2

Although recursion can lead to some elegant solutions it can also lead to difficult to follow code and stack overflows, as each recursive calls allocates a new stack frame. By default each thread has a 1MB stack, so it doesn't take long to run out of space.

Tail recursion can fix this, as long as your actually doing a tail recursive call, and the compiler can spot this. At the IL level there is support for tail recursion with the TailCall instruction, but the C# compiler doesn't generate code that uses it.

Sean
  • 60,939
  • 11
  • 97
  • 136
  • So using `call` before my calling my method `call method(datetime)` will make it a tail instruction? – Piotr Kula Feb 05 '14 at 21:08
  • 1
    Thanks Sean. I didn't know about the Stack issue here.. so really upgrading my method to do the `call` will fix the base issue. But in reality the best code is the code that is understandable by the company. So if I were my own company that would be excellent but in terms of the current situation, politics win. – Piotr Kula Feb 05 '14 at 21:18
  • I was just reading around this topic some more and found this interesting question and answer on here. http://stackoverflow.com/questions/15864670/generate-tail-call-opcode - Basically saying that C# Devs should use loops instead of recursion because of optimization, like you said. So I think I picked up recursion form C/C++ sometime ago, which optimizes recursion internally. But essentially looping is faster than recursions. Its hard to admit.. but I was writing crap code :P and my team were strong enough to point it out. Hooray. – Piotr Kula Feb 07 '14 at 11:45
  • 1
    There's nothing in the C/C++ spec to required any optimizations around recurision, and in my experience it not done. This is why most people recommend converting a recursive function to a loop. The `Scheme` programming language does mandate that tail recursion be done without allocating a new stack frame, but it's your job to ensure that you are correctly doing tail recursion. – Sean Feb 07 '14 at 12:04