sje wrote:Symbolic's search has no recursion. There is the one routine Node() which has a big switch statement with each case being a different phase. The routine's main loop hits the switch each time through until the current phase is PhaseExit. At the top of the loop is is single check of a volatile boolean which, if triggered, sets the phase to PhaseExit. There is no unwinding as there is nothing to unwind. There is nothing hidden on the stack to deconstruct as there is no recursion. The search can be paused, and it can also be stopped and restarted at any phase at any depth.
A lot of chess programmers still use a recursive search because they've copied it out of a textbook or from someone else's program. If they would take the time to learn about the alternative of no recursion, then they just might a more elegant -- and possibly faster -- program.
So you use an iterative search, everything is done in one really big function, with a huge switch block. That means you have to handle the stack manually, and create your own stack (for alpha, beta, node_type, pv pointer, ply, etc.). How exactly is that better than a recursive search ?
And writing an iterative search while forcing yourself not to use goto and break or continue, is completely ridiculous. I can only imagine that your Node() function is an enormous pile of knots, with an extremely compolex control flow. For example, when I want to dive into the search (child node) recursively... Oh no wait! Recursion is forbiden, so I set the stack for the next ply manually, but then I cannot use goto, so I need to set a flag to tell all that mess of control structures to branch to the right point and search again the child node. How is that more readable than a neat recursive call ?
IMO an iterative search should use goto. That being said, I do not see the point of using an iterative search. When I think of alpha beta algorithm, I think of it recursively. I do not want to twist my brain into thinking how to "iterativize" something that is naturally recursive. It does not simplify code (quite the opposite) and it does not simplify readability because it makes the control flow much more complex, and forces the reader to think in counterintuitive way about the search.
Again you have decided not to use recursion, not to use goto, setjmp(), longjmp(), break or return in certain places only, etc. But behind these decisions there is only dogma, and no valid technical reason.
As for switch, I do not like the switch statement, and rarely use it. If I know that the compiler will generate a jump table, and the cost of branching is indeed critical to the overall execution time (very rare), then I will use it. Otherwise I often find if's more readable, and when you have long list of cases, you should redesign your code so that the need for switch is not necessary instead IMO (break functions into smaller ones for eg.)
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.