www.digitalmars.com         C & C++   DMDScript  

D - [Suggestion] retry

reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Here's an idea for exception handling/recovery.

For certain kinds of errors, it is common to prompt the user to retry 
the operation.  (Common examples: no disk in drive, disk is write 
protected, printer is out of paper....)

For these, a handy idea would be a means of retrying the operation that 
has failed.  It would work like this:

	try {
		doSomething();
	} catch (Exception ex) {
		if (promptToRetry()) retry;
	}

The retry statement would simply jump back to the beginning of the try 
block.

Without it, we're stuck with either:

- A while loop.  The problem is that in the normal flow of program 
logic, it only does it once.  The concept of trying and trying again 
until it works (or the user gives up) is really part of error handling.

- A while loop in the catch block, which would perhaps use a variable to 
track success/failure on the retry.  But the while loop would duplicate 
the try code, leading to an unsightly redundancy and maintenance overhead.

- The dreaded goto.

What do you think?

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the 
unfortunate victim of intensive mail-bombing at the moment.  Please keep 
replies on the 'group where everyone may benefit.
Mar 29 2004
next sibling parent reply Dave Sieber <dsieber spamnot.sbcglobal.net> writes:
Stewart Gordon <smjg_1998 yahoo.com> wrote:

 For certain kinds of errors, it is common to prompt the user to retry 
 the operation.  (Common examples: no disk in drive, disk is write 
 protected, printer is out of paper....)
 
 For these, a handy idea would be a means of retrying the operation
 that has failed.  It would work like this:
 
      try {
           doSomething();
      } catch (Exception ex) {
           if (promptToRetry()) retry;
      }
 

It might compile (internally) to something like this: try { retry: doSomething(); } catch (Exception ex) { if (promptToRetry()) goto retry; } which I don't find too horrible, because it really *is* a goto, however you end up writing it. Introducing a new keyword would be like pretending it's not a goto when that's really what it is :-) OTOH, I would probably write it with a loop, just to avoid the scorn of peers who would see that I used the dreaded "g" word . Bottom line, IMO, is that it's readily accomplished with features already in the language, and doesn't buy us anything. Is there any advantage it would give us, something we couldn't do otherwise without messy or complicated code? -- dave
Mar 29 2004
parent larry cowan <larry_member pathlink.com> writes:
Possibly more like:

initialize();
try {
retry:
doSomething();
doSomething2();
doSomething3();
}
catch (myError me) {
fprintf(stderr,"Error: %.*s - continue? ",me);
if (promptForRetryYes()) {
reinitialize();
goto retry;
}
else assert(0);
}

OR

initialize();
while (1) {
try {
..
break;
}
catch ... {
fprintf ...
if (...)
reinitialize();
else
assert(0);
}
}

.. but if coded clearly, it is not terrible.  I agree with Dave. Not needed.

In article <Xns94BB4564CBFA0dsiebersbc 63.105.9.61>, Dave Sieber says...
Stewart Gordon <smjg_1998 yahoo.com> wrote:

 For certain kinds of errors, it is common to prompt the user to retry 
 the operation.  (Common examples: no disk in drive, disk is write 
 protected, printer is out of paper....)
 
 For these, a handy idea would be a means of retrying the operation
 that has failed.  It would work like this:
 
      try {
           doSomething();
      } catch (Exception ex) {
           if (promptToRetry()) retry;
      }
 

It might compile (internally) to something like this: try { retry: doSomething(); } catch (Exception ex) { if (promptToRetry()) goto retry; } which I don't find too horrible, because it really *is* a goto, however you end up writing it. Introducing a new keyword would be like pretending it's not a goto when that's really what it is :-) OTOH, I would probably write it with a loop, just to avoid the scorn of peers who would see that I used the dreaded "g" word . Bottom line, IMO, is that it's readily accomplished with features already in the language, and doesn't buy us anything. Is there any advantage it would give us, something we couldn't do otherwise without messy or complicated code? -- dave

