World: r4wp
[!REBOL3] General discussion about REBOL 3
older newer | first last |
Ladislav 13-Mar-2013 [1958] | OK, nevermind. I will try to be understandable for you: if you want to do so, you *can* eliminate the only combination of START, END, BUMP values that causes infinite loop by default while still remaining consistent at the cost of disallowing something that may be perceived as "legitimate" by some users, and as an "unsolicited for" limitation. |
BrianH 13-Mar-2013 [1959] | Really? Because I was assuming that FOR would have termination conditions (similar to yours). The initial conditions model just picks which set of termination conditions to apply, at least as far as the start, end and bump parameters are concerned. The body parameter, being a code block, is assumed to be under developer control. So if the developer wants to hack the termination conditions in the code block that is their fault. |
Ladislav 13-Mar-2013 [1960] | Ha, are we still discussing 1993 or some other ticket? |
BrianH 13-Mar-2013 [1961] | FOREVER is assumed to be a solicited-for infinite loop, because it's right there in the name. #864 is assumed to be whatever the developer says, because "General loop" is right there in the doc string. #1993-1994 FOR has the *feature* of not *accidentally* being infinite for any value of start, end and bump, its constraint is a feature; of course it could be *intentionally* infinite by changing the index in the code block, but that just means that there is one parameter that the developer would have to be careful about, the body block, and since that is a general pattern throughout R3 they would be doing that anyway. |
Ladislav 13-Mar-2013 [1962x2] | Assuming that we are discussing #1993 and assuming: * you insiste to allow the FOR I 1 1 0 and similar to be "infinite by default" * want to support cycle variable changes in a simple and consistent way the best you can do is to cause an error when finding out that all [start = end bump = 0] is TRUE, since in that case there is no reasonable terminating condition that could not cause infinite loop by default. Some people may object, but otherwise it looks as not a big deal. |
err: "you insist to not allow FOR I 1 1 0 and similar to be "infinite by default"" is what I meant | |
BrianH 13-Mar-2013 [1964x7] | {you insiste to allow the FOR I 1 1 0 and similar to be "infinite by default"} -> {you insiste to allow the FOR I 1 1 0 and similar to never be "infinite by default"} |
Right. | |
The fact that we even have a FOREVER loop at all means that there would be a value in having developers use it, just for their own documentation. | |
And that allows developers to be less careful with start, end and bump, for values of "careful" that mean "wrapping FOR in expensive conditional code". | |
We've been trying to reduce the amount of expensive conditional code throughout R3. That's why a lot more functions allow none now. | |
ASSERT/type means that typechecks don't have to be considered expensive anymore. Value checks still require EITHER and other conditional functions though. | |
For that matter, typesets make the type tests of function argument specs less expensive now too, so we can afford to be picky there as well. | |
Ladislav 13-Mar-2013 [1971] | Am I to understand that instead of causing an error int that case you simply prefer to not loop taking it as an exceptional condition? |
BrianH 13-Mar-2013 [1972x2] | An out-of-range condition, yes. |
The other model was the trigger-an-error model. | |
Bo 13-Mar-2013 [1974] | BrianH: I'm really glad to hear that there is a concerted effort to reduce the amount of expensive conditional code throughout R3. Great job all! |
Ladislav 13-Mar-2013 [1975] | Hmm, it is not out-of-range in the normal sense, because when START = END and BUMP = 0 the values both are and remain "in range", but it is "exceptional" |
BrianH 13-Mar-2013 [1976x4] | Depends on the model. If bump is a velocity, you can say that only velocities above (or below of you're going in reverse) 0 are in range. |
That is a matter of coming up with a plausible theoretical explanation for something that we want to do for practical reasons. | |
Then start-vs-end sets the direction, and bump sets the velocity. It's just a way to explain *why* to newbiees. | |
Dealing with the consequences of triggering an error is more expensive, so we tend to only want to trigger errors when they really *are* errors. If there is a plausible way to just do nothing and/or return none when it's not potentially damaging, we should come up with a rationale that lets do that instead. | |
Ladislav 13-Mar-2013 [1980] | You can say that you "support" zero velocity by "not looping", but, in fact, you rather don't support it by failing as silently as possible. |
BrianH 13-Mar-2013 [1981] | It's really a rationale. |
Ladislav 13-Mar-2013 [1982x2] | No problem to say it is "zero velocity". The problem is that in "normal life" something having zero velocity does not "vanish", rather it stays where it is. |
So you may be caught as using "inappropriate logic", but I do not mind, being able to eventually answer that it is an exceptional case that you simply did not want to handle to not cause headaches to some users, while causing inconveniences to people being able to calculate what it is they should have expected. | |
BrianH 13-Mar-2013 [1984] | We can just arbitrarily declare that we want 0 velocity to be considered out of range, as a favor to the developer, and the velocity explanation gives us a good excuse to not trigger an error. FOREVER existing means that they have other options, and index setting means that they can do whatever they want if they really want to, so it's not actually a constraint if they don't want it to be. |
Ladislav 13-Mar-2013 [1985] | You can always declare something arbitrarily. The problem is that if you do declare a + b = none in case a = 0 you are most probably causing inconveniences to all people knowing that there might have been a more consistent behaviour... |
BrianH 13-Mar-2013 [1986] | Remember, #864 is a proposal to replace FOR with a more flexible power-user function that would be less safe to use. They lose some safety as a tradeoff for more power and prettier sytnax. So, they lose two features (safety and backwards compatibility) but gain more flexibility. The greater flexibility would come at the expense of a slower function: negligably in the case of the function itself, but more when you add the conditional wrapper code, so it would have to be used carefully if you want it to be efficient. Overall, that is the R3 motto right there: R2 is for newbies, R3 for power users. |
Ladislav 13-Mar-2013 [1987] | But let's just forget about it in this specific case. I guess that FOR is not expected to be used extensively anyway. |
BrianH 13-Mar-2013 [1988] | So, I would recommend that the #1993 restrictions against accidental infinite loops should go into R3/Backwards and rebol-patches, because R2 is for newbies. And I would recommend that #864 be the new FOR for R3 and R2/Forward, because R3 is for power users. |
Gregg 13-Mar-2013 [1989] | Man, you guys are typing faster than I'm reading. :-) |
Ladislav 13-Mar-2013 [1990] | LOL |
Gregg 13-Mar-2013 [1991x2] | the best you can do is to cause an error when finding out that all [start = end bump = 0] is TRUE, since in that case there is no reasonable terminating condition that could not cause infinite loop by default. I think this answers what I was asking. Though it seems that Ladislav wants [1 1 0] to be infinite for consistency, while Biran and I want it not to be, for perceived user friendliness. :-) |
Brian, for that case, does your model make it a "no loop" or "once only" condition? | |
Ladislav 13-Mar-2013 [1993] | Gregg, we just agreed to make it "no-loop" |
Gregg 13-Mar-2013 [1994] | OK, I skimmed too fast. Thanks. |
Ladislav 13-Mar-2013 [1995x2] | (which is "the most silent failure") |
once only would be rather inconsistent with any terminating condition, because there is none that could cause it to loop exactly once | |
Gregg 13-Mar-2013 [1997x2] | Updting %new-loop.r now. |
Posted %mezz/new-loop.r | |
BrianH 13-Mar-2013 [1999x3] | Gress, for the start-vs-end-sets-direction bump-is-velocity model: * start=end means no direction so just loop until the =end termination condition is met and ignore bump. If the index gets changed in the body block, let the =end termination condition handle it. * start<end means positive direction, for values of "positive" that don't include 0, so bump <= 0 is out of range, meaning no loop. The termination condition *if we start looping* is >= end. * start>end means negative direction, for values of "negative" that don't include 0, so bump >= 0 is out of range, meaning no loop. The termination condition *if we start looping* is >= start. Positive and negative directions don't include 0 because if the developer wanted to do an infinite loop they would have used FOREVER or R3's #864 FOR general loop. R2 was aimed at newbies, and they need extra coddling. |
Gress -> Gregg | |
For the bump-sets-direction start-and-end-set-the-range model, 0 doesn't set a direction so it should trigger an error. Otherwise, the same. | |
Gregg 13-Mar-2013 [2002] | Brian, can you point out which test case is incorrect, and what it should produce? That way we can match against Ladislav's examples. |
BrianH 13-Mar-2013 [2003] | I like the model that doesn't trigger an error. |
Gregg 13-Mar-2013 [2004] | And I tested %new-loop.r only under R2, not R3, just in case. |
BrianH 13-Mar-2013 [2005x3] | Test cases for the first model, just using literal numbers as metaphors for the principles: ; start = end, start is not constrained, termination is x = end [i: 0 1 = for x 5 5 1 [if i >= 1 [break/return 'fail] i: i + 1]] [i: 0 1 = for x 5 5 -1 [if i >= 1 [break/return 'fail] i: i + 1]] [i: 0 1 = for x 5 5 0 [if i >= 1 [break/return 'fail] i: i + 1]] ; start < end, start is x >= end, termination is x >= end [i: 0 2 = for x 4 5 1 [if i > 2 [break/return 'fail] i: i + 1]] [none? for x 4 5 -1 [break/return 'fail]] [none? for x 4 5 0 [break/return 'fail]] ; start > end, start is x <= end, termination is x <= end [i: 0 2 = for x 5 4 -1 [if i > 2 [break/return 'fail] i: i + 1]] [none? for x 5 4 1 [break/return 'fail]] [none? for x 5 4 0 [break/return 'fail]] In all cases, bump is added to x after the termination condition is not met and before looping again. |
Let me fix some comments above: ; start < end, start is bump > 0 and x >= end, termination is x >= end ; start > end, start is bump < 0 and x <= end, termination is x <= end So, the direction sets the termination condition, and the bump sets the velocity that the loop is advanced between iterations, with range limits on the velocity as a starting condition in addition to the end range limits. | |
Ugh, let me fix the comments again, AltME is annoying: ; start < end, start is bump > 0 and x <= end, termination is x >= end ; start > end, start is bump < 0 and x >= end, termination is x <= end | |
older newer | first last |