AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 4382 |
r3wp | 44224 |
total: | 48606 |
results window for this page: [start: 3201 end: 3300]
world-name: r4wp
Group: !REBOL3 ... General discussion about REBOL 3 [web-public] | ||
Gregg: 11-Mar-2013 | I think mine used it, but I agree that standalone is better, and won't be any harder in this case. | |
Gregg: 11-Mar-2013 | Thanks, cloned and found them. | |
Ladislav: 12-Mar-2013 | I gave the for i 1 2 0 [prin "x"] a second thought, and the fact is that the "forever" functionality looks legitimate as well. Thus, it would be best if we made a user poll to find out what is preferred. Whether looping forever or not looping at all. So, please, let us know what do you prefer. | |
GrahamC: 12-Mar-2013 | shouldn't a for loop run at least once, and then on the next run check to see if limits are exceeded? | |
Ladislav: 12-Mar-2013 | That is a matter of preferences as well (at least IMO). You can have such preference and express it, but another legitimate wish is for this case: for i 2 1 1 [prin "x"] to not run at all yielding #[none] as it currently does in R3 | |
Pekr: 12-Mar-2013 | well, I can imagine more scenarios, and it needs some thought to stay consistent between the cases. So my first thoughts, starting with the latest example: for i 2 1 1 [prin "x"] If above scenario means returning #none (and I agree with that), then I think that the for i 1 2 0 [print "x"] could be just the same. But - it might be related to the thoughts of the indexing. In REBOL series (if I am right), the position is in between the elements (not on the first element). So in that regards, skip 0 moves nowhere. But - it might also mean (as "first series" returns first element), that it should perform the loop just once. The last option for me is to cause an infinite loop, although from some point of view, it might make some sense too - you simply want to traverse the range, from 1 to 2, but you skip 0. If you would use just 'skip, you would cause an infinite loop. So - I really don't know .... | |
GrahamC: 12-Mar-2013 | execute once, increment the loop counter and then check it against the upper bounds. | |
Ladislav: 12-Mar-2013 | Regarding the negative bump versus the positive bump: * I tend to think that the set of integers specified by start-bound 1 end-bound 3 and bump 1 to contain the numbers [1 2 3] * I tend to think that the set of integers specified by start-bound 3 end-bound 1 and bump -1 to contain the numbers [3 2 1] * judged this way the set of integers specified by start-bound 1 end-bound 3 and bump 0 may be considered ** incorrectly specified (cause error) ** empty since it does not specify correctly a nonempty set of integer numbers (do not loop) ** it may be specially defined as [1 2 3] (infinite loop) Choosing an alternative of the above three I consider just a matter of preference. | |
Endo: 12-Mar-2013 | It looks like (on R3) it checks the upper bound if the bump value is positive, lower bound if the bump value if negative AND if the bound value can be reachable with the bump value. | |
Ladislav: 12-Mar-2013 | I understand you, and youi gave some inspiration, but you used some terms that may be rather confusing: right bound - did you mean the END value? lower bound - did you mean the START value or the minimum of START and END? | |
Ladislav: 12-Mar-2013 | BTW, END and START I did not mean as English words. I meant them as the respective FOR parameters. | |
Gregg: 12-Mar-2013 | This is an excellent question Ladislav. What if we start with the doc string: R2: Repeats a block over a range of values. R3: Evaluate a block over a range of values. That makes me think 'bump has to be non-zero, and it should throw an error. It should also throw an error (under R2) if 'start and 'end are series values and won't terminate (e.g. empty series). R3 does this now. That is, FOR should always terminate. R2 allows char! values, R3 does not. Under R2 specifying an 'end of #"ÿ" (char 255) also results in an endless loop. My RANGE func tests for that, because it caused me a problem at one point. | |
BrianH: 12-Mar-2013 | I think that we have two conflicting values here: * Do what I *say*, since you can't read my mind to know what I mean * Trigger errors when you run into something almost definitely wrong as a favor to the developer In the case of FOREACH, it triggers an error for an empty words block and doesn't allow none because that block is part of the control structure, not the data (which we do allow empty or none for). In the case of a block of only set-words, that also doesn't really advance, but at least you get a reference to the series so you could in theory be doing something (that you should probably use WHILE to do instead), so not triggering an error in that case is iffy, you could make an argument either way. For FOR, the main factor for whether the loop would normally end (without BREAK or changing the index manually somehow) is whether the step > 0 if start < end, or step < 0 if start > end. So it's not whether it = 0. | |
Gregg: 12-Mar-2013 | And since I mentioned RANGE (which I still think could be a useful datatype), how would we expect FOR to work in the context of a range! type? e.g., a range with bounds of 0 and 0. With regard to decimal 'bump values, I do allow them in my RANGE func, which uses FOR internally. It is one of the few places I do use FOR. | |
Gregg: 12-Mar-2013 | Well, yes, REPEAT would be the clear choice, but if you have a range! and passed its lower and upper bounds to FOR, what would you expect? FWIW, I've always thought 'bump should have been a refinement option in FOR. | |
BrianH: 12-Mar-2013 | If you have a range type (which was rejected, btw, but might get revisited) and you break out its upper and lower bounds so it can be passed to FOR's *two* parameters for those values, the programmer would still need to specify them as they see fit. | |
BrianH: 12-Mar-2013 | We can't really discourage anything because we don't have "warnings" in Rebol (no way to implement them without a logging facility, and no point in logging them without a precompiler). It's allowed or it's not. If it's allowed (in R3 at least) it's because it's part of the intentioned model. | |
BrianH: 12-Mar-2013 | So the question we're posing is whether we want the developer to be able to manually affect the FOR loop process from the inside (a feature, useful for advanced developers), or whether we want the loop process to be inviolate regardless of changes to the index in the code (another feature, useful for compilers that might want to unroll loops). Given that we don't have a compiler, that suggests that affecting it might be a useful feature, but Red compatibility and the overhead of checking the index value rather than just setting it based on an internal value in native code suggests that the latter might be better. There is no point in discouraging anything, since there is so much overhead to allowing it at all that we should only do so to provide a feature explicitly. | |
BrianH: 12-Mar-2013 | If you have the loop process inviolate then you can use a C value or even a raw value slot as an internal loop counter. If you want changes to the index in the code to persist, the loop would need to check that word after the loop cycle ends to determine its current value, then change that. That has overhead, like checking for and reacting to unset values, that just ignoring the word's value doesn't have. So if we want to allow it at all, it shouldn't be discouraged except as a potential gotcha, it should be considered a feature. | |
Maxim: 12-Mar-2013 | in languages like C the for loop is the basic iterator and it should be completely open. but in REBOL we do have a lot of purpose-built iterators, I think FOR shoudn't allow non advancing steps and should't allow the inner loop to affect index. This would make FOR faster for its primary purpose. I don't see the point in trying to make every different iterator another interface to while/until | |
Ladislav: 12-Mar-2013 | in languages like C the for loop is the basic iterator and it should be completely open - actually, C does not have a FOR loop, it only have a general loop called for () | |
BrianH: 12-Mar-2013 | Back to the step argument: For FOR, the main factor for whether the loop would normally end is whether the step > 0 if start < end, or step < 0 if start > end. So it's not whether it = 0. We should allow one iteration when start = end, but trigger an error otherwise if we have a non-advancing step. Developers can just as easily use BREAK and such for an advancing step. | |
BrianH: 12-Mar-2013 | Do we have enough factors to make some tests and tickets for FOR? I'm not sure whether we came to an agreement about the changing index issue, so that might be worth an issue ticket (assuming this conversation will disappear because we're in AltME, not CureCode). | |
Bo: 12-Mar-2013 | I think that 'for should be as flexible as possible. One of the main problems IMHO of most programming languages and software systems is designed inflexibility. | |
Bo: 12-Mar-2013 | Let's say that I have two series that are the same length, and the values at each position of each series are related to each other. What if I want to use a 'for loop to increment through the first series, but in some cases, depending on the value of the first series, I want to skip x values ahead, and on other values, I want to access that same position in the second series and perform an action on it. Why couldn't I use a 'for loop to do this if I wanted? | |
MarcS: 12-Mar-2013 | (Sorry for the tangent:) Can anyone reproduce http://curecode.org/rebol3/ticket.rsp?id=1974 on OSX? For me, I obtain the expected result on OSX and see the erroneous 9.9.9 under Linux. | |
DocKimbel: 12-Mar-2013 | Bo: you could rely on FORALL and series positions instead of carrying numerical indexes around: forall b [ offset: either b/1 = pick s1 index? b [ do something 1 ][ do something2 5 ] b: skip b offset ] | |
Gregg: 12-Mar-2013 | Bo, while I want flexibility as well, especially in a language like REBOL, I don't think we need complete flexibility everywhere. Constraints are very powerful and helpful. | |
Gregg: 12-Mar-2013 | To me, FOR creates an expectation of consistent stepping behavior, *but* there are times when you don't want that, and FOR seems like the first function you still want to go do. | |
BrianH: 12-Mar-2013 | It would make sense for maps, where SELECT and PICK are pretty much the same thing, but not for series, where they mean something different. | |
Ladislav: 12-Mar-2013 | Actually, there is one more reason I see why a general loop is quite natural and it is needed in Rebol: in case we need to iterate using decimal! values, it is quite likely that we need more "custom" END comparisons than any FOR implementation can give us. That is exactly the case when FOR cannot be improved much. | |
BrianH: 12-Mar-2013 | For some reason I thought that R2 allowed indexes to be changes, but R3 didn't, and that was a loss of functionality. After actually testing, it appears it was the other way around, a gain of functionality. I'm for R3's model in this case, enough so that I didn't think it worth adding a ticket. | |
Bo: 12-Mar-2013 | If this was a language designed to promote "proper" programming, I could see having constraints on every function to keep them from being used in new ways, and to promote the proper usage of the function. However, in real life, flexibility is key. Let me know if this makes any sense: If I want to rip the fender off my car and fashion it into a medieval helmet, physics allows me to do so (if I had the requisite skill). However, in programming languages, this type of thing would rarely be possible. So what I'm saying is this: Try as much as possible to refrain from placing software developers in a box when it comes to how they might choose to use a function or a feature. | |
Gregg: 12-Mar-2013 | There is nothing preventing you from hacking FOR into a helmet. What I'm saying is that we should tell developers "Here is a helmet, and here is a fender. You should use each appropriately." and we shouldn't make the fender a poorer fender design in order to accommodate helmet makers. | |
BrianH: 12-Mar-2013 | Ladislav, in answer to your first question about "We should allow one iteration when start = end, but trigger an error otherwise if we have a non-advancing step.", yes. That is the difference between the two models in that ticket. 0 bump should behave consistently, according to a model which makes sense. In one of those models, the bump is given primacy over the start-vs-end factor, and judged *on its own* a bump of 0 is an error (since it doesn't make FOR advance in one or the other direction). So, that error should be triggered categorically before the range is even considered. If, on the other hand, start-vs-end is given primacy, then we have 3 valid answers to the direction argument: forwards, backwards, or once - the bump argument doesn't determine direction, it determines velocity in the direction already chosen. In the start=end case the bump is always ignored, so ignoring it for 0 makes sense. In the start<end or start>end cases, a bump of 0 is basically out of range because those cases are only defined to move in the positive or negative direction, respectively. That means that start<end is only positive, and start>end is only negative. Does that make the difference between the models clear? Of course, because you can BREAK, CONTINUE, or even set the index position in the code, that doesn't actually reduce our flexibility where we really want to do anything interesting. It just makes the basic model make sense. | |
Ladislav: 12-Mar-2013 | For me, the model preferring START and END to determine the direction makes more sense and looks less constraining. | |
Ladislav: 12-Mar-2013 | The model preferring BUMP looks rather "uninteligent" and "constraining" to me. | |
BrianH: 12-Mar-2013 | Well, if you think bump should have primacy, triggering an error for 0 before you even look at start or end is the only thing that makes sense. And the velocity model for bump is the only justification for its existence at all if start-vs-end has primacy. Really, it can be anything we want as long as it makes sense :) | |
BrianH: 12-Mar-2013 | I think that something as powerful as yours, but maybe a little friendlier for the newbies, and maybe with some REWORD-style thoroughness, might work. I think that we need to go beyond the old style of general loop though - we're competing against languages with list comprehensions, not just C-like languages :) | |
Ladislav: 12-Mar-2013 | power only in the sense that you get the power to specify looping in an easy and flexible way | |
BrianH: 12-Mar-2013 | Not easy and flexible enough. You proved that we can do this already with the two-line implementation, but it doesn't have the syntactic sugar that the list comprehension fans need. So we might want to rethink the API but keep the power. Sometimes I think you're too smart for dialect design, Ladislav :) | |
Ladislav: 12-Mar-2013 | Sorry, the "not easy and flexible enough" does not make much sense to me. There is no more flexible cycle function than this one in Rebol at present. | |
BrianH: 12-Mar-2013 | Flexible and powerful isn't enough. I know this is difficult Ladislav, but try: Imagine that you're dumb. What would dumb you want? | |
Andreas: 12-Mar-2013 | Just as another perspective: COLLECT + FOREACH is a powerful, easy, and flexible list comprehension-like alternative. | |
BrianH: 12-Mar-2013 | Ladislav, that's a feature list, not a dialect. It's a great feature list, and when we're building the dialect we should take all of that into account. But what you suggest in CFOR is not much prettier than FOR, and is almost as ugly as C's for loop. It's powerful, but not something we can point to and say "Look at how powerful we are!" to people who don't understand that surface stuff doesn't matter when you're talking about power. Imagine people who haven't heard of big-O notation or Turing completeness, but have used Python or Ruby. Especially Ruby because of how pretty it is but how much it sucks beneath the surface. | |
Andreas: 12-Mar-2013 | I consider CFOR prettier than current FOR. The main use of CFOR I see, is to have everything loop-control related kept together and lexically before the body (otherwise you can just use plain WHILE). | |
Ladislav: 12-Mar-2013 | And, BTW, CFOR is substantially more powerful than what C for() offers. | |
Sunanda: 13-Mar-2013 | CFOR, EVERY etc I'm happy with FOR as I do not need to construct and perhaps REDUCE a block to set up variable start conditions -- just have to set words to values. For me, the syntaxtic sugar neatness of the new proposals is outweighed by the simplicity of the setup for the existing method. No real opinion on how to standardise the existing behavior other than to reiterate a point Brian has already made: FOR start and end can work on series too; all the examples I've seen of proposed change behavior is for numbers. We need to ensure thar series FORing works as expected too. | |
sqlab: 13-Mar-2013 | I think the proposed loop is too mighty. How easily do you forget an argument without getting an error and doing something different to what you wanted. | |
Ladislav: 13-Mar-2013 | I'm happy with FOR as I do not need to construct and perhaps REDUCE a block to set up variable start conditions - this looks like you never used CFOR, otherwise you would have know that it does not require anything of that kind | |
Gregg: 13-Mar-2013 | Sqlab (I'm sorry I don't remember your real name, and it's not in your profile here), it would certainly be easy to add keywords as markers, even optionally; or remove the REPEAT compatible option if that's too liberal. With the latter change, the only difference from FOR is that the bump value is optional. | |
Gregg: 13-Mar-2013 | Ladislav, in your latest FOR notes, is your last case [for i 1 1 0] an infinite loop? I changed %new-loop.r to reflect your design, but tripped over that and wanted to clarify. Is this a correct interpretation? Normal termination [loop [i 1 2 1] [print i]] [loop [i 2 1 -1] [print i]] Should not start [loop [i 2 1 1] [print i]] [loop [i 1 2 -1] [print i]] [loop [i 1 2 0] [print i]] [loop [i 2 1 0] [print i]] One cycle [loop [i 1 1 1] [print i]] [loop [i 1 1 -1] [print i]] Infinite loop loop [i 1 1 0] [print i] | |
BrianH: 13-Mar-2013 | I need to be more clear about that in the ticket and comments. | |
BrianH: 13-Mar-2013 | OK, so the difference between your model and one of my two models is that it allows something that we absolutely need to forbid? Or am I misunderstanding your model? | |
Ladislav: 13-Mar-2013 | Brian, your arbitrary rules don't make sense when observed from the "termination test" POV. There is no termination test that can yield TRUE and FALSE being run twice in a row and not having changed inputs | |
BrianH: 13-Mar-2013 | OK, so the important question which you are glossing over by going on about termination tests is: Can any combination of start, end and bump result in an infinite loop without changing the index explicitly in the body block? Because that is what we need to make sure *never* happens. | |
Gregg: 13-Mar-2013 | Brian, agreed, and agreed on accidental infinite loops. | |
Ladislav: 13-Mar-2013 | Because that is what we need to make sure *never* happens. - there is only one way how it can *never* happen: if we forget about termination tests and do some arbitrarinesses whatever they are. Count me out | |
Gregg: 13-Mar-2013 | For the moment, assuming all Lad's latest tests and design pass, except [1 1 0], as outlined above, are there any other issues Brian? | |
Gregg: 13-Mar-2013 | And, Ladislav, *should* [1 1 0] be an intentional, infinite loop in your design? | |
Gregg: 13-Mar-2013 | It's not clear to me that it should be, since [1 2 0] and [2 1 0] are not. | |
BrianH: 13-Mar-2013 | Termination conditions affect when the loop ends. Initial conditions affect when it starts and which direction it is thought to be going in. | |
Ladislav: 13-Mar-2013 | OK, concrete example: for i 1 1 1 [print i i: -5] How and why? | |
Gregg: 13-Mar-2013 | And if it should *not* be infinite, is it a "should never start" case, or a "once only" case? | |
BrianH: 13-Mar-2013 | Once you get past the initial conditions then everything after that is affected by the direction, the bump and the code block. But we have to assume that start, end and bump could have come from the result of a possible erroneous calculation based on crappy data. The initial conditions guard against that. Ladislav, every code example you give that sets the index in the code block is considered intentional behavior. It is only start, end and bump that are considered possible out of the developer's control. If a developer passes an unknown code block to FOR then they deserve what they get. | |
Ladislav: 13-Mar-2013 | every code example you give that sets the index in the code block is considered intentional behavior. - what behaviour? (I do know what shall happen having specified it, but what shall happen according to your arbitrary rules and why?) | |
Ladislav: 13-Mar-2013 | My rules address any combination of START, END and BUMP with any combination of the actual cycle variable VALUE telling whether the loop shall terminate or not. | |
BrianH: 13-Mar-2013 | For instance, you might noting that FOR has a lit-word parameter for its index. That makes the word peovided considered intentional, because you have to do an extra step to not know which word was provided. And in general, people are presumed to know where they get their code blocks from. | |
BrianH: 13-Mar-2013 | In the constrained #1993 FOR, the constraint is a feature. It will protect you from infinite loops that you don't intend, regardless of what start, end and bump say. You would have to go out of your way to make an infinite loop, by setting the index in code that you wrote. That way, you know you can safely call FOR when you don't even know what start, end and bump are. | |
Ladislav: 13-Mar-2013 | Also, (just a warning). If you still want to allow cycle variable changes you do need to have the means how to determine when to terminate and when not | |
BrianH: 13-Mar-2013 | That wasn't a comment on the inconsistencies, that was an answer to the previous message where you said "the best what can be done is to not use the function at all." - I was agreeing with you in the infinite loop case, and giving my reasons why. | |
BrianH: 13-Mar-2013 | We are giving developers more control by saying that some stuff is under their control (i.e. the code blocks). We are providing some safety by saying that some stuff is presumed to be not under their control and thus possibly suspect (i.e. immediate-evaluation parameters to functions that they didn't write). We do screening of some stuff because that cuts down on the screening they have to do themselves. That way dvelopers can use functions and assume that they are safe to use by default. For instance, one advantage of #1993 FOR would be that they would have to go out of their way to make it do an infinite loop, since no combination of start, end and bump would generate one. That means that they wouldn't have to wrap calls to FOR in expensive conditional code, they can just pass in any values of those parameters and trust FOR to never go infinite without them expecting it. Your CFOR would not have that advantage, but since it takes code blocks for all parameters it is assumed that you are more careful about those code blocks, as you should be as a general rule in R3. It's about providing a balance. Complete consistency in how all parameters are treated regardless of their nature would not allow us to help developers where they need it. However, having a consistent policy that code must be treated more carefully by developers than non-code allows developers some flexibility while still allowing them to be careful. That is why code that developers provide explicitly is considered to be what they want to do, at least from the outside of functions. And you can make the distinction between code and non-code using simple type tests, which is why we have APPLY and ASSERT/type. | |
Ladislav: 13-Mar-2013 | 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 | 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. | |
BrianH: 13-Mar-2013 | 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 | 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. | |
Ladislav: 13-Mar-2013 | 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 | {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"} | |
BrianH: 13-Mar-2013 | 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". | |
BrianH: 13-Mar-2013 | ASSERT/type means that typechecks don't have to be considered expensive anymore. Value checks still require EITHER and other conditional functions though. | |
Ladislav: 13-Mar-2013 | 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 | Then start-vs-end sets the direction, and bump sets the velocity. It's just a way to explain *why* to newbiees. | |
BrianH: 13-Mar-2013 | 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. | |
BrianH: 13-Mar-2013 | 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. | |
BrianH: 13-Mar-2013 | 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. | |
BrianH: 13-Mar-2013 | 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 | 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. :-) | |
BrianH: 13-Mar-2013 | 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. | |
BrianH: 13-Mar-2013 | 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 | Brian, can you point out which test case is incorrect, and what it should produce? That way we can match against Ladislav's examples. | |
Gregg: 13-Mar-2013 | And I tested %new-loop.r only under R2, not R3, just in case. | |
BrianH: 13-Mar-2013 | 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. | |
BrianH: 13-Mar-2013 | 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. | |
BrianH: 13-Mar-2013 | 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 | |
Gregg: 13-Mar-2013 | If you get a chance, it runs the tests and just outputs to the console, so you can, I hope, see quickly where it goes off. | |
BrianH: 13-Mar-2013 | Well, when I get the chance I would like to review all of the FOR tests. But the question is whether at this stage of the game we should change tests for an R2 function. R3/Backwards and rebol-patches make R2 fixes relevant again, and this change is in keeping with R2's target market (newbies), but I don't know whether FOR's behavior is important enough to make it worth fixing in the tests, or important to keep bug-for-bug compatible (does anyone actually use it?). For R3, the tests will probably end up having to be redone for #864 FOR. | |
BrianH: 13-Mar-2013 | Is there even a significant number of existing R2 users who even use FOR at all? I mean, it really was crappy in R2. I definitely want to fix this in rebol-patches just on general principle, and likely R3/Backwards too since they're supposed to be compatible with each other, but does it even make sense to have a regression test for R2 if we're not going to have new versions? Are the R2 tests supposed to be testing rebol-patches and R3/Backwards, or new R2 versions that may never exist? | |
Gregg: 13-Mar-2013 | I don't think we can know, aside from scanning rebol.org and asking people. I use it sparingly. | |
Ladislav: 14-Mar-2013 | * 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. - that is not reasonable for BUMP = 0 (no consistent termination condition can be defined for that), also, the termination condition should be VALUE <> END in this case if you want to be consistent | |
Ladislav: 14-Mar-2013 | And =end is not a termination condition because you want the cycle to run at least once |
3201 / 48606 | 1 | 2 | 3 | 4 | 5 | ... | 31 | 32 | [33] | 34 | 35 | ... | 483 | 484 | 485 | 486 | 487 |