Mar 29 2004
prev sibling next sibling parent reply "Derek Parnell" <Derek.Parnell psyc.ward> writes:
On Mon, 29 Mar 2004 13:50:57 +0100 (29/Mar/04 10:50:57 PM)
, Stewart Gordon <smjg_1998 yahoo.com> wrote:

 Here's an idea for exception handling/recovery.

 For certain kinds of errors, it is common to prompt the user to retry  
 the operation.  (Common examples: no disk in drive, disk is write  
 protected, printer is out of paper....)

 For these, a handy idea would be a means of retrying the operation that  
 has failed.  It would work like this:

 	try {
 		doSomething();
 	} catch (Exception ex) {
 		if (promptToRetry()) retry;
 	}

 The retry statement would simply jump back to the beginning of the try  
 block.

 Without it, we're stuck with either:

 - A while loop.  The problem is that in the normal flow of program  
 logic, it only does it once.  The concept of trying and trying again  
 until it works (or the user gives up) is really part of error handling.

 - A while loop in the catch block, which would perhaps use a variable to  
 track success/failure on the retry.  But the while loop would duplicate  
 the try code, leading to an unsightly redundancy and maintenance  
 overhead.

 - The dreaded goto.

 What do you think?

I work with a programming language (Progress 4GL) that has this feature. It is a very useful and well used feature. This language supports 'retry', 'next', 'leave', and 'undo' for use in loop blocks. It goes one level more too. It permits named blocks so that these commands can refer to a higher level block in a nested situation. Example ... Blk_Main: for each Customer: find Account of Customer. Blk_Second: for each Transaction of Account: .. do something .. if whatever then next Blk_Main. end. end. -- Derek
Mar 29 2004
parent reply larry cowan <larry_member pathlink.com> writes:
In article <opr5nc5rabu2m3b2 news.digitalmars.com>, Derek Parnell says...
On Mon, 29 Mar 2004 13:50:57 +0100 (29/Mar/04 10:50:57 PM)
, Stewart Gordon <smjg_1998 yahoo.com> wrote:

 Here's an idea for exception handling/recovery.

 For certain kinds of errors, it is common to prompt the user to retry  
 the operation.  (Common examples: no disk in drive, disk is write  
 protected, printer is out of paper....)

 For these, a handy idea would be a means of retrying the operation that  
 has failed.  It would work like this:

 	try {
 		doSomething();
 	} catch (Exception ex) {
 		if (promptToRetry()) retry;
 	}

 The retry statement would simply jump back to the beginning of the try  
 block.

 Without it, we're stuck with either:

 - A while loop.  The problem is that in the normal flow of program  
 logic, it only does it once.  The concept of trying and trying again  
 until it works (or the user gives up) is really part of error handling.

 - A while loop in the catch block, which would perhaps use a variable to  
 track success/failure on the retry.  But the while loop would duplicate  
 the try code, leading to an unsightly redundancy and maintenance  
 overhead.

 - The dreaded goto.

 What do you think?

I work with a programming language (Progress 4GL) that has this feature. It is a very useful and well used feature. This language supports 'retry', 'next', 'leave', and 'undo' for use in loop blocks. It goes one level more too. It permits named blocks so that these commands can refer to a higher level block in a nested situation. Example ... Blk_Main: for each Customer: find Account of Customer. Blk_Second: for each Transaction of Account: .. do something .. if whatever then next Blk_Main. end. end. -- Derek

http://www.digitalmars.com/d/ctod.html#labelledbreak but I don't see "retry" "leave" or "undo" in the code above. "Retry" is the topic - but is it better to have a bunch of special keywords that all mean "goto" than to just use it when it's appropriate? "Goto" has its uses, but is very easy to abuse and thus is badly maligned. Where there are good alternative constructs that are efficient (which is most places), they should be used, but just renaming the term is meaningless even if it will assuage the purists.
Mar 29 2004
parent reply "Derek Parnell" <Derek.Parnell psyc.ward> writes:
On Tue, 30 Mar 2004 00:24:50 +0000 (UTC) (30/Mar/04 10:24:50 AM)
, larry cowan <larry_member pathlink.com> wrote:

 In article <opr5nc5rabu2m3b2 news.digitalmars.com>, Derek Parnell says...
 On Mon, 29 Mar 2004 13:50:57 +0100 (29/Mar/04 10:50:57 PM)
 , Stewart Gordon <smjg_1998 yahoo.com> wrote:

 Here's an idea for exception handling/recovery.

 For certain kinds of errors, it is common to prompt the user to retry
 the operation.  (Common examples: no disk in drive, disk is write
 protected, printer is out of paper....)

 For these, a handy idea would be a means of retrying the operation that
 has failed.  It would work like this:

 	try {
 		doSomething();
 	} catch (Exception ex) {
 		if (promptToRetry()) retry;
 	}

 The retry statement would simply jump back to the beginning of the try
 block.

 Without it, we're stuck with either:

 - A while loop.  The problem is that in the normal flow of program
 logic, it only does it once.  The concept of trying and trying again
 until it works (or the user gives up) is really part of error handling.

 - A while loop in the catch block, which would perhaps use a variable  
 to
 track success/failure on the retry.  But the while loop would duplicate
 the try code, leading to an unsightly redundancy and maintenance
 overhead.

 - The dreaded goto.

 What do you think?

