From: <no...@so...> - 2002-05-10 21:56:34
|
Feature Requests item #550789, was opened at 2002-04-30 17:28 You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=360894&aid=550789&group_id=10894 Category: 15. Commands A-H Group: None Status: Open Resolution: None >Priority: 3 Submitted By: Nobody/Anonymous (nobody) Assigned to: Don Porter (dgp) >Summary: [break] should take an "after"-script Initial Comment: It would be very convenient if one could supply to break a script that will be evaluated after the loop command that the [break] is breaking has ended, but before the first command after it. This could be used to break out of nested loops: foreach i {a b c d} { foreach j {a b c d} { set foo [bar $i $j] if {$foo<3} then { break {break} } # Some more processing } # break in break-script would be evaluated here incr sum $foo ; # Some still more processing } or to break out of an inner loop and immediately continue to the next iteration of an outer: for {set i 0} {$i<$i_max} {incr i} { for {set j 0} {$j<$j_max} {incr j} { if {[try_it $i $j]} then { set T($i) $j break {continue} } } # continue in break-script would be # evaluated here puts stdout "No solution found for i=$i." } To break out of three nested loops, one would similarly give the command break {break {break}} In want of this feature, I have lately found myself making very frequent use of auxiliary variables, so that the first example would instead have been set breaking 0 foreach i {a b c d} { foreach j {a b c d} { set foo [bar $i $j] if {$foo<3} then { set breaking 1 break } # Some more processing } if {$breaking} then {break} incr sum $foo ; # Some still more processing } which is much less elegant (and no doubt slower). Making special procedures for loops that I need to break out of (so that I can use [return] instead) helps in some cases, but is not always appropriate. As far as the implementation is concerned, this does not seem particularly complicated. Since no more than one [break] can be going on at any single time, the interpreter never needs to keep track of more than one break-script. In principle, all the [break] command would have to do would be to set some variable (perhaps a global variable "breakScript", to go with "errorInfo" and "errorCode"?) to the break-script. Then the looping commands need, when they catch a TCL_BREAK return, only look at this variable to see if there is a special script to evaluate or not. Even more streamlined would be to have a [break] with a script argument return some new code, say, TCL_BREAK_SCRIPT instead of TCL_BREAK. Some notes: 1. Since break-scripts can make TCL_BREAK and TCL_CONTINUE returns, they appearently return a result. This can be used to have [for], [foreach], and [while] return a non-empty result: set i_pos\ [foreach i $some_list { if {$A($i)>0} then {break {set i}} }] will set $i_pos to the first $i for which $A($i)>0, or to an empty string if there was no such $i. In the case of [for], this would not add any extra functionality since a separate [set i] commad after the [for] would have pretty much the same effect, but in the case of [foreach] it allows one to distinguish between not finding anything and finding something on the last iteration. 2. Procedure bodies and the [catch] command also catch TCL_BREAK returns; how should they react to break- scripts then? In the case of procedure bodies, evaluating [break] is normally an error, so there is no need to react to the break-script at all. In the case of catch there is similarly no need to evaluate the break- script, as the code [catch]ing might want to inspect it (just as with $errorCode); this is why it would make sense to put the script in a variable that is accessible from Tcl. 3. The mechanism proposed above have many similarities to the TCL_EVAL return code suggested in TIP #90. It is probably best treated in conjuction with that. /Lars Hellström ---------------------------------------------------------------------- >Comment By: Don Porter (dgp) Date: 2002-05-10 17:56 Message: Logged In: YES user_id=80530 For compatibility reasons, I do not think such a proposal can be considered before Tcl 9. I do not think this request is a good idea. It proposes a change to [break], but really this is a proposed change to a number of commands that respond to the TCL_BREAK completion code. It's not at all clear how some of those commands would need to adapt to this change. ([subst] ? Evaluation of Tk bindings? ) [break] has a very narrow purpose of providing at the script level the ability to return a TCL_BREAK completition code. I do not think it should be further complexified. The particular applications outlined in the proposal are worthwhile and interesting, but Tcl already provides the ability to define new looping commands and new completion codes that can implement those ideas. Such commands could be added to the control package of tcllib, if it is believed necessary to provide such commands broadly. I don't think there's any need to change the core to give the proposer the power he seeks. I'm leaving the request open for further comment, but dropping the priority. ---------------------------------------------------------------------- Comment By: Donal K. Fellows (dkf) Date: 2002-05-01 03:57 Message: Logged In: YES user_id=79902 TIP #90's Don Porter's baby; this FRQ should probably be considered by him as well. ---------------------------------------------------------------------- You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=360894&aid=550789&group_id=10894 |