On Sun, Feb 19, 2012 at 08:33:04PM -0600, Andrei Alexandrescu wrote: > On 2/19/12 7:53 PM, H. S. Teoh wrote: > >I stand by my objection that if something might succeed if it can be > >retried, then it needs to be retried in the called function, not the > >caller. > > If read fails from a socket, it's of no use to try it again. One must > close the socket, reconnect, and attempt the whole operation once > again. [...]
Correct, so that would be a recovery strategy at the operation level, say at sendHttpRequest or something like that. There is not enough information available to sendHttpRequest to know whether or not the caller wants the request to be retried if it fails. But if the higher-level code could indicate this by way of a recovery policy delegate, then this retry can be done at the sendHttpRequest level, instead of percolating up the call stack all the way to submitHttpForm, which then has to reparse user data, convert into JSON, say, and then retry the entire operation all over again. I'm really liking the Lisp approach. It nicely combines stack unwinding with in-context recovery by using a high-level delegate to make sound decisions based on factors outside the scope of the low-level function. You can unwind up to the level where a high-level delegate can step in and select a recovery strategy, and then continue on your way, rather than unwinding all the way up to the top and having to restart from square 1. The delegate that makes decisions doesn't have to be at the absolute top level either (that wouldn't make sense, since it would break encapsulation: top-level code needs to know about inner workings of low-level code so that it can decide how to recover from low-level operations). You can have a chain of delegates that make decisions at various levels, and the one nearest to where the exception is generated is invoked. It can then decide to defer to the next handler if it doesn't have enough information to proceed. T -- Дерево держится корнями, а человек - друзьями.