I work with a programming language (Progress 4GL) that has this feature. It is a very useful and well used feature. This language supports 'retry', 'next', 'leave', and 'undo' for use in loop blocks. It goes one level more too. It permits named blocks so that these commands can refer to a higher level block in a nested situation. Example ... Blk_Main: for each Customer: find Account of Customer. Blk_Second: for each Transaction of Account: .. do something .. if whatever then next Blk_Main. end. end. -- Derek

http://www.digitalmars.com/d/ctod.html#labelledbreak

Thanks. I'd missed that somehow. That feature is nice indeed.
 but I don't see "retry" "leave" or "undo" in the code above.  "Retry" is  
 the
 topic -

Sorry. ... if whatever then retry Blk_Main. else undo, leave Blk_Main. There, is that better now?
 - but is it better to have a bunch of special keywords that all mean  
 "goto" than to just use it when it's appropriate?  "Goto" has its uses,  
 but is very easy to abuse and thus is badly maligned.

Goto is most useful when one needs to shave microseconds off the runtime performance of a routine. But that is not very often, IMHO. So I would vote 'yes' to explicit keywords that have an exact (precise, predicatible) meaning. As you say, D already has 'break' and 'continue', so this would just add ONE new keyword 'retry' that would mean to restart the CURRENT interation of the loop. Thus for a 'for' loop, the end-of-iteration statements would be bypassed and control would just move to the top of the iteration code. for(i = 0; i < len; i++) { . . . if (whatever) retry; // 'i' does not get incremented. . . . };
 Where there are good  alternative
 constructs that are efficient (which is most places), they should be  
 used, but
 just renaming the term is meaningless even if it will assuage the  
 purists.

Sure, a goto would work as well, but it can be easily misused, as you say. A retry is just as efficient but will lead to more maintainable code. -- Derek
Mar 29 2004
parent reply larry cowan <larry_member pathlink.com> writes:
In article <opr5nizgt5u2m3b2 news.digitalmars.com>, Derek Parnell says...
On Tue, 30 Mar 2004 00:24:50 +0000 (UTC) (30/Mar/04 10:24:50 AM)
, larry cowan <larry_member pathlink.com> wrote:

 In article <opr5nc5rabu2m3b2 news.digitalmars.com>, Derek Parnell says...
 On Mon, 29 Mar 2004 13:50:57 +0100 (29/Mar/04 10:50:57 PM)
 , Stewart Gordon <smjg_1998 yahoo.com> wrote:

 Here's an idea for exception handling/recovery.

 For certain kinds of errors, it is common to prompt the user to retry
 the operation.  (Common examples: no disk in drive, disk is write
 protected, printer is out of paper....)

 For these, a handy idea would be a means of retrying the operation that
 has failed.  It would work like this:

 	try {
 		doSomething();
 	} catch (Exception ex) {
 		if (promptToRetry()) retry;
 	}

 The retry statement would simply jump back to the beginning of the try
 block.




..just add ONE new keyword 'retry' that would mean to restart the CURRENT
interation of the loop. Thus for a 'for' loop, the end-of-iteration  
statements would be bypassed and control would just move to the top of the  
iteration code.

    for(i = 0; i < len; i++)
    {
       . . .
       if (whatever)
           retry; // 'i' does not get incremented.
       . . .
    };

if (whatever) i--; continue; but where the loop is something like for (link=begin; link ;link=link.next) // D style, no -> and there are only forward links available, then it has some use. I doubt if its sufficiently compatible with the "retry" originally mentioned unless we are now to start labeling try blocks as well as loops and every retry has an operand. Then it looks just like a "goto" to me!
Mar 29 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
larry cowan wrote:
 In article <opr5nizgt5u2m3b2 news.digitalmars.com>, Derek Parnell says...
 

   for(i = 0; i < len; i++)
   {
      . . .
      if (whatever)
          retry; // 'i' does not get incremented.
      . . .
   };


 I doubt if its sufficiently compatible with the "retry" originally mentioned
 unless we are now to start labeling try blocks as well as loops and every retry
 has an operand.  Then it looks just like a "goto" to me!

Except that it would act as though the label is just inside the loop rather than just outside it/labelling the loop itself, so that the initialisation isn't repeated. Breaks and continues can be labelled or unlabelled. Surely if we're going to support retry on this level it would be the same? Stewart. -- My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment. Please keep replies on the 'group where everyone may benefit.
Mar 30 2004
parent larry cowan <larry_member pathlink.com> writes:
In article <c4bgqd$2udp$1 digitaldaemon.com>, Stewart Gordon says...
larry cowan wrote:
 In article <opr5nizgt5u2m3b2 news.digitalmars.com>, Derek Parnell says...
 

   for(i = 0; i < len; i++)
   {
      . . .
      if (whatever)
          retry; // 'i' does not get incremented.
      . . .
   };


 I doubt if its sufficiently compatible with the "retry" originally mentioned
 unless we are now to start labeling try blocks as well as loops and every retry
 has an operand.  Then it looks just like a "goto" to me!

Except that it would act as though the label is just inside the loop rather than just outside it/labelling the loop itself, so that the initialisation isn't repeated. Breaks and continues can be labelled or unlabelled. Surely if we're going to support retry on this level it would be the same? Stewart.

containing loop or the try block associated with the catch it's in if no label is given, or to the label wherever it may be if it is given. Sounds pretty messy to me, with retries in the loops in a try block and in the catch for it, not even counting the retry that throws you to a reset section that prepares for re-execution of the try block. The idea is nice for each, but... I think that the loop usage can be handled in the few cases where it is apropos (see my forward linking loop in an earlier message) by "goto", and should be (this context is basically within a well-defined block and not abuse as far as I can see). Other ways of doing this are messy and markedly less efficient. Most common cases can be handled by minimally inefficient "un-crement; continue". The try block usage is more compelling, and it would be nice to handle that with a syntax sugar construct that is more limited than "goto". I do want a label option since more than one exception might be trappable with different retry points needed. It should be restricted to be in the associated try block. Any required resets or reinitialization can be done in the catch block before issuing the retry.
Mar 30 2004
prev sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
You might consider constructing a Retry class where the various methods
accept either a delegate, or an Interface implementer. Such things are very
easy to mold to your own requirements, and don't require language
extensions.

- Kris

"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:c4963j$242u$1 digitaldaemon.com...
 Here's an idea for exception handling/recovery.

 For certain kinds of errors, it is common to prompt the user to retry
 the operation.  (Common examples: no disk in drive, disk is write
 protected, printer is out of paper....)

 For these, a handy idea would be a means of retrying the operation that
 has failed.  It would work like this:

 try {
 doSomething();
 } catch (Exception ex) {
 if (promptToRetry()) retry;
 }

 The retry statement would simply jump back to the beginning of the try
 block.

 Without it, we're stuck with either:

 - A while loop.  The problem is that in the normal flow of program
 logic, it only does it once.  The concept of trying and trying again
 until it works (or the user gives up) is really part of error handling.

 - A while loop in the catch block, which would perhaps use a variable to
 track success/failure on the retry.  But the while loop would duplicate
 the try code, leading to an unsightly redundancy and maintenance overhead.

 - The dreaded goto.

 What do you think?

 Stewart.

 --
 My e-mail is valid but not my primary mailbox, aside from its being the
 unfortunate victim of intensive mail-bombing at the moment.  Please keep
 replies on the 'group where everyone may benefit.

Mar 29 2004
parent Ilya Minkov <minkov cs.tum.edu> writes:
Kris schrieb:
 You might consider constructing a Retry class where the various methods
 accept either a delegate, or an Interface implementer. Such things are very
 easy to mold to your own requirements, and don't require language
 extensions.
 
 - Kris

It better not be a class, but simply a group of loose function pointers. But yes, i was going to suggest exactly this. This might reduce coupling between unrelated library features. What can also be useful, is an Auto class which overwrite overwrite some of these pointers, but restore them back as it gets destroyed, thus allowing to temporarily change behaviour with convenience. -eye
Mar 31 2004