• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r4wp

[!REBOL3] General discussion about REBOL 3

Ladislav
12-Mar-2013
[1751x2]
this still leaves an uncertainty whether we want to handle the situation 
of

    for i 1 2 0

the same as

    for i 1 1 0
BTW, END and START I did not mean as English words. I meant them 
as the respective FOR parameters.
Endo
12-Mar-2013
[1753]
according to my explanation, both should return none, because end 
value is not reachable.
Ladislav
12-Mar-2013
[1754]
hmm, but 1 = 1 + 0, i.e. the END value actually is reachable in the 
latter case
Endo
12-Mar-2013
[1755x5]
Yes, if step is negative START - END should be swapped.
aha, second case, you are right.
wait, it should pass the END value.
For i=1 To 1 Step 0 --> infinite loop on  BASIC.
Normally, in old BASICs languages, variable used in FOR, its value 
stays END+1 at the end of the loop.
* end_value + step_value
Ladislav
12-Mar-2013
[1760]
Hmm, that is not convenient in some cases
Endo
12-Mar-2013
[1761x2]
There is another issue;
on R3:

for i 1 3 0.2  [print i] ; prints 1 ... 2.8 (end value is not included)

for i 3 1 -0.2 [print i] ; prints 3 ... 1.2 (end value is not included)
on R2:

for i 1 3 0.2 [print i] ; prints 1 ... 3 (both start & end value 
included)

for i 3 1 -0.2 [print i] ; prints 3 ... 1 (both start & end value 
included)
I think R2's behaviour is "more" correct.
Ladislav
12-Mar-2013
[1763x2]
for i 1 3 0.2  [print i] ; prints 1 ... 2.8 (end value is not included)

 - this is an arithmetic problem; 0.2 is not representable exactly 
 by a binary floating point (i.e. decimal!) value.
I do *not* recommend to use a general code for such loops
Endo
12-Mar-2013
[1765]
right,
for i 1 3 0.1999999999999999 [print i] ; --> 1.0 ... 3.0
Gregg
12-Mar-2013
[1766]
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
[1767]
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
[1768]
My preference, then, is to 1) throw an error or 2) never execute 
the loop.
BrianH
12-Mar-2013
[1769]
Bad control parameters usually mean triggering an error in R3, to 
better help the developer with their debugging. We only do nothing 
for empty data, sometimes for values of "empty" that include none.
Gregg
12-Mar-2013
[1770]
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.
BrianH
12-Mar-2013
[1771]
REPEAT would be used with the range, not FOR. FOR takes too many 
parameters.
Gregg
12-Mar-2013
[1772x2]
Brian, yes. I vote for an error because FOR says, to me, that you 
expect the loop to terminate. If you want an infinite loop, use FOREVER 
to make that clear.
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
[1774]
Right. One thing we need to consider is whether we want changes to 
the index in the code block to affect the index of the loop, or whether 
we just want to do that with BREAK. There are advantages to either 
model. If manual changes to the index are ignored, it becomes safe 
to change in your code. If they aren't ignored, it becomes another 
way to affect the loop in your code.
Gregg
12-Mar-2013
[1775]
Another fun question. :-)
BrianH
12-Mar-2013
[1776]
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.
Gregg
12-Mar-2013
[1777x2]
While I think it's a bad idea to mess with the index, there are reasons 
to allow it. I think manual changes should be allowed, but discouraged.
On range!, my thinking is that the default would be a 'bump of 1 
(next value in a series), because that's how I think of iterating 
over a range of values.
BrianH
12-Mar-2013
[1779]
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.
Ladislav
12-Mar-2013
[1780]
We can't really discourage anything

 - I guess that Gregg mentions to discourage it in the documentation
Gregg
12-Mar-2013
[1781]
Yes, in docs.
Ladislav
12-Mar-2013
[1782]
(should be "means")
BrianH
12-Mar-2013
[1783x3]
The range! type turned out to not actually be useful. You can stop 
adding a ! when referring to ranges :)
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.
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
[1786]
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
[1787]
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 ()
Maxim
12-Mar-2013
[1788]
IMHO, differenciation of each iterator, increase their relative "relevance" 
in the language.
BrianH
12-Mar-2013
[1789]
Whatever we choose with FOR, we should make REPEAT behave similarly 
in that same choice. Those two are in the same family.
Ladislav
12-Mar-2013
[1790]
i.e. C language for () is not a FOR loop, in fact. it is a general 
loop
BrianH
12-Mar-2013
[1791]
Ladislav, try to keep on topic. We're not talking about CFOR, we're 
talking about FOR :)
Ladislav
12-Mar-2013
[1792]
It was Max who mentioned that
BrianH
12-Mar-2013
[1793x3]
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.
Simply not doing anything is bad here because it makes the error 
much harder to track down. It's terrible for debugging.
Wait, I might be wrong about step. For start > end, if step is positive 
then FOR should do nothing. It should only trigger an error for 0. 
The step sign determines the direction of the FOR.
Maxim
12-Mar-2013
[1796x2]
exactly.   it should only raise an error when the step  = 0
I've used some languages that try to prevent ranges which are opposite 
to step (with an error) but I found that very annoying when playing 
with code which uses variables for start & end values.
BrianH
12-Mar-2013
[1798x3]
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).
I can make the tickets later today - it just looks like two, one 
for step, one for index-changing.
Sorry, bump. Don't know why I thought it was called